# Phase 10: Cranelift JIT Backend（MIR→VM→Cranelift）

Status: Planned (Primary path for native speed)
Last Updated: 2025-08-25

## 🎯 ゴール
- 実行系の主経路を「MIR→VM」を維持しつつ、ホットパスをCraneliftでJIT化して高速化する。
- LLVM AOTは後段（Phase 11以降）の研究対象へ繰り延べ。

## 🔗 位置づけ
- これまでの案（MIR→LLVM AOT）を改め、現実的な開発速度と安定性を優先してCranelift JITを先行。
- VMとのハイブリッド実行（OSR/ホットカウントに基づくJIT）を採用。

## 📐 アーキテクチャ
```
AST → MIR → Optimizer → VM Dispatcher
                         └─(Hot)→ Cranelift JIT (fn単位)
```
- VMが命令カウント・プロファイルを集計し、しきい値超過関数をJITコンパイル。
- JIT済み関数は関数テーブルから直接呼び出し、VMはフォールバック先として維持。

## 📋 スコープ
1) 基盤
- JITマネージャ（関数プロファイル・コンパイルキャッシュ）
- Craneliftコード生成（MIR→CLIF Lower）
- 呼出しABI（Nyash VMスタック/レジスタとのブリッジ）

2) 命令カバレッジ（段階導入）
- Phase A: Const/Copy/BinOp/Compare/Jump/Branch/Return（純関数相当）
- Phase B: Call/BoxCall/ArrayGet/ArraySet（ホットパス対応）
- Phase C: TypeOp/Ref*/Weak*/Barrier（必要最小）

3) ランタイム連携
- Boxの所有・参照モデルを維持（共有/クローンの意味論を破らない）
- 例外・TypeErrorはVMの例外パスへエスケープ

## ✅ 受け入れ基準（Milestone）
- M1: 算術/比較/分岐/returnの関数がJIT化され、VMより高速に実行
- M2: Array/Mapの代表操作（get/set/push/size）がJITで安定動作
- M3: BoxCallホットパス（特にArray/Map）で有意な高速化（2×目標）
- M4: 回帰防止のベンチと`--vm-stats`連携（JITカウント/時間）

## 🪜 実装ステップ
1. JITマネージャ/関数プロファイルの導入（VM統計と統合）
2. MIR→CLIF Lower骨子（基本型/算術/比較/制御）
3. 呼出しABIブリッジ（引数/戻り値/BoxRefの表現）
4. JIT関数テーブル + VMディスパッチ切替
5. Array/Map/BoxCallのホットパス最適化
6. TypeOp/Ref/Weak/Barrierの必要最小を実装
7. ベンチ/スナップショット整備・回帰検出

## ⚠️ 依存・前提
- MIR26整合（TypeOp/WeakRef/Barrierの統合前提）
- P2PBox再設計（Phase 9.x）を先に安定化しておく（VM/プラグインE2E維持）

## 📚 参考
- Cranelift: Peepmatic/CLIF、simple_jitの最小例
- JIT/VMハイブリッド: LuaJIT/HotSpotのOSR設計

---
備考: LLVM AOTはPhase 11以降の研究路線に移行（設計ドキュメントは維持）。

## 🔬 Sub-Phases (10_a .. 10_h)

各サブフェーズは「小さく立ち上げ→検証→次へ」。既存のVM/Thunk/PICを活用し、JITは同じ経路に自然合流させる。

### 10_a: JITブートストラップ（基盤＋プロファイラ）
- 目的: Cranelift JITの骨組みとホット関数検出の導線を用意。
- 具体: 
  - `JitManager`（関数プロファイル、しきい値、キャッシュ）
  - CLIF環境初期化（`Module`, `Context`, `ISA`）
  - VM統合: 関数入口でホット度チェック→JITコンパイル/呼び出し
  - 診断: `NYASH_JIT_STATS=1`（JIT件数/時間/キャッシュヒット）
- 受入: ダミー関数をJIT登録してVMから呼出可能、ログが出る

### 10_b: Lower(Core-1) – Const/Move/BinOp/Cmp/Branch/Ret
- 目的: ループや条件分岐を含む純粋関数をJIT実行可能に。
- 具体:
  - MIR値/型→CLIF型（i64/f64/i1/void）
  - Const/Copy/算術/比較/ジャンプ/分岐/return のLower
  - フレームレイアウト（VMValue最小表現）
- 受入: 算術/比較/分岐のみの関数がJITでVMより速い（小ベンチ）

### 10_c: ABI/呼出し – 関数呼び出しとフォールバック
- 目的: JIT化関数から他関数を呼ぶ/VMへ戻る道を用意。
- 具体:
  - 同一モジュール関数呼び出し（JIT→JIT／JIT→VM）
  - 引数/戻り値の受け渡し（整数/浮動/void）
  - 例外/TypeErrorはVMへバイアウト（trap→VM）
- 受入: 再帰/多段呼び出しが安定動作

### 10_d: コレクション基礎 – Array/Map ホット操作（外部呼び出し）
- 目的: 実用的ホットパス（length/get/set/push/pop）をJIT側から呼べるように。
- 具体:
  - ホスト関数テーブル（外部シンボル）で既存Rust実装を呼ぶ
  - 境界チェック/エラーはRust側に委譲、JITは薄い橋渡し
- 受入: Array操作がVM経由より高速（目安1.5–2.0×）

Status（2025-08-27）
- Param経路でのE2Eを実装（`NYASH_JIT_HOSTCALL=1`ゲート）
- 実装済みシンボル（PoC, C-ABI in Rust）:
  - `nyash.array.{len,push,get,set}` / `nyash.map.size`
- 使い方（例）:
```bash
cargo build --features cranelift-jit --release
NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EXEC=1 \
  ./target/release/nyash --backend vm examples/jit_array_param_call.hako
NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EXEC=1 \
  ./target/release/nyash --backend vm examples/jit_map_param_call.hako
```
Notes
- 関数パラメータに渡した配列/MapのみHostCall経由でアクセス（thread-local引数参照）
- ローカルnew値は10_eへ移管（ハンドル表PoC: u64→Arc<Box>）

### 10_e: BoxCall高速化 – Thunk/PICの直結
- 目的: Phase 9.79bの `TypeMeta{slot->thunk}` と Poly-PIC をJITにインライン。
- 具体:
  - `slot -> thunk -> target` 解決をJITで再現（ユニバーサル0..3含む）
  - `(type_id, version)` チェック（Poly-PIC 2–4件）→ヒット直呼び、ミスVM
  - バージョンミスマッチで安全にフォールバック
- 受入: BoxCallホットサイトで2×以上の高速化＋正しい無効化挙動

### 10_f: TypeOp/Ref/Weak/Barrier（最小）
- 目的: 実アプリで必要な最小限のタイプ/参照操作を埋める。
- 具体:
  - `as_bool()` 等の基本型変換
  - 参照/弱参照/バリアの最小パス（重い経路はVMへ）
- 受入: 代表的コードパスでJIT有効のままE2E成功

### 10_g: 診断/ベンチ/回帰
- 目的: 可視化と安定化。
- 具体:
  - `--vm-stats` にJIT統計統合（compile/ms, sites, cache率）
  - ベンチ更新（JIT有/無比較）とスナップショット
- 受入: CIで回帰検知可能／ドキュメント更新

### 10_h: 硬化・パフォーマンス調整
- 目的: ホットスポットの最適化とノイズ除去。
- 具体:
  - ガード配置最適化（分岐予測/ICヒット優先）
  - 不要コピー削減、ホスト呼出回数の削減
- 受入: 代表ベンチで安定して目標達成（2×以上）

## 📦 成果物（各サブフェーズ）
- 10_a: `jit/manager.rs` スケルトン、VM連携、統計ログ
- 10_b: `jit/lower/core.rs`（Const/BinOp/Cmp/Branch/Ret）＋単体テスト
- 10_c: `jit/abi.rs`（call/ret/fallback）＋再帰テスト
- 10_d: `jit/extern/collections.rs`（Array/Mapブリッジ）＋マイクロベンチ
- 10_e: `jit/inline_cache.rs`（PIC/VT連携）＋無効化テスト
- 10_f: `jit/lower/typeop_ref.rs`（最小）
- 10_g: ベンチ/統計/README更新
- 10_h: 最適化コミットと測定レポート

## 🧩 既存資産との連携（重要）
- Thunk: Phase 9.79b.3の `TypeMeta{thunks}` をJIT直呼びターゲットとして使用
- Poly-PIC: VMの構造をJITに投影（同じキー `(label, version)` を使用）
- Versioning: `cache_versions` のイベントに同期してIC無効化

## 🎯 マイルストーン再定義
- M1: 10_a + 10_b 合格（Core関数のJIT実行）
- M2: 10_c + 10_d 合格（関数呼出/Arrayホット操作）
- M3: 10_e 合格（BoxCallホットパス2×）
- M4: 10_g + 10_h 合格（ベンチ/統計/硬化）

## ⚠️ リスクと緩和
- ABI複雑化: まず整数/浮動/voidに限定し、BoxRefはホスト関数へブリッジ
- 最適化過剰: 常にVMフォールバックを保持、ガード失敗で安全に戻す
- デバッグ困難: CLIFダンプ/CFG表示/`NYASH_JIT_STATS`で観測

## 🐛 発見した問題点（2025-08-27 ベンチマーク実行時）

### 1. インタープリター性能問題
- **問題**: 10万回のループで2分以上かかりタイムアウト
- **原因**: `unwrap_instance`のデバッグログが大量出力（毎回の演算でInstanceBoxチェック）
- **目標**: 10万回ループを数秒で完了
- **対策**: 
  - デバッグログの条件付き出力化
  - 基本演算の高速化（IntegerBoxの直接操作最適化）

### 2. VMの変数管理エラー
- **問題**: `Invalid value: Value %47 not set` - simple_add_loop内の変数zが正しく管理されていない
- **原因**: MIR生成時の変数スコープ管理の不具合
- **対策**: MirBuilderの変数トラッキング改善

### 3. Box APIの成熟度
- **問題**: TimeBoxにelapsed()/reset()メソッドがインタープリターから呼べない
- **原因**: Boxメソッドの登録システム未完成
- **対策**: 
  - Boxメソッドの統一的登録システム実装
  - インタープリターとVMのメソッド解決統一

### 4. ベンチマーク基盤
- **問題**: Nyashスクリプトでの正確な時間計測が困難
- **根本原因**: TimeBoxのelapsed()/reset()メソッドがインタープリターから呼べない（Box API問題と同じ）
- **対策**: Box APIの成熟度問題（問題3）が解決すれば自動的に解決

### 改善優先度
1. **高**: インタープリター性能問題（基本機能の使い物にならない）
2. **中**: VM変数管理（JIT最適化の前提）
3. **中**: Box APIの成熟度（ベンチマーク基盤も同時解決）

## 🚀 Phase 10.9: Cranelift AOT Backend（追加計画）

Status: Future (JIT実装の上乗せで実現可能)

### 概要
JIT実装（10_a～10_h）で構築したMIR→CLIF変換基盤をそのまま活用し、事前コンパイル（AOT）によるスタンドアロン実行ファイル生成を実現する。

### 利点
- **コード再利用**: JITと同じLowerCore実装を使用（追加実装最小）
- **非同期完全サポート**: WASMの制限なし、ネイティブ非同期可能
- **最高性能**: ネイティブコード直接実行（起動時コンパイル不要）
- **デバッグ容易**: gdb/lldb等のネイティブデバッガ使用可能

### 実装ステップ案
```
10.9a: ObjectModule統合
├── cranelift-objectモジュール導入
├── CLIF→オブジェクトファイル生成
└── 既存のLowerCore再利用

10.9b: ランタイムライブラリ
├── Nyash標準Box群の静的リンク版作成
├── プラグインの静的埋め込み対応
└── 最小ランタイム（GC hooks等）分離

10.9c: リンカー統合
├── cc/ldによる実行ファイル生成
├── プラットフォーム別設定
└── デバッグシンボル生成

10.9d: クロスコンパイル
├── 複数ターゲット（x86_64/aarch64/wasm32）
├── ターゲット別最適化
└── CI/CDでのマルチプラットフォームビルド
```

### 使用イメージ
```bash
# ネイティブ実行ファイル生成
./target/release/nyash --compile-native program.hako -o program
./program  # スタンドアロン実行！

# クロスコンパイル
./target/release/nyash --compile-native --target x86_64-pc-windows-msvc program.hako -o program.exe
./target/release/nyash --compile-native --target aarch64-apple-darwin program.hako -o program.mac
```

### 技術的詳細
- **共通基盤**: `LowerCore`のemit処理はJIT/AOT両対応
- **差分実装**: JITは`JITModule`、AOTは`ObjectModule`を使用
- **リンク方式**: 静的リンク優先（配布容易性重視）
- **サイズ最適化**: LTO/strip対応で実行ファイルサイズ削減

### WASM AOTとの比較
| 特性 | Cranelift AOT | WASM AOT |
|------|--------------|----------|
| 非同期 | ✅ 完全対応 | ❌ 制限あり |
| 実行速度 | 最速 | 速い |
| ファイルサイズ | 大（MB級） | 小（KB級） |
| ポータビリティ | プラットフォーム別 | 高い |
| デバッグ | ネイティブツール | 限定的 |

### 想定スケジュール
- Phase 10（JIT）安定化後に着手
- 実装期間: 2-3週間（JIT基盤の再利用により短期実現可能）
- 初期ターゲット: Linux x86_64、その後Windows/macOS対応
