# 機能設計書 4-opt

## 概要

本ドキュメントは、opt（LLVM最適化ツール）の機能設計を記述する。optは、LLVM中間表現（IR）に対して様々な最適化パスを適用し、最適化されたIRを出力するツールである。

### 本機能の処理概要

optは、LLVMビットコードまたはアセンブリを読み込み、指定された最適化パスを適用し、結果を出力する。開発者は最適化パスを個別に指定したり、定義済みの最適化パイプラインを使用したりできる。

**業務上の目的・背景**：コンパイラの最適化フェーズをテスト・デバッグするためのツールを提供する。フロントエンドとバックエンドを介さずに、純粋なIRレベルの変換を検証できる。これにより、最適化パスの開発、デバッグ、およびパフォーマンス分析が効率的に行える。

**機能の利用シーン**：
- 新しい最適化パスの開発とテスト
- 既存パスの動作検証とデバッグ
- IR変換の効果確認
- パス組み合わせの実験
- コンパイラパイプラインの分析

**主要な処理内容**：
1. LLVM IRの読み込み（ビットコード/アセンブリ）
2. 最適化パスの解析と構築
3. パスパイプラインの実行
4. 変換結果の検証
5. 最適化済みIRの出力

**関連システム・外部連携**：
- LLVM Coreライブラリとの連携
- パスプラグインとの連携
- 最適化レマーク出力との連携

**権限による制御**：特になし（コマンドラインツールとして実行）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | optはCLIツールであり、GUI画面は持たない |

## 機能種別

最適化処理 / IR変換 / 解析ツール

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| InputFilename | string | No | 入力ビットコードファイル（デフォルト: stdin） | .bc/.llファイル |
| -o | string | No | 出力ファイル名 | 有効なパス |
| -passes | string | No | パスパイプライン指定 | 有効なパス名 |
| -O0/-O1/-O2/-O3 | flag | No | 最適化レベル | いずれか1つ |
| -Os/-Oz | flag | No | サイズ最適化 | いずれか1つ |
| -S | flag | No | アセンブリ出力 | true/false |
| -disable-output | flag | No | 出力抑制 | true/false |
| -verify-each | flag | No | 各パス後に検証 | true/false |
| -print-passes | flag | No | 利用可能パス一覧表示 | true/false |

### 入力データソース

- LLVMビットコードファイル（.bc）
- LLVMアセンブリファイル（.ll）
- 標準入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ビットコード | .bc | 最適化後のビットコード |
| アセンブリ | .ll | 最適化後のLLVM IR |
| 最適化レマーク | YAML | 最適化情報 |
| パス一覧 | text | 利用可能なパス |

### 出力先

- ファイル（-oオプションで指定）
- 標準出力（-o -）

## 処理フロー

### 処理シーケンス

```
1. コマンドライン解析
   └─ オプションとパス指定の解析
2. ターゲット初期化
   └─ ターゲット情報の初期化
3. IRファイル読み込み
   └─ ビットコード/アセンブリの解析
4. パスパイプライン構築
   └─ 指定パスのパイプライン構築
5. パス実行
   └─ 各パスを順次実行
6. 検証
   └─ 出力IRの整合性検証
7. 出力生成
   └─ ビットコードまたはアセンブリ出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[コマンドライン解析]
    B --> C{print-passes?}
    C -->|Yes| D[パス一覧表示]
    C -->|No| E[ターゲット初期化]
    D --> Z[終了]
    E --> F[IRファイル読み込み]
    F --> G{使用PM判定}
    G -->|NewPM| H[runPassPipeline]
    G -->|LegacyPM| I[DebugifyCustomPassManager]
    H --> J[パス実行]
    I --> J
    J --> K{verify-each?}
    K -->|Yes| L[各パス後検証]
    K -->|No| M[最終検証]
    L --> M
    M --> N{出力形式}
    N -->|bitcode| O[ビットコード出力]
    N -->|assembly| P[アセンブリ出力]
    O --> Z
    P --> Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | NPMデフォルト | 新パスマネージャがデフォルト | レガシーPM未指定時 |
| BR-002 | 排他的-O | -O0〜-O3は排他的 | 最適化レベル指定時 |
| BR-003 | パス優先 | -passesと-Oは排他的 | 両方指定時エラー |
| BR-004 | 出力形式 | -S指定でアセンブリ、未指定でビットコード | 出力時 |

### 計算ロジック

- パスパイプライン解析：文字列からパス構造への変換
- 依存関係解決：require<analysis>による分析パス挿入

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

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | optはデータベースを使用しない |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | ファイルエラー | 入力ファイルが存在しない | ファイルパスを確認 |
| 1 | 解析エラー | 不正なIR形式 | 入力ファイルを修正 |
| 1 | パスエラー | 不正なパス名指定 | パス名を確認 |
| 1 | 検証エラー | 変換後IRが不正 | パスを確認 |
| 1 | オプションエラー | -Oと-passesの同時指定 | いずれかを使用 |

### リトライ仕様

リトライは行わない。

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

optはデータベーストランザクションを使用しない。

## パフォーマンス要件

- 大規模モジュールの効率的な処理
- 時間プロファイラによる処理時間計測
- run-twice機能による結果の再現性確認

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

- 入力IRの検証
- パスプラグインのロード制限

## 備考

optは新パスマネージャ（NPM）とレガシーパスマネージャの両方をサポートしている。NPMが推奨。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | opt.cpp | `llvm/tools/opt/opt.cpp` | エントリーポイント |
| 1-2 | optdriver.cpp | `llvm/tools/opt/optdriver.cpp` | メインドライバ実装 |

**主要処理フロー（optdriver.cpp）**:
1. **406-498行目**: optMain関数 - 初期化とオプション解析
2. **493-496行目**: print-passesオプション処理
3. **553-565行目**: IRファイル読み込み
4. **712-767行目**: 新/旧パスマネージャ分岐

#### Step 2: 新パスマネージャ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | NewPMDriver.cpp | `llvm/tools/opt/NewPMDriver.cpp` | 新パスマネージャドライバ |

**主要処理フロー**:
- runPassPipeline関数
- PassBuilderによるパイプライン構築
- パス文字列のパース

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

```
main (opt.cpp)
    │
    └─ optMain (optdriver.cpp:406)
           │
           ├─ InitializeAllTargets()
           ├─ cl::ParseCommandLineOptions()
           │
           ├─ [print-passes] printPasses()
           │
           ├─ parseIRFile()
           │
           ├─ [NewPM] runPassPipeline (NewPMDriver.cpp)
           │      │
           │      ├─ PassBuilder::buildDefaultAAPipeline
           │      └─ ModulePassManager::run
           │
           └─ [LegacyPM] DebugifyCustomPassManager
                  └─ legacy::PassManager::run
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| opt.cpp | `llvm/tools/opt/opt.cpp` | ソース | エントリーポイント |
| optdriver.cpp | `llvm/tools/opt/optdriver.cpp` | ソース | メインドライバ |
| NewPMDriver.cpp | `llvm/tools/opt/NewPMDriver.cpp` | ソース | 新PM処理 |
| PassBuilder.h | `llvm/include/llvm/Passes/PassBuilder.h` | ヘッダ | パスビルダー |
| PassManager.h | `llvm/include/llvm/IR/PassManager.h` | ヘッダ | パスマネージャ |
