# 機能設計書：llvm-link

## 1. 機能概要

### 1.1 機能名
llvm-link - 複数のLLVMモジュールをリンクするツール

### 1.2 機能説明
llvm-linkは、複数のLLVM IR（ビットコード）ファイルをリンクして1つのモジュールに統合するリンカーツールです。ThinLTOバックエンドプロセスのシミュレーションや、関数インポート機能のテストにも使用されます。

### 1.3 関連する画面/API
- CLI（コマンドラインインターフェース）
- 入力：複数の.bcファイル（ビットコード）、.llファイル（LLVM IR）、.aファイル（アーカイブ）
- 出力：リンクされた.bcファイルまたは.llファイル

---

## 2. 入出力設計

### 2.1 入力
| 項目 | 型 | 必須 | 説明 |
|------|-----|------|------|
| input files | ファイルパス | Yes | リンクするビットコードファイル群（1つ以上必須） |
| -override | ファイルパス | No | 既存シンボルを上書きするビットコードファイル |
| -import | function:filename | No | インポートする関数とそのファイル |
| -summary-index | ファイルパス | No | モジュールサマリーインデックスファイル |
| -o | ファイルパス | No | 出力ファイル名（デフォルト: 標準出力） |

### 2.2 出力
| 項目 | 型 | 説明 |
|------|-----|------|
| output file | ファイル | リンクされたビットコードまたはLLVM IRアセンブリ |
| exit code | 整数 | 0: 成功、1: エラー |

### 2.3 コマンドラインオプション
| オプション | 説明 |
|-----------|------|
| -internalize | リンクされたシンボルを内部化（外部から不可視に） |
| -only-needed | 必要なシンボルのみをリンク |
| -f | ターミナルへのバイナリ出力を許可 |
| -S | LLVM IRアセンブリとして出力 |
| -v | 詳細情報を出力 |
| -d | リンク中にアセンブリをダンプ |
| -disable-lazy-loading | 遅延モジュールロードを無効化 |
| -disable-debug-info-type-map | デバッグ情報の型マップを使用しない |
| -suppress-warnings | すべてのリンク警告を抑制 |
| -disable-verify | 検証を実行しない |
| -ignore-non-bitcode | アーカイブ内の非ビットコードファイルを無視 |

---

## 3. 処理フロー

### 3.1 基本フロー

```
[開始]
   │
   ▼
[コマンドライン引数解析]
   │
   ▼
[LLVMContext初期化]
   │
   ▼
[合成モジュール作成]
   │
   ▼
[通常入力ファイルのリンク] ←─── linkFiles()
   │
   ▼
[オーバーライドファイルのリンク] ←─── linkFiles() with OverrideFromSrc
   │
   ▼
[関数インポート処理] ←─── importFunctions()
   │
   ▼
[モジュール検証] ←─── verifyModule()
   │
   ▼
[出力ファイル書き込み]
   │
   ▼
[終了]
```

### 3.2 ファイルリンク処理

```
linkFiles()
   │
   ▼
[各ファイルに対して]
   │
   ├─► [アーカイブファイル?] ──Yes──► loadArFile()
   │         │                            │
   │         No                           ▼
   │         │                    [アーカイブ内の各メンバーをリンク]
   │         ▼
   │    loadFile()
   │         │
   ▼         ▼
[モジュール検証（オプション）]
   │
   ▼
[サマリーインデックス処理]
   │
   ▼
[Linker.linkInModule()]
   │
   ▼
[内部化処理（オプション）]
```

### 3.3 関数インポート処理

```
importFunctions()
   │
   ▼
[サマリーインデックス読み込み]
   │
   ▼
[各インポート指定に対して]
   │
   ├─► [関数名:ファイル名を解析]
   │         │
   │         ▼
   │    [ソースモジュールロード]
   │         │
   │         ▼
   │    [関数の存在・リンケージ確認]
   │         │
   │         ▼
   │    [インポートリストに追加]
   │
   ▼
[FunctionImporter.importFunctions()]
```

---

## 4. データ構造

### 4.1 主要なデータ構造

```cpp
// 遅延ロードモジュールキャッシュ
class ModuleLazyLoaderCache {
    StringMap<std::unique_ptr<Module>> ModuleMap;
    std::function<std::unique_ptr<Module>(...)> createLazyModule;
};

// インポートリスト構造
FunctionImporter::ImportMapTy ImportList;  // モジュール→グローバル変数リスト
```

### 4.2 リンカーフラグ
```cpp
enum Linker::Flags {
    None = 0,
    LinkOnlyNeeded = 1,      // -only-needed
    OverrideFromSrc = 2      // -override用
};
```

---

## 5. エラーハンドリング

### 5.1 エラーケース
| エラー | 原因 | 対応 |
|--------|------|------|
| ファイル未検出 | 指定ファイルが存在しない | エラーメッセージ出力、終了コード1 |
| 非ビットコードファイル | アーカイブ内に非ビットコードファイル | -ignore-non-bitcodeで無視可能 |
| インポート形式エラー | -import引数に':'がない | エラーメッセージ出力、失敗 |
| 関数未検出 | インポート対象関数が存在しない | 警告メッセージ、スキップ |
| weak_any関数 | weak_anyリンケージの関数インポート | 警告メッセージ、スキップ |
| モジュール検証失敗 | リンク結果が不正 | エラーメッセージ出力、終了コード1 |

### 5.2 診断ハンドラー
```cpp
struct LLVMLinkDiagnosticHandler : public DiagnosticHandler {
    // DS_Error: エラーとして出力
    // DS_Warning: -suppress-warningsでない場合は警告出力
};
```

---

## 6. 技術仕様

### 6.1 モジュールロード方式
- **遅延ロード**（デフォルト）: `getLazyIRModule()`を使用
- **即時ロード**: `-disable-lazy-loading`指定時に`parseIR()`を使用

### 6.2 デバッグ情報処理
- デフォルトでODR型ユニーク化が有効
- `-disable-debug-info-type-map`で無効化可能
- `UpgradeDebugInfo()`による自動アップグレード

### 6.3 アーカイブ処理
- `file_magic::archive`で判定
- 各メンバーを個別にロードしリンク
- 非ビットコードメンバーは`-ignore-non-bitcode`で無視可能

### 6.4 ThinLTO対応
- `-summary-index`でモジュールサマリーインデックス指定
- ローカルシンボルの自動プロモーション
- `renameModuleForThinLTO()`による名前変更

---

## 7. 制約事項

### 7.1 入力制約
- 少なくとも1つの入力ファイルが必要
- ビットコードまたはLLVM IRテキスト形式のみ対応
- アーカイブファイル内も同様

### 7.2 処理制約
- weak_anyリンケージの関数はインポート不可
- 最初のファイルには内部化が適用されない
- OverrideFromSrcフラグは最初のファイルには適用されない

---

## 8. 非機能要件

### 8.1 パフォーマンス
- 遅延ロードによるメモリ効率化
- モジュールキャッシュによる重複ロード回避

### 8.2 セキュリティ
- 入力ファイルのビットコード形式検証
- モジュール検証による整合性チェック

---

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

### 9.1 エントリーポイント
- **ファイル**: `llvm/tools/llvm-link/llvm-link.cpp`
- **関数**: `main()` (462-528行目)

### 9.2 重要な関数
| 関数名 | 行番号 | 説明 |
|--------|--------|------|
| main() | 462-528 | エントリーポイント、全体制御 |
| loadFile() | 127-152 | 単一ファイルのロード処理 |
| loadArFile() | 154-226 | アーカイブファイルのロード処理 |
| linkFiles() | 376-460 | ファイル群のリンク処理 |
| importFunctions() | 299-374 | 関数インポート処理 |

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

```
main()
├── cl::ParseCommandLineOptions()        [467行目]
├── Context.enableDebugTypeODRUniquing() [474行目]
├── linkFiles() [通常入力]                [484行目]
│   ├── MemoryBuffer::getFileOrSTDIN()   [383行目]
│   ├── loadArFile() / loadFile()        [395-397行目]
│   ├── verifyModule()                   [407行目]
│   ├── renameModuleForThinLTO()         [430行目]
│   └── Linker::linkInModule()           [439-446行目]
├── linkFiles() [オーバーライド]          [488行目]
├── importFunctions()                    [493行目]
│   ├── getModuleSummaryIndexForFile()   [303行目]
│   ├── ModuleLazyLoaderCache            [316行目]
│   └── FunctionImporter::importFunctions() [371行目]
├── verifyModule()                       [508行目]
└── WriteBitcodeToFile() / print()       [518-520行目]
```

### 9.4 データフロー図

```
入力ファイル群 (.bc/.ll/.a)
         │
         ▼
    ┌─────────────┐
    │ loadFile()  │ ← 遅延/即時ロード選択
    │ loadArFile()│
    └─────────────┘
         │
         ▼ Module
    ┌─────────────┐
    │ verifyModule│ ← 検証（オプション）
    └─────────────┘
         │
         ▼
    ┌─────────────────────┐
    │ renameModuleForThinLTO │ ← サマリーインデックス使用時
    └─────────────────────┘
         │
         ▼
    ┌─────────────┐
    │   Linker    │ ← リンク処理
    │ linkInModule│
    └─────────────┘
         │
         ▼ Composite Module
    ┌─────────────────────┐
    │ FunctionImporter    │ ← -import指定時
    │ importFunctions()   │
    └─────────────────────┘
         │
         ▼
    ┌─────────────────────┐
    │ WriteBitcodeToFile  │ ← バイナリ出力
    │ print()             │ ← アセンブリ出力(-S)
    └─────────────────────┘
         │
         ▼
      出力ファイル
```

### 9.5 関連ファイル一覧

| ファイルパス | 役割 |
|-------------|------|
| llvm/tools/llvm-link/llvm-link.cpp | メインソースファイル（529行） |
| llvm/include/llvm/Linker/Linker.h | Linkerクラス定義 |
| llvm/include/llvm/IR/Module.h | Moduleクラス定義 |
| llvm/include/llvm/Bitcode/BitcodeReader.h | ビットコード読み込みAPI |
| llvm/include/llvm/Bitcode/BitcodeWriter.h | ビットコード書き込みAPI |
| llvm/include/llvm/IRReader/IRReader.h | IR読み込みAPI |
| llvm/include/llvm/Transforms/IPO/FunctionImport.h | 関数インポートAPI |
| llvm/include/llvm/Transforms/IPO/Internalize.h | 内部化変換API |

---

## 10. 使用例

### 10.1 基本的なリンク
```bash
llvm-link a.bc b.bc c.bc -o combined.bc
```

### 10.2 LLVM IRアセンブリ出力
```bash
llvm-link -S a.bc b.bc -o combined.ll
```

### 10.3 シンボルの内部化
```bash
llvm-link -internalize a.bc b.bc -o internal.bc
```

### 10.4 シンボルのオーバーライド
```bash
llvm-link a.bc -override b.bc -o overridden.bc
```

### 10.5 関数のインポート（ThinLTOテスト用）
```bash
llvm-link main.bc -import=foo:lib.bc -summary-index=index.thinlto.bc -o result.bc
```

---

## 11. 改訂履歴

| 版数 | 日付 | 変更内容 | 担当者 |
|------|------|----------|--------|
| 1.0 | 2026-02-01 | 初版作成 | llvm-link機能設計書生成 |
