# 機能設計書 55-bugpoint

## 概要

本ドキュメントは、LLVMプロジェクトにおけるbugpointツールの機能設計を記述する。bugpointは、コンパイラのバグを特定するための自動テストケース削減ツールであり、クラッシュやミスコンパイルの原因となるパスやコードを自動的に特定する。

### 本機能の処理概要

bugpointは、LLVMコンパイラのバグを自動的にデバッグするためのツールである。入力プログラムとバグを引き起こす最適化パスを受け取り、バグを再現するために必要な最小限のコードとパスを特定する。コンパイラクラッシュ、ミスコンパイル（誤った出力）、コード生成エラーの3種類のバグを診断できる。

**業務上の目的・背景**：コンパイラ開発において、バグの原因特定は非常に困難な作業である。大規模なプログラムで発生するバグは、どの最適化パスがどのコード部分に対して問題を起こしているかを特定するのに多大な時間を要する。bugpointは、この作業を自動化し、バグの再現に必要な最小限のテストケースを生成することで、開発者の負担を大幅に軽減する。

**機能の利用シーン**：
- 最適化パスによるコンパイラクラッシュのデバッグ
- 実行結果が期待と異なるミスコンパイルの診断
- コード生成器のバグ特定
- リグレッションバグの原因調査

**主要な処理内容**：
1. 入力IRファイルの読み込みとリンク
2. 問題の種類を自動判定（クラッシュ/ミスコンパイル/コード生成）
3. バグを引き起こすパスの二分探索
4. バグを引き起こすコード（関数/基本ブロック）の二分探索
5. 最小テストケースの出力

**関連システム・外部連携**：
- LLVMの最適化パス（-O1, -O2, -O3等）
- コード生成器（llc相当の機能）
- 外部コンパイラ（gcc等、参照実装として）

**権限による制御**：本ツールはファイルシステムへの読み書きアクセスと、子プロセスの実行権限を必要とする。

## 関連画面

本ツールはCLI（コマンドラインインターフェース）ツールであり、GUI画面は存在しない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | コマンドライン | 主画面 | 入力ファイル、パス、オプションの指定 |

## 機能種別

バグ診断 / テストケース削減

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| InputFilenames | list<string> | Yes | 入力IRファイル（複数可） | ファイルが存在すること |
| PassList | list<string> | No | テストする最適化パス | 有効なパス名 |
| --find-bugs | bool | No | 様々なパス順序を試してバグを探索 | - |
| --timeout | int | No | プログラム実行のタイムアウト秒数（デフォルト: 300） | 正の整数 |
| --mlimit | int | No | メモリ使用上限MB（デフォルト: 400） | 正の整数または0で無制限 |
| --output | string | No | 参照出力ファイル（ミスコンパイル検出用） | - |
| --enable-valgrind | bool | No | valgrind経由で最適化を実行 | - |
| --mtriple | string | No | ターゲットトリプルの上書き | - |

### 入力データソース

- LLVM IRファイル（.ll：テキスト形式、.bc：ビットコード形式）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ReducedTestcase | file | 削減されたテストケースファイル |
| DiagnosticOutput | text | バグ診断結果の詳細ログ |

### 出力先

- 標準出力：診断プロセスの進捗
- ファイル：削減されたテストケース

## 処理フロー

### 処理シーケンス

```
1. 初期化処理
   └─ パスレジストリの初期化、ターゲット初期化
2. 入力ファイル読み込み
   └─ 複数ファイルをリンクして単一モジュールに
3. BugDriver初期化
   └─ タイムアウト、メモリ制限等の設定
4. 問題タイプ判定
   ├─ パス実行でクラッシュ → クラッシュデバッグ
   ├─ コード生成でクラッシュ → コード生成クラッシュデバッグ
   └─ 出力不一致 → ミスコンパイルデバッグ
5. 問題削減
   └─ バグパス/コードの二分探索
6. 結果出力
   └─ 最小テストケースの保存
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[初期化・パス登録]
    B --> C[入力ファイル読み込み・リンク]
    C --> D{--find-bugs?}
    D -->|Yes| E[ランダムパス順序でバグ探索]
    D -->|No| F{パス実行でクラッシュ?}
    F -->|Yes| G[debugOptimizerCrash]
    F -->|No| H[実行環境初期化]
    H --> I{コード生成でクラッシュ?}
    I -->|Yes| J[debugCodeGeneratorCrash]
    I -->|No| K[参照出力生成/取得]
    K --> L{出力一致?}
    L -->|No| M[debugMiscompilation]
    L -->|Yes| N[debugCodeGenerator]
    G --> O[最小テストケース出力]
    J --> O
    M --> O
    N --> O
    O --> P[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | リスト削減 | パスや関数を二分探索で削減 | 問題絞り込み時 |
| BR-02 | タイムアウト保護 | 指定秒数で実行を強制終了 | 常時 |
| BR-03 | メモリ制限 | 指定MB以上のメモリ使用を制限 | 常時 |
| BR-04 | コアファイル抑制 | クラッシュ時のコアダンプを抑制 | 常時（DEBUG_BUGPOINT未定義時） |
| BR-05 | トリプル継承 | 入力ファイルのトリプルを使用、なければホストトリプル | トリプル未指定時 |

### 計算ロジック

- ListReducer：要素リストの最小化アルゴリズム
  - 半分ずつ削除してテスト
  - 成功すれば削除を確定
  - 失敗すれば別の半分をテスト
  - 最終的に1要素ずつ削除を試行

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

本ツールはデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 入力エラー | IRファイルの読み込みに失敗 | ファイルを確認 |
| 1 | 検証エラー | 入力モジュールが不正 | 有効なIRを使用 |
| - | タイムアウト | 実行が指定時間を超過 | --timeoutを増加 |

### リトライ仕様

各削減ステップで複数のバリエーションをテストする。

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

該当なし（ファイル入出力処理）。

## パフォーマンス要件

バグ削減は多数のコンパイル・実行を伴うため、時間がかかる場合がある。

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

- 子プロセスを多数生成するため、システムリソースに注意
- デフォルトでコアファイル生成を抑制

## 備考

- llvm-reduceが後継ツールとして開発されている
- レガシーパスマネージャを使用

---

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

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

### 推奨読解順序

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

バグ診断に使用される主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | BugDriver.h | `llvm/tools/bugpoint/BugDriver.h` | BugDriverクラスの定義 |
| 1-2 | ToolRunner.h | `llvm/tools/bugpoint/ToolRunner.h` | AbstractInterpreter、ToolExecutor等 |
| 1-3 | ListReducer.h | `llvm/tools/bugpoint/ListReducer.h` | リスト削減アルゴリズム |

**読解のコツ**: BugDriverが全体の制御を担い、ToolRunnerが外部プロセス実行を担当。ListReducerは汎用的な削減アルゴリズム。

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

処理の起点となるmain関数を読み解く。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | bugpoint.cpp | `llvm/tools/bugpoint/bugpoint.cpp` | main関数と初期化処理 |

**主要処理フロー**:
1. **99-121行目**: InitLLVMとパスレジストリ初期化
2. **122-128行目**: コマンドライン引数パース、割り込みハンドラ設定
3. **130-136行目**: トリプル設定
4. **138-151行目**: メモリ制限設定
5. **153-156行目**: BugDriver初期化、入力ファイル追加
6. **158-161行目**: パスリスト設定
7. **176-179行目**: BugDriver::run()実行

#### Step 3: BugDriverの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | BugDriver.cpp | `llvm/tools/bugpoint/BugDriver.cpp` | BugDriver::run()メソッド |

**主要処理フロー**:
- **157-162行目**: --find-bugsモード処理
- **171-175行目**: 最適化パスクラッシュのチェック
- **178-179行目**: 実行環境初期化
- **182-186行目**: コード生成クラッシュチェック
- **189-200行目**: 参照出力生成
- **211-224行目**: ミスコンパイル/コード生成バグの診断分岐

#### Step 4: クラッシュデバッグを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | CrashDebugger.cpp | `llvm/tools/bugpoint/CrashDebugger.cpp` | debugOptimizerCrash等 |

#### Step 5: ミスコンパイルデバッグを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Miscompilation.cpp | `llvm/tools/bugpoint/Miscompilation.cpp` | debugMiscompilation |

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

```
main()
    │
    ├─ initializeCore/ScalarOpts/... ()
    ├─ InitializeAllTargets()
    ├─ cl::ParseCommandLineOptions()
    │
    ├─ BugDriver::BugDriver()
    ├─ BugDriver::addSources()
    │      └─ parseInputFile() [x N]
    │             └─ Linker::linkModules()
    │
    └─ BugDriver::run()
           ├─ runManyPasses() [--find-bugs時]
           │
           ├─ runPasses() [クラッシュチェック]
           │      └─ debugOptimizerCrash()
           │
           ├─ initializeExecutionEnvironment()
           ├─ compileProgram()
           │      └─ debugCodeGeneratorCrash()
           │
           ├─ createReferenceFile() / diffProgram()
           │
           └─ debugMiscompilation() / debugCodeGenerator()
```

### データフロー図

```
[入力]               [処理]                    [出力]

IRファイル群    ───▶ parseInputFile()     ───▶ 統合Module
                        │
                        ▼
                  BugDriver::run()
                        │
           ┌────────────┼────────────┐
           ▼            ▼            ▼
    クラッシュ?   ミスコンパイル?   コード生成?
           │            │            │
           ▼            ▼            ▼
    debugOptimizer  debugMis-    debugCode
    Crash          compilation   Generator
           │            │            │
           └────────────┴────────────┘
                        │
                        ▼
                  削減Module  ───▶ 最小テストケース
                                    (ファイル)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| bugpoint.cpp | `llvm/tools/bugpoint/bugpoint.cpp` | ソース | メインエントリーポイント |
| BugDriver.cpp | `llvm/tools/bugpoint/BugDriver.cpp` | ソース | バグドライバ実装 |
| BugDriver.h | `llvm/tools/bugpoint/BugDriver.h` | ヘッダー | バグドライバ定義 |
| CrashDebugger.cpp | `llvm/tools/bugpoint/CrashDebugger.cpp` | ソース | クラッシュデバッグ |
| Miscompilation.cpp | `llvm/tools/bugpoint/Miscompilation.cpp` | ソース | ミスコンパイルデバッグ |
| ExtractFunction.cpp | `llvm/tools/bugpoint/ExtractFunction.cpp` | ソース | 関数抽出 |
| OptimizerDriver.cpp | `llvm/tools/bugpoint/OptimizerDriver.cpp` | ソース | 最適化実行 |
| ExecutionDriver.cpp | `llvm/tools/bugpoint/ExecutionDriver.cpp` | ソース | 実行環境管理 |
| ToolRunner.cpp | `llvm/tools/bugpoint/ToolRunner.cpp` | ソース | ツール実行 |
| ToolRunner.h | `llvm/tools/bugpoint/ToolRunner.h` | ヘッダー | ツール実行定義 |
| ListReducer.h | `llvm/tools/bugpoint/ListReducer.h` | ヘッダー | リスト削減アルゴリズム |
| FindBugs.cpp | `llvm/tools/bugpoint/FindBugs.cpp` | ソース | バグ探索 |
