# 機能設計書 118-gold

## 概要

本ドキュメントは、LLVMプロジェクトにおけるGNU goldリンカ用LTOプラグイン「gold-plugin」の機能設計を記述する。

### 本機能の処理概要

gold-pluginは、GNU goldリンカにLink Time Optimization（LTO）機能を提供するプラグインである。ビットコード形式のオブジェクトファイルを認識し、リンク時に最適化を実行してネイティブコードを生成する。Regular LTOとThinLTOの両方をサポートし、大規模プロジェクトでのビルド効率を向上させる。

**業務上の目的・背景**：プログラム全体の最適化（Whole Program Optimization）は、個別のコンパイルユニットでは不可能な最適化（インライン化、デッドコード除去、定数伝播など）を可能にする。goldリンカのプラグインAPIを通じてLLVMのLTO機能を統合することで、既存のビルドシステムを大きく変更することなくLTOを適用できる。

**機能の利用シーン**：
- 大規模C/C++プロジェクトのリンク時最適化
- ThinLTOによる並列ビルド
- 分散ビルドシステムとの連携
- プロファイルガイド最適化（PGO）との組み合わせ

**主要な処理内容**：
1. goldリンカからのファイル登録（claim_file_hook）
2. ビットコードファイルの認識とシンボル抽出
3. シンボル解決情報の取得（all_symbols_read_hook）
4. LTOバックエンドによる最適化・コード生成
5. 生成されたオブジェクトファイルのリンカへの返却

**関連システム・外部連携**：GNU gold linker、LLVM LTOライブラリ、ThinLTOバックエンド

**権限による制御**：特になし。ファイルシステムへのアクセス権限のみ必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLI | 主機能 | goldリンカ経由でのプラグイン呼び出し |

## 機能種別

リンク時最適化 / コード生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| thinlto | bool | No | ThinLTOモードを有効化 | - |
| thinlto-index-only | bool/string | No | インデックスファイルのみ生成 | - |
| jobs | string | No | 並列度指定 | 有効な数値 |
| O | int | No | 最適化レベル（0-3） | 0-3の範囲 |
| mcpu | string | No | ターゲットCPU | - |
| mtriple | string | No | ターゲットトリプル | - |
| cache-dir | string | No | ThinLTOキャッシュディレクトリ | - |
| sample-profile | string | No | サンプルプロファイルファイル | ファイル存在確認 |

### 入力データソース

- LLVMビットコードファイル（.bc / .o形式で埋め込み）
- ネイティブオブジェクトファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| NativeObjects | binary | LTO処理後のネイティブオブジェクトファイル |
| ThinLTOIndex | binary | ThinLTOインデックスファイル（thinlto-index-only時） |
| ImportsFiles | text | インポート情報ファイル（オプション） |

### 出力先

- 一時ファイル（リンカに返却）
- 指定されたパス（obj-pathオプション時）

## 処理フロー

### 処理シーケンス

```
1. プラグイン初期化（onload）
   ├─ ターゲット初期化
   ├─ コールバック登録
   │   ├─ claim_file_hook
   │   ├─ all_symbols_read_hook
   │   └─ cleanup_hook
   └─ オプション処理
2. ファイル登録フェーズ（claim_file_hook）
   ├─ 各入力ファイルの検査
   ├─ ビットコードファイルの認識
   ├─ シンボル抽出
   └─ goldへのシンボル登録
3. シンボル解決フェーズ（all_symbols_read_hook）
   ├─ 解決済みシンボル情報取得
   ├─ LTOインスタンス作成
   ├─ モジュール追加
   ├─ LTO実行
   └─ 生成ファイルをリンカに追加
4. クリーンアップ（cleanup_hook）
   ├─ 一時ファイル削除
   └─ キャッシュ整理
```

### フローチャート

```mermaid
flowchart TD
    A[gold linker起動] --> B[onload呼び出し]
    B --> C[ターゲット初期化]
    C --> D[コールバック登録]
    D --> E{オプション処理}
    E --> F[claim_file_hook]
    F --> G{ビットコード?}
    G -->|Yes| H[InputFile作成]
    G -->|No| I[*claimed=0で戻る]
    H --> J[シンボル抽出]
    J --> K[add_symbols呼び出し]
    K --> L[Modulesリストに追加]
    L --> M{次のファイル?}
    M -->|Yes| F
    M -->|No| N[all_symbols_read_hook]
    N --> O[get_symbolsでシンボル解決情報取得]
    O --> P[createLTO]
    P --> Q{ThinLTO?}
    Q -->|Yes| R[ThinLTOバックエンド設定]
    Q -->|No| S[Regular LTOバックエンド設定]
    R --> T[モジュール追加ループ]
    S --> T
    T --> U[addModule]
    U --> V[シンボル解決設定]
    V --> W{次のモジュール?}
    W -->|Yes| T
    W -->|No| X[Lto->run]
    X --> Y{thinlto-index-only?}
    Y -->|Yes| Z[インデックスファイル出力]
    Y -->|No| AA[オブジェクトファイル生成]
    AA --> AB[add_input_file]
    AB --> AC[cleanup_hook]
    Z --> AC
    AC --> AD[一時ファイル削除]
    AD --> AE[キャッシュ整理]
    AE --> AF[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | ビットコード認識 | ビットコードセクションを含むファイルをLTO対象として認識 | claim_file時 |
| BR-002 | シンボル解決 | goldの解決情報に基づきPrevailing/Exportなどを決定 | all_symbols_read時 |
| BR-003 | ThinLTOインデックス | thinlto-index-onlyでは最適化せずインデックスのみ生成 | thinlto-index-only時 |
| BR-004 | キャッシュ管理 | cache-dir指定時はThinLTOオブジェクトをキャッシュ | cache-dir指定時 |
| BR-005 | Wrap対応 | --wrapオプションのシンボルはインライン化を抑制 | get_wrap_symbols時 |

### 計算ロジック

- 最適化レベル：O0-O3で指定、デフォルトO2
- 並列度：hardware_concurrencyベースまたはjobs指定

## データベース操作仕様

該当なし（ファイルベースのツール）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| LDPL_FATAL | 致命的エラー | ビットコード読み込み失敗 | エラーメッセージ出力後終了 |
| LDPL_ERROR | エラー | シンボル追加失敗 | エラーメッセージ出力後継続 |
| LDPL_WARNING | 警告 | 軽微な問題 | 警告出力後継続 |

### リトライ仕様

リトライ処理なし

## トランザクション仕様

該当なし

## パフォーマンス要件

- ThinLTOによる並列処理対応
- キャッシュ機能による再ビルド効率化

## セキュリティ考慮事項

- 入力ファイルの検証
- 一時ファイルの適切な管理

## 備考

- goldリンカのプラグインAPIを使用
- LLVM LTOライブラリに依存
- Regular LTOとThinLTOの両方をサポート

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

claimed_file、ResolutionInfoがモジュールとシンボル解決情報を管理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | gold-plugin.cpp | `llvm/tools/gold/gold-plugin.cpp` | claimed_file構造体（77-83行目）、ResolutionInfo構造体（109-114行目） |

**読解のコツ**: claimed_fileは入力ファイル情報、ResolutionInfoはシンボルごとの解決ポリシーを保持。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | gold-plugin.cpp | `llvm/tools/gold/gold-plugin.cpp` | onload関数（351-492行目） |

**主要処理フロー**:
1. **353-357行目**: ターゲット初期化
2. **368-467行目**: transfer vectorのパースとコールバック登録
3. **399-401行目**: LDPT_OPTIONでprocess_plugin_option呼び出し
4. **402-410行目**: claim_file_hook登録
5. **411-419行目**: all_symbols_read_hook登録
6. **420-426行目**: cleanup_hook登録

#### Step 3: ファイル登録を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | gold-plugin.cpp | `llvm/tools/gold/gold-plugin.cpp` | claim_file_hook関数（534-687行目） |

**claim_file_hook処理フロー**:
- **536-562行目**: MemoryBuffer取得（get_view or getOpenFileSlice）
- **566-580行目**: InputFile::createでビットコード認識
- **584-604行目**: claimed_file構造体へのファイル情報格納
- **606-654行目**: シンボル抽出とResInfo更新
- **656-661行目**: add_symbols呼び出し
- **665-684行目**: --wrap対応

#### Step 4: LTO実行を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | gold-plugin.cpp | `llvm/tools/gold/gold-plugin.cpp` | allSymbolsReadHook関数（1147-1189行目）、runLTO関数（1049-1142行目） |

**allSymbolsReadHook処理フロー**:
- **1151-1152行目**: 追加オプションのパース
- **1167行目**: runLTO呼び出し
- **1180-1182行目**: 生成ファイルをリンカに追加

**runLTO処理フロー**:
- **1061-1065行目**: createLTOでLTOインスタンス作成
- **1074-1094行目**: モジュール追加ループ
- **1130行目**: Lto->run()実行

#### Step 5: LTO設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | gold-plugin.cpp | `llvm/tools/gold/gold-plugin.cpp` | createLTO関数（875-992行目） |

**createLTO処理フロー**:
- **877-978行目**: Conf構造体の設定
- **908-920行目**: ThinLTOバックエンド設定（thinlto_index_only分岐）
- **927-957行目**: 出力タイプ別フック設定
- **989-991行目**: LTOインスタンス生成

### プログラム呼び出し階層図

```
gold linker
    │
    ▼
onload()
    │
    ├─ InitializeAllTargets等
    │
    ├─ transfer vector解析
    │      ├─ LDPT_OPTION → process_plugin_option()
    │      ├─ LDPT_REGISTER_CLAIM_FILE_HOOK
    │      ├─ LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK
    │      └─ LDPT_REGISTER_CLEANUP_HOOK
    │
    │   [claim_file_hook per file]
    ├─ claim_file_hook()
    │      ├─ get_view / getOpenFileSlice
    │      ├─ InputFile::create
    │      ├─ シンボル抽出
    │      ├─ add_symbols
    │      └─ get_wrap_symbols処理
    │
    │   [リンク後]
    ├─ all_symbols_read_hook()
    │      ├─ allSymbolsReadHook()
    │      │      ├─ runLTO()
    │      │      │      ├─ createLTO()
    │      │      │      ├─ addModule() [per module]
    │      │      │      └─ Lto->run()
    │      │      └─ recordFile() [per output]
    │      └─ llvm_shutdown()
    │
    └─ cleanup_hook()
           ├─ 一時ファイル削除
           └─ キャッシュ整理
```

### データフロー図

```
[claim_file_hook]
入力ファイル ──▶ get_view ──▶ MemoryBuffer ──▶ InputFile::create
                                                      │
                                                      ▼
                                               シンボル抽出
                                                      │
                                         ┌────────────┴────────────┐
                                         ▼                         ▼
                                   add_symbols               ResInfo更新
                                   (gold登録)               (解決ポリシー)
                                         │                         │
                                         ▼                         ▼
                                      Modules ◀───────────────── claimed_file

[all_symbols_read_hook]
Modules ──▶ get_symbols ──▶ シンボル解決情報
                                   │
                                   ▼
                             createLTO ──▶ LTO Config
                                   │
                                   ▼
                    ┌──────────────┼──────────────┐
                    ▼              ▼              ▼
              Regular LTO    ThinLTO      Unified LTO
                    │              │              │
                    └──────────────┼──────────────┘
                                   ▼
                             Lto->run()
                                   │
                    ┌──────────────┼──────────────┐
                    ▼              ▼              ▼
              .o files      .thinlto.bc      .imports
                    │
                    ▼
              add_input_file (gold返却)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| gold-plugin.cpp | `llvm/tools/gold/` | ソース | メイン処理 |
| LTO.h | `llvm/include/LTO/` | ヘッダ | LTOインターフェース |
| plugin-api.h | (システム) | ヘッダ | goldプラグインAPI |
| Config.h | `llvm/include/LTO/` | ヘッダ | LTO設定 |
| CMakeLists.txt | `llvm/tools/gold/` | 設定 | ビルド設定 |
