Files
hakorune/docs/development/roadmap/phases/phase-12.5/optimization-strategy.txt

208 lines
7.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

================================================================================
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<bool>, // 分岐予測ヒント
cold: bool, // めったに実行されない
// ループ特性
loop_count: Option<u32>, // ループ回数ヒント
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の最適化哲学。