# 機能設計書 3-lli

## 概要

本ドキュメントは、lli（LLVM JITコンパイラ/インタプリタ）の機能設計を記述する。lliは、LLVM中間表現（IR）を直接実行するためのJust-In-Time（JIT）コンパイラおよびインタプリタツールである。

### 本機能の処理概要

lliは、LLVMビットコードやIRファイルを読み込み、JITコンパイルまたはインタプリット実行することで、コンパイル済みの実行ファイルを生成せずにプログラムを動的に実行する。

**業務上の目的・背景**：プログラムの動的実行が必要なシーンにおいて、事前コンパイルを行わずにLLVM IRを直接実行できる機能を提供する。これにより、REPL環境の構築、動的コード生成、JITコンパイラのテスト、およびLLVM IRの動作検証が可能となる。特にコンパイラ開発時のデバッグやテストにおいて、IRレベルでの実行確認を即座に行える。

**機能の利用シーン**：
- LLVM IRの動作検証とデバッグ
- JITコンパイラ機能のテスト
- インタプリタモードでの実行解析
- 動的言語のランタイム実装
- ORC JIT APIの検証

**主要な処理内容**：
1. LLVM IRビットコードの読み込みと解析
2. 実行エンジン（MCJIT/ORC/インタプリタ）の初期化
3. JITコンパイルまたはインタプリット実行
4. 外部ライブラリのロードとシンボル解決
5. プログラムの実行と終了処理

**関連システム・外部連携**：
- LLVM Coreライブラリとの連携
- ORC JITフレームワークとの連携
- MCJIT実行エンジンとの連携
- 外部動的ライブラリとの連携
- リモート実行プロセスとの連携

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

## 関連画面

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

## 機能種別

JITコンパイル / インタプリタ実行 / ランタイム処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| InputFile | string | No | 入力ビットコードファイル（デフォルト: stdin） | .bc/.llファイル |
| -jit-kind | enum | No | JITエンジン種別（mcjit/orc/orc-lazy） | 有効な種別 |
| -force-interpreter | bool | No | インタプリタモードを強制 | true/false |
| -entry-function | string | No | エントリーポイント関数名（デフォルト: main） | 有効な関数名 |
| -extra-module | string | No | 追加モジュールファイル | .bc/.llファイル |
| -extra-object | string | No | 追加オブジェクトファイル | .oファイル |
| -dlopen | string | No | ロードする動的ライブラリ | 有効なライブラリパス |
| -O | char | No | 最適化レベル（0-3、デフォルト: 2） | 0, 1, 2, 3 |
| -mtriple | string | No | ターゲットトリプル | 有効なトリプル形式 |

### 入力データソース

- LLVMビットコードファイル（.bc）
- LLVMアセンブリファイル（.ll）
- 追加オブジェクトファイル
- 動的ライブラリ
- プログラム引数

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 実行結果 | int | プログラムの終了コード |
| 標準出力 | stream | プログラムの出力 |
| 標準エラー | stream | エラーメッセージ |
| デバッグ情報 | stream | JITデバッグ出力 |

### 出力先

- 標準出力（プログラム出力）
- 標準エラー（エラーメッセージ）
- 終了コード

## 処理フロー

### 処理シーケンス

```
1. コマンドライン解析
   └─ オプションと入力ファイルの解析
2. ネイティブターゲット初期化
   └─ 現在のプラットフォーム用ターゲット初期化
3. IRファイル読み込み
   └─ ビットコード/アセンブリの解析
4. 実行エンジン選択
   └─ MCJIT/ORC/インタプリタの選択
5. 追加モジュール/オブジェクト読み込み
   └─ 追加のコードとライブラリのロード
6. シンボル解決
   └─ 外部シンボルの解決
7. エントリー関数実行
   └─ main関数または指定関数の実行
8. 後処理
   └─ デストラクタ実行と終了
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[コマンドライン解析]
    B --> C[ネイティブターゲット初期化]
    C --> D[IRファイル読み込み]
    D --> E{JIT種別判定}
    E -->|MCJIT| F[MCJIT ExecutionEngine生成]
    E -->|ORC| G[ORC LLJIT生成]
    E -->|Interpreter| H[Interpreter生成]
    F --> I[追加モジュール読み込み]
    G --> I
    H --> I
    I --> J[動的ライブラリロード]
    J --> K[エントリー関数検索]
    K --> L{関数存在確認}
    L -->|存在| M[静的コンストラクタ実行]
    L -->|不在| N[エラー終了]
    M --> O[main関数実行]
    O --> P[静的デストラクタ実行]
    P --> Q[終了コード返却]
    Q --> R[終了]
    N --> R
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | JITデフォルト | デフォルトはORC JITを使用 | jit-kind未指定 |
| BR-002 | エントリーデフォルト | デフォルトのエントリーポイントはmain | entry-function未指定 |
| BR-003 | インタプリタ制限 | インタプリタモードではリモート実行不可 | force-interpreter + remote-mcjit |
| BR-004 | 遅延コンパイル | orc-lazyではモジュール単位の遅延コンパイル可 | per-module-lazy指定時 |

### 計算ロジック

- エントリーポイント検索：Module::getFunction()による関数検索
- シンボル解決：ExecutionEngineのシンボルテーブル検索
- メモリ管理：SectionMemoryManagerによるJITコード領域管理

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | ファイルエラー | 入力ファイルが存在しない | ファイルパスを確認 |
| 1 | 解析エラー | 不正なビットコード形式 | 入力ファイルを修正 |
| 1 | 関数未発見 | エントリー関数が存在しない | 正しい関数名を指定 |
| 1 | 実行エラー | 実行時エラー発生 | プログラムをデバッグ |
| -1 | 実行エラー | エントリー関数が見つからない | モジュールを確認 |

### リトライ仕様

リトライは行わない。エラー発生時はエラーコードで終了。

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

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

## パフォーマンス要件

- JITコンパイルによる初回実行オーバーヘッドの最小化
- オブジェクトキャッシュによる再コンパイル回避
- 遅延コンパイルによるスタートアップ時間削減

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

- 入力IRの検証
- JIT生成コードのメモリ保護
- 外部ライブラリロード時の権限確認

## 備考

lliはORC JIT、MCJIT、インタプリタの3つの実行モードをサポートしている。ORC JITが推奨される。

---

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

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

### 推奨読解順序

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

lliのメイン処理フローを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | lli.cpp | `llvm/tools/lli/lli.cpp` | メイン関数とJIT種別分岐 |

**主要処理フロー**:
1. **419-449行目**: main関数 - 初期化と基本セットアップ
2. **427-429行目**: InitializeNativeTarget - ネイティブターゲット初期化
3. **446-449行目**: JIT種別によるrunOrcJIT分岐
4. **452-746行目**: MCJIT/インタプリタモードの処理

**読解のコツ**: main関数はJIT種別（MCJIT/ORC/Interpreter）によって処理が大きく分岐する。ORC JITはrunOrcJIT関数で、MCJIT/インタプリタはmain関数内で処理される。

#### Step 2: ORC JIT処理を理解する

ORC JIT使用時の処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | lli.cpp | `llvm/tools/lli/lli.cpp` | runOrcJIT関数 |

**主要処理フロー**:
1. **918-1184行目**: runOrcJIT関数
2. **922-934行目**: ThreadSafeContext生成とモジュール読み込み
3. **936-944行目**: LLLazyJITBuilder設定
4. **1044行目**: Builder.create()でLLJIT生成
5. **1172-1174行目**: エントリー関数検索と実行

#### Step 3: MCJIT処理を理解する

MCJIT使用時の処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | lli.cpp | `llvm/tools/lli/lli.cpp` | main関数内MCJIT処理 |

**主要処理フロー**:
- **476-509行目**: EngineBuilder設定
- **520-528行目**: ExecutionEngine生成
- **626-629行目**: エントリー関数取得
- **681行目**: runFunctionAsMain実行

#### Step 4: オブジェクトキャッシュを理解する

JITコンパイル結果のキャッシュ処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | lli.cpp | `llvm/tools/lli/lli.cpp` | LLIObjectCacheクラス |

**主要処理フロー**:
- **299-364行目**: LLIObjectCacheクラス
- **309-323行目**: notifyObjectCompiled - コンパイル結果保存
- **325-342行目**: getObject - キャッシュからの取得

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

```
main (lli.cpp:419)
    │
    ├─ InitializeNativeTarget()
    ├─ InitializeNativeTargetAsmPrinter()
    ├─ InitializeNativeTargetAsmParser()
    │
    ├─ [ORC] runOrcJIT (lli.cpp:918)
    │      │
    │      ├─ loadModule
    │      ├─ LLLazyJITBuilder::create
    │      ├─ J->addLazyIRModule / J->addIRModule
    │      ├─ J->initialize
    │      └─ runAsMain
    │
    └─ [MCJIT/Interpreter]
           │
           ├─ parseIRFile
           ├─ EngineBuilder::create
           ├─ EE->addModule
           ├─ EE->runStaticConstructorsDestructors
           └─ EE->runFunctionAsMain
```

### データフロー図

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

LLVM IR (.bc/.ll) ──▶ parseIRFile ──▶ Module
       │                                 │
       │                                 ▼
プログラム引数 ───────────────────▶ ExecutionEngine / LLJIT
                                         │
                                    [JIT種別]
                                    ┌────┴────┐
                                    │         │
                                    ▼         ▼
                               ORC JIT   MCJIT/Interp
                                    │         │
                                    └────┬────┘
                                         ▼
                                  main関数実行
                                         │
                                         ▼
                                    終了コード
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| lli.cpp | `llvm/tools/lli/lli.cpp` | ソース | メインドライバ |
| ForwardingMemoryManager.h | `llvm/tools/lli/ForwardingMemoryManager.h` | ヘッダ | リモートメモリ管理 |
| ExecutionEngine.h | `llvm/include/llvm/ExecutionEngine/ExecutionEngine.h` | ヘッダ | 実行エンジン抽象化 |
| LLJIT.h | `llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h` | ヘッダ | ORC JIT API |
| MCJIT.h | `llvm/include/llvm/ExecutionEngine/MCJIT.h` | ヘッダ | MCJIT API |
| Interpreter.h | `llvm/include/llvm/ExecutionEngine/Interpreter.h` | ヘッダ | インタプリタAPI |
