# 機能設計書 116-llvm-cat

## 概要

本ドキュメントは、LLVMプロジェクトにおけるモジュール結合ツール「llvm-cat」の機能設計を記述する。

### 本機能の処理概要

llvm-catは、複数のLLVMビットコードファイルを結合（concatenate）して、マルチモジュールビットコードファイルを生成するツールである。主にLLVMの内部テスト用途で使用され、マルチモジュールビットコードファイルに依存する機能のテストを可能にする。

**業務上の目的・背景**：LLVMのビットコードリーダー/ライターや最適化パスの一部は、マルチモジュールビットコードファイル（複数のモジュールを含む単一のビットコードファイル）を扱う機能を持つ。本ツールは、そのような機能のテストデータを作成するために使用される。通常のビルドプロセスでは使用されないが、LLVMの開発・テストにおいて重要な役割を果たす。

**機能の利用シーン**：
- マルチモジュールビットコードファイルのテストデータ作成
- ビットコードリーダーの機能テスト
- ThinLTO関連機能のテスト
- ビットコードファイルの結合

**主要な処理内容**：
1. コマンドライン引数の解析
2. 入力ファイルの読み込み
3. 各モジュールのビットコード書き込み
4. 文字列テーブルの統合
5. 出力ファイルへの書き込み

**関連システム・外部連携**：LLVM Bitcode/BitcodeReader、BitcodeWriterライブラリを使用。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLI | 主機能 | コマンドラインインターフェースによる操作 |

## 機能種別

データ結合 / ファイル変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| InputFilenames | string[] | Yes | 入力ビットコードファイル | ファイル存在確認 |
| -o | string | Yes | 出力ファイル名 | パス妥当性確認 |
| -b | bool | No | バイナリ結合モード（ビットコードをそのまま結合） | - |

### 入力データソース

- LLVMビットコードファイル（.bc）
- LLVM IRテキストファイル（.ll）：-bオプション未指定時

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| MultiModuleBitcode | binary | マルチモジュールビットコードファイル |

### 出力先

- 指定されたファイル（-oオプション、必須）

## 処理フロー

### 処理シーケンス

```
1. コマンドライン解析
   └─ オプション取得
2. BitcodeWriter初期化
   └─ 出力バッファ準備
3. モード判定
   ├─ バイナリモード（-b指定）
   │   └─ 各入力ファイル処理
   │       ├─ ビットコード読み込み
   │       ├─ モジュールリスト取得
   │       └─ バッファに追加、文字列テーブルコピー
   └─ 通常モード
       └─ 各入力ファイル処理
           ├─ IR解析（parseIRFile）
           └─ モジュール書き込み（writeModule）
4. 文字列テーブル書き込み（通常モード）
5. 出力ファイル書き込み
6. 終了処理
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[コマンドライン解析]
    B --> C[BitcodeWriter初期化]
    C --> D{-bオプション?}
    D -->|Yes| E[バイナリ結合モード]
    D -->|No| F[通常モード]
    E --> G[入力ファイルループ]
    G --> H[MemoryBuffer読み込み]
    H --> I[getBitcodeModuleList]
    I --> J[各モジュールをバッファに追加]
    J --> K[copyStrtab]
    K --> L{次のファイル?}
    L -->|Yes| G
    L -->|No| M[出力ファイル書き込み]
    F --> N[入力ファイルループ]
    N --> O[parseIRFile]
    O --> P{パース成功?}
    P -->|No| Q[エラー出力・終了]
    P -->|Yes| R[writeModule]
    R --> S[OwnedModsに保存]
    S --> T{次のファイル?}
    T -->|Yes| N
    T -->|No| U[writeStrtab]
    U --> M
    M --> V{書き込み成功?}
    V -->|No| W[エラー出力・終了]
    V -->|Yes| X[正常終了]
    Q --> Y[終了 code=1]
    W --> Y
    X --> Z[終了 code=0]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 出力ファイル必須 | -oオプションは必須 | 起動時 |
| BR-002 | バイナリモード | -b指定時はビットコードをそのまま結合（パースなし） | -bオプション指定時 |
| BR-003 | 通常モード | -b未指定時はIRを解析して再ビットコード化 | -bオプション未指定時 |
| BR-004 | モジュール所有権 | 通常モードでは文字列テーブル書き込みまでモジュールを保持 | 通常モード時 |

### 計算ロジック

特になし。ファイル結合のみ。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ファイルエラー | 入力ファイルが開けない | エラーメッセージ出力後終了 |
| - | パースエラー | IR解析に失敗 | エラーメッセージ出力後終了 |
| - | 出力エラー | 出力ファイルが開けない | エラーメッセージ出力後終了 |

### リトライ仕様

リトライ処理なし

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

該当なし

## パフォーマンス要件

特に規定なし

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

- 入力ファイルの検証

## 備考

- テスト用ユーティリティとして設計
- 通常のビルドでは使用しない

---

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

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

### 推奨読解順序

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

BitcodeWriterがマルチモジュールビットコードの書き込みを管理する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | BitcodeWriter.h | `llvm/include/Bitcode/BitcodeWriter.h` | BitcodeWriterクラスのインターフェース |

**読解のコツ**: writeModule()は個別モジュール書き込み、writeStrtab()は共有文字列テーブル書き込み、copyStrtab()は既存の文字列テーブルコピー。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | llvm-cat.cpp | `llvm/tools/llvm-cat/llvm-cat.cpp` | main関数（50-96行目） |

**主要処理フロー**:
1. **51-52行目**: コマンドライン解析
2. **54-55行目**: ExitOnErr設定、LLVMContext作成
3. **57-58行目**: BitcodeWriter初期化
4. **59-68行目**: バイナリモード処理
5. **69-84行目**: 通常モード処理
6. **86-92行目**: 出力ファイル書き込み
7. **94-95行目**: 書き込み実行

#### Step 3: 各モードを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | llvm-cat.cpp | `llvm/tools/llvm-cat/llvm-cat.cpp` | バイナリモード（59-68行目）、通常モード（69-84行目） |

**バイナリモード処理フロー**:
- **61-62行目**: MemoryBuffer読み込み
- **63行目**: getBitcodeModuleList取得
- **64-66行目**: 各モジュールのバッファ追加と文字列テーブルコピー

**通常モード処理フロー**:
- **72-73行目**: OwnedModsベクタ準備（モジュール所有権維持）
- **74-75行目**: parseIRFile呼び出し
- **76-79行目**: パースエラー処理
- **80-81行目**: writeModule、モジュール保存
- **83行目**: writeStrtab呼び出し

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

```
main()
    │
    ├─ cl::ParseCommandLineOptions
    │
    ├─ BitcodeWriter(Buffer) 初期化
    │
    ├─ BinaryCat? ──▶ バイナリモード
    │                    │
    │                    ├─ MemoryBuffer::getFileOrSTDIN
    │                    ├─ getBitcodeModuleList
    │                    └─ append_range / copyStrtab
    │
    └─ !BinaryCat? ──▶ 通常モード
                          │
                          ├─ parseIRFile
                          ├─ Writer.writeModule
                          └─ Writer.writeStrtab
                                │
    raw_fd_ostream ◀───────────┘
         │
         └─ OS.write(Buffer.data(), Buffer.size())
```

### データフロー図

```
[バイナリモード]
ビットコード1 ──┐
ビットコード2 ──┼──▶ getBitcodeModuleList ──▶ append_range ──▶ マルチモジュール
ビットコードN ──┘          │                                    ビットコード
                     copyStrtab

[通常モード]
IR/ビットコード1 ──┐
IR/ビットコード2 ──┼──▶ parseIRFile ──▶ writeModule ──▶ マルチモジュール
IR/ビットコードN ──┘                           │         ビットコード
                                          writeStrtab
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| llvm-cat.cpp | `llvm/tools/llvm-cat/` | ソース | メイン処理 |
| BitcodeWriter.h | `llvm/include/Bitcode/` | ヘッダ | ビットコード書き込み |
| BitcodeReader.h | `llvm/include/Bitcode/` | ヘッダ | ビットコード読み込み |
| IRReader.h | `llvm/include/IRReader/` | ヘッダ | IR解析 |
| CMakeLists.txt | `llvm/tools/llvm-cat/` | 設定 | ビルド設定 |
