6.4 KiB
6.4 KiB
Phase 268: if_form.rs への Frag 適用 + Entry Edge-args SSOT化
Status: ✅ 完了(P0 + P1) Date: 2025-12-21
目的
EdgeCFG Fragment を "層を跨がずに" 実戦投入
- P0:
if_form.rsの emit_conditional + emit_jump を Frag+emit_frag に置換(1箇所のみ) - P1: compose::if_() の then/else entry edge-args を SSOT 化(TODO 解消)
実装結果
P0: 最小適用(emission 層経由)
アーキテクチャ戦略:
if_form.rsに直接 Frag 構築コードを書かず、emission/branch.rsに薄い入口関数emit_conditional_edgecfg()を追加- 理由: 層が綺麗(Frag 構築は emission 層に閉じる)、差分が小さい(if_form.rs は API 呼び出し差し替えのみ)、デバッグ容易(層境界が明確)
アーキテクチャ図:
if_form.rs (MirBuilder 層)
↓ 呼び出し
emission/branch.rs::emit_conditional_edgecfg() (emission 層: 薄ラッパー)
↓ 内部で使用
Frag 構築 + compose::if_() + emit_frag() (EdgeCFG Fragment API)
↓ 最終的に呼び出し
set_branch_with_edge_args() / set_jump_with_edge_args() (Phase 260 SSOT)
変更内容:
-
emission/branch.rs に
emit_conditional_edgecfg()関数追加(~50行)- 責務: Frag 構築 + compose::if_() + emit_frag() の薄いラッパー
- Then/Else Frag 構築(then_exit_block/else_exit_block から Normal exit 作成)
- Join Frag 構築
- compose::if_() で合成
- emit_frag() で MIR terminator に変換
-
if_form.rs API 呼び出し差し替え
- Lines 109-114: 削除(emit_conditional 呼び出し)
- Line 147: 削除(emit_jump 呼び出し)
- Line 202: 削除(emit_jump 呼び出し)
- Line 206: 追加(emit_conditional_edgecfg 呼び出し、~10行)
- 差分: 削除3箇所 + 追加1箇所のみ(層が綺麗)
テスト結果:
- ✅ cargo build --release: 成功
- ✅ cargo test --lib --release: 1395 tests PASS
- ✅ quick smoke: 45/46 PASS(既存状態維持)
P1: compose::if_() Entry Edge-args SSOT化
目的: compose::if_() 内部で then/else entry edge-args を "勝手に空 Vec で生成" しない → 呼び出し側が明示的に渡す(SSOT 原則)
変更内容:
-
compose.rs (Lines 106-127): compose::if_() シグネチャ変更
- Before:
if_(header, cond, t, e, join_frag) - After:
if_(header, cond, t, then_entry_args, e, else_entry_args, join_frag) - TODO コメント削除完了(Phase 267 P2+ TODO 解消)
- Before:
-
emission/branch.rs (Lines 110-125): emit_conditional_edgecfg() から空 EdgeArgs を渡す
compose::if_( pre_branch_bb, condition_val, then_frag, EdgeArgs { layout: CarriersOnly, values: vec![] }, // then entry args else_frag, EdgeArgs { layout: CarriersOnly, values: vec![] }, // else entry args join_frag, ) -
テスト更新(3箇所):
- compose.rs: Lines 638-652, 720-734(2箇所)
- emit.rs: Lines 555-569(1箇所)
- 全て新シグネチャに更新、空 EdgeArgs を渡す
テスト結果:
- ✅ cargo build --release: 成功(0エラー)
- ✅ cargo test --lib --release: 1444/1444 PASS
- ✅ quick smoke: 45/46 PASS(既存状態維持)
核心的な設計判断
P0: なぜ emission 層経由か
- 層が綺麗: Frag 構築ロジックを emission 層に閉じ込め、MirBuilder 層から分離
- 差分が小さい: if_form.rs は API 呼び出し差し替えのみ(3箇所削除 + 1箇所追加)
- デバッグ容易: 層境界が明確で問題切り分けが簡単
- 拡張性: 将来他の箇所(loop_form.rs 等)も同じパターンで統一可能
P1: なぜ SSOT 化か
- 推測禁止: compose::if_() 内部で then/else entry edge-args を "勝手に空 Vec で生成" しない
- 呼び出し側 SSOT: P0 で emission/branch.rs に薄いラッパーを作ったので、edge-args も同じ層で SSOT として渡す
- P0 との整合性: Frag 構築と edge-args 提供を同じ層(emission)に集約
重要な発見
Frag "from" ブロックの厳密性
- then_exit_block/else_exit_block は「実際に merge へ飛ぶブロック」と一致必須
- ✅ 正しい: if_form.rs Line 141, 197 で取得済みの値を使用
- ❌ 誤り: "それっぽい" ブロックから Normal exit を作成(ズレる)
JoinIR Fallback との非交差
- JoinIR 経路は PHI のみ処理(terminator 非依存、Line 287-298)
- terminator 生成(emit_conditional_edgecfg)と PHI 生成(JoinIR)は完全に分離されている
- 競合可能性なし
次フェーズへの橋渡し
Phase 269: Pattern への展開
- Pattern6/7/8 を Frag 化
- NormalizedShadow/JoinIR への適用
- pattern番号分岐削減
- fixture + smoke test
関連ドキュメント
- 設計図:
docs/development/current/main/design/edgecfg-fragments.md - 現在のタスク:
docs/development/current/main/10-Now.md - バックログ:
docs/development/current/main/30-Backlog.md - Phase 267:
docs/development/current/main/phases/phase-267/README.md
受け入れ基準(全達成)
P0 成功条件
- ✅
cargo build --release成功 - ✅
cargo test --lib --releaseで 1395 tests PASS - ✅
tools/smokes/v2/run.sh --profile quickで 45/46 PASS - ✅ MIR dump で Branch/Jump terminator 正常生成確認
- ✅ JoinIR fallback 経路動作確認
P1 成功条件
- ✅
cargo build --release成功 - ✅
cargo test --lib --releaseで 1444 tests PASS - ✅ compose.rs/emit.rs unit tests 全 PASS
- ✅
tools/smokes/v2/run.sh --profile quickで 45/46 PASS 維持 - ✅ TODO コメント削除完了(Phase 267 P2+ TODO 解消)
- ✅ Edge-args パラメータ SSOT 化完了
- ✅ ドキュメント更新完了(4ファイル):
- ✅ 10-Now.md 追記
- ✅ 30-Backlog.md 更新
- ✅ edgecfg-fragments.md 追記
- ✅ phases/phase-268/README.md 新規作成
まとめ
Phase 268 P0-P1 完全成功!
- ✅ EdgeCFG Fragment の最初の実戦投入(if_form.rs)
- ✅ emission 層経由で層境界を綺麗に保つアーキテクチャ確立
- ✅ compose::if_() の entry edge-args SSOT 化完了
- ✅ 全テスト PASS(1444 tests + 45/46 smoke)
- ✅ TODO 削除完了
次のステップ: Phase 269 で Pattern6/7/8 への Frag 適用 + fixture/smoke test