================================================================================ Phase 12.5: MIR15最適化戦略 - コンパイラ丸投げ作戦 ================================================================================ 【基本哲学】 「CPU(コンパイラ)に丸投げできるところは丸投げ」 MIR15の美しさ(15命令)を保ちながら、実用的な性能を達成する戦略。 自前で複雑な最適化を実装するのではなく、既存の成熟したコンパイラ技術を活用。 ================================================================================ 1. 最適化の境界線 ================================================================================ ■ MIR15側でやること(軽量・意味保存のみ) ├─ 定数畳み込み(Const Folding) │ └─ Const(3) + Const(5) → Const(8) ├─ デッドコード除去(DCE) │ └─ 未使用のStore、到達不能コード除去 ├─ 分岐単純化(Branch Folding) │ └─ if true → Jump、if false → 削除 ├─ CFG整理 │ └─ 空ブロック除去、ブロック併合 └─ 軽量インライン化 └─ 小さい関数のみ(10命令以下)、再帰なし ■ MIR15側でやらないこと(コンパイラに丸投げ) ├─ ループ最適化 │ └─ アンローリング、LICM、ベクトル化 → Cコンパイラ/LLVM ├─ レジスタ割り当て │ └─ 完全にバックエンドに任せる ├─ 命令選択・スケジューリング │ └─ CPU依存の最適化は触らない └─ SIMD/並列化 └─ 高度な最適化は成熟したツールに ================================================================================ 2. ヒントシステム(命令を増やさずに最適化を強化) ================================================================================ ■ MIRMetadataの設計 struct MIRMetadata { // 関数特性 pure: bool, // 副作用なし(同じ引数→同じ結果) readonly: bool, // グローバル状態を読まない noalias: bool, // ポインタエイリアスなし nothrow: bool, // 例外を投げない // 制御フロー likely: Option, // 分岐予測ヒント cold: bool, // めったに実行されない // ループ特性 loop_count: Option, // ループ回数ヒント vectorizable: bool, // ベクトル化可能 } ■ 適用例 BoxCall("StringBox", "length") → {pure: true, readonly: true, nothrow: true} BoxCall("ConsoleBox", "log") → {pure: false, readonly: false} Branch(cond, then, else) → {likely: Some(true)} // thenが高確率 ================================================================================ 3. バックエンド別マッピング ================================================================================ ■ Cエミッタ(zig cc / clang / MSVC) ├─ pure → __attribute__((pure)) ├─ readonly → __attribute__((const)) ├─ noalias → restrict ├─ likely → __builtin_expect └─ cold → __attribute__((cold)) ■ Cranelift ├─ ヒントをCranelift IRのフラグに変換 └─ 特にループとメモリアクセスのヒントが効果的 ■ LLVM(実装済み・依存重いため非推奨) ├─ 完全なメタデータサポート ├─ !llvm.loop.vectorize.enable ├─ !prof 分岐確率 ├─ noalias, readonly等の属性 └─ ※Phase 11で実装完了、動作確認済み ================================================================================ 4. 段階的最適化レベル ================================================================================ Level 0: 開発モード - MIR最適化なし - デバッグ情報完全保持 - nyash program.hako Level 1: 基本最適化(デフォルト) - MIRカノニカル化のみ - Cエミッタ → gcc -O2 - nyash --release program.hako Level 2: 高速化 - MIR全最適化パス - Cエミッタ → zig cc -O3 -flto - nyash --release --opt program.hako Level 3: プロファイルガイド(PGO) - 実行プロファイル収集 - ホットパス特定 - nyash --release --pgo program.hako Level 4: 特殊用途 - SIMD必要 → LLVM使用(ただし依存が重い) - 起動速度重視 → Cranelift JIT(推奨) - nyash --backend cranelift program.hako ================================================================================ 5. 実装計画 ================================================================================ Phase 12.5.1: 基盤整備(1週間) □ MIRMetadata構造体追加 □ 各MIR命令にmetadataフィールド追加 □ デフォルトヒントの設定 Phase 12.5.2: MIR最適化パス(1週間) □ ConstFoldingPass実装 □ DeadCodeElimPass実装 □ BranchFoldingPass実装 □ CFGCleanupPass実装 □ LightInliningPass実装 Phase 12.5.3: バックエンド統合(2週間) □ Cエミッタでヒント→属性変換 □ zig cc最適化オプション統合 □ MSVC最適化オプション対応 □ 簡易ベンチマーク作成 Phase 12.5.4: 評価・調整(1週間) □ 各最適化レベルの性能測定 □ コンパイル時間 vs 実行時間のトレードオフ評価 □ ドキュメント作成 ================================================================================ 6. 成功指標 ================================================================================ - MIR15の命令数は変更なし(15命令維持) - 基本的なベンチマークで既存言語の70%以上の性能 - コンパイル時間は既存言語の10%以下 - 最適化パスのコード行数は1000行以下 ================================================================================ 7. リスクと対策 ================================================================================ リスク1: ヒントが複雑になりすぎる → 対策: 自動推論を強化、明示的ヒントは最小限 リスク2: バックエンド依存が強くなる → 対策: 共通ヒントセットを定義、バックエンド固有は分離 リスク3: 性能が期待に達しない → 対策: プロファイリング強化、ボトルネック特定 ================================================================================ 8. なぜこの戦略が最適か ================================================================================ 1. シンプルさの維持 - MIR15の美しさを損なわない - 最適化バグのリスク最小化 2. 実用的な性能 - 成熟したコンパイラ技術を活用 - 必要十分な性能を達成 3. 開発効率 - 車輪の再発明を避ける - 既存ツールチェーンと協調 4. 将来性 - コンパイラの進化を自動的に享受 - 新しいCPUアーキテクチャにも対応 ================================================================================ 9. Phase 11からの知見 ================================================================================ LLVM実装完了から得られた重要な知見: 1. 技術的成功・実用的課題 - LLVM統合は技術的に成功 - しかし依存関係が重すぎる(ビルド時間・バイナリサイズ) - Craneliftが現実的な選択肢 2. コンパイラ丸投げ戦略の妥当性 - LLVMの重さを経験したことで、Cコンパイラ活用の価値を再認識 - zig cc / clang / MSVCは既にインストール済み - 追加依存なしで高性能を達成可能 3. 段階的アプローチの重要性 - 必要な時だけ重い最適化 - デフォルトは軽量・高速 - ユーザーが選択可能 ================================================================================ 「シンプルなMIR × 賢いコンパイラ = 実用的な性能」 これがNyashの最適化哲学。