Files
hakorune/docs/private/roadmap/phases/phase-20.12

Phase 20.12 — Performance Optimization (AOT & VM) + PHI Localization

目的

  • AOTEXEと VM の実行性能を、構造を崩さずに最適化する。
  • 入口は AotBoxプラグイン優先を維持し、最適化は箱の内側 or 上位スクリプト層で行うBoxFirst

性能目標(現実的レンジ)

  • EXEAOT: C言語の 60〜80%(単純ループは過去計測で ≥60% を確認済み)
  • VM: PythonCPythonと同程度±20%)を目指す
    • 備考: 箱Box生成コストがボトルネックのため、割付パターン/再利用の改善で達成を狙う

範囲

  • AOT前処理Hakoruneスクリプト層AotPrepBoxJSON正規化/定数畳み込み/リンクフラグ生成)
  • VMホットパスHakoruneスクリプト層VMHotPathBox軽量ディスパッチ/メソッドマップ事前構築)
  • 既存CABI/FFIの FailFast/短文診断方針は不変

ゲート(既定)

  • AOT 前処理: 20.12 では dev/quick プロファイルで既定 ONHAKO_AOT_PREP=1, HAKO_AOT_PREP_LANG=1)。
    • 失敗時は Rust 前処理へフォールバックし FailFast を維持。
    • CI/integration プロファイルは段階移行中は既定 OFF を維持(安定後に昇格)。
  • VM ホットパス: HAKO_VM_FAST_PATH=1既定OFF、段階導入

受け入れ基準(抜粋)

  • 代表マイクロベンチで EXE が C の 0.6× 以上、VM が Python 比 ±20% 以内
  • 既存スモークは緑FailFast/短文維持、SKIP方針は不変
  • dist 形状での FFI 既定探索は docs の手順で再現可能

ベンチ指針(起動コスト対策)

  • subtract ベースラインret0 EXE固定N の net 時間で it/s を推定(HAKO_BENCH_SUBTRACT_STARTUP=1)。
  • N 自動プローブ(HAKO_BENCH_AUTOPROBE=1, HAKO_BENCH_MIN_DT=…)で起動コスト影響を最小化。
  • inprocess ベンチwarmup → 計測のみを代表sum/mulとして併用し、EXE の実力を定点観測。

デフォルト化の方針AOT 前処理)

  • フェーズ 1本フェーズ内: dev/quick で既定 ON。負例スモークと sidecar MIR 観測で回帰監視。
  • フェーズ 2次フェーズ : integration-core で既定 ON に昇格。全ベンチ中央値が基準を満たすこと。
  • ロールバック容易性 : いずれも HAKO_AOT_PREP=0 または HAKO_AOT_PREP_LANG=0 で即座に OFF。

リスクと対策

  • 最適化で意味論が動くリスク → すべてゲート化+スモークでパリティ観測
  • リンク環境差Linuxのリンカ差→ 既存回避策(-no-pie / lld 推奨)を引き続き提示

実装メモ(このパスで詰め済み)

  • AotPrep inplace の対象関数選定を拡張:main 優先→存在しない場合は functions[] を順次走査し、最初に安全パターンが見つかった関数で inplace 置換const→ret
  • CFG 正規化最小first block の instructions 配列に限定し、二重の const + binop(+//*) + ret の連鎖のみを畳み込み。その他のCFG/複数ブロックは恒等FailFastなし
  • VM HotPath v0.1:整数 Add/Mul/Sub の superinstruction を HAKO_VM_FAST_PATH=1 時にのみ有効化。quick プロファイルで既定 ON。

PHI LocalizationLocalizationPhiBox

  • 新規箱 lowering/localize_phi.py を導入。pred==1 の場合に限り、局所PHIを作らず pred 終端のSSAを i64 正規化して“そのまま”使う。
  • mir_call.py の console 降ろしでは、PhiDispatchPoint が 0 を返した場合に LocalizationPhiBox を試行。multipred の場合は pred スナップショットの最初の値を安全に採用i64 正規化)し、最終的な意味論は predeclare→finalize の正道に委譲。
  • predeclare は multipred のみに限定empty PHI を避ける。PHI は常にブロック先頭で生成され、グルーピング/支配関係の LLVM 規約を維持。
  • スモーク追加:strict_print_loop_exe.sh(ループ最終値の print が 1000strict_print_if_merge_exe.shif-merge の print が 1000