## 変更内容 ### Router Fail-Fast 統一 - Pattern3 stub fallback 特例を撤去 - extract 成功 → normalize/lower 失敗は即 Err(他パターンと統一) ### normalize_pattern3_if_phi() 実装 - CFG 構造: 8 blocks (preheader, header, body, then, else, merge, step, after) - PHI 構成: 3本(header×2 + merge×1) - Header: loop_var_current, carrier_current - Merge: carrier_next (if-else 合流) - Frag: BranchStub×2 + EdgeStub×4(Pattern1 流儀の直接構築) ### 発見・修正 - lowerer は body_bb の block_effects を無視して loop_plan.body を emit - body_bb effects は CorePlan::Effect(...) として loop_plan.body に配置 ## テスト結果 - Phase 118 smoke: PASS (出力 12) - quick: 154/154 PASS - Plan line 完走確認: route=plan ... Pattern3_IfPhi MATCHED 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
5.1 KiB
Status: Active
Date: 2025-12-26
Scope: Phase 286 P2.6.1(Pattern3 Plan line を “完走” させる)手順書。実装は小刻みに、quick smoke green を維持する。
Related:
- docs/development/current/main/phases/phase-286/README.md
- docs/development/current/main/design/joinir-plan-frag-ssot.md
- docs/development/current/main/design/edgecfg-fragments.md
Phase 286 P2.6.1: Pattern3(Loop with If‑Phi)Plan 完走
目的
Pattern3(Loop body 内の if/else により carrier が条件更新される形)を、 legacy JoinIR line(JoinIR→bridge→merge)ではなく Plan/Frag SSOT(CorePlan→Frag→emit_frag)で完走させる。
成功条件(必須)
bash tools/smokes/v2/profiles/integration/apps/phase118_pattern3_if_sum_vm.shが PASS(期待値 12)./tools/smokes/v2/run.sh --profile quickが 0 FAILED(154/154 PASS 維持)HAKO_JOINIR_DEBUG=1でroute=plan ... Pattern3_IfPhiが出て、legacy fallback に落ちない
現状(P2.6 途中の状態)
extract_pattern3_plan()は実装済み(DomainPlan を返す)PlanNormalizer::normalize_pattern3_if_phi()は stub(Err(...)を返す)- router は Pattern3 のみ “stub fallback” 特例を持つ(
continueして legacy へ)
→ P2.6.1 では normalizer を実装し、router の特例を撤去して Fail-Fast に揃える。
実装方針(重要な制約)
- terminator 直生成は禁止(SSOT:
Frag + compose::* + emit_frag()) - extractor が
Someを返したら、normalize/lower 失敗は Err(silent fallback 禁止) - Pattern1 の誤マッチ再発を防ぐ(既に router の
pattern_kindガードあり)
1) Pattern3 の CFG(Plan 側の正本)
Pattern3 を “Loop + If + Merge(PHI) + Step” として正規化する。
preheader → header(PHI: i_current, carrier_current) → body(if_condition)
↓ ↓
after then | else
↓ ↓
merge(PHI: carrier_next)
↓
step(i_next)
↓
back-edge to header
ポイント:
- header に loop_var と carrier の PHI(2本)
- then/else で carrier 更新値を作る
- merge で carrier_next を PHI で合流
- step で i_next を作り、header に戻す(carrier_next も header PHI に渡る)
2) 実装タスク
2.1 normalizer 実装
対象: src/mir/builder/control_flow/plan/normalizer.rs
normalize_pattern3_if_phi(...)を stub から実装へ置換する- 既存の Pattern1/4/9/8 で確立した部品を流用する
alloc_typed(...)phi_bindings(PHI dst を AST lowering 時に優先参照)lower_value_ast / lower_compare_ast / lower_binop_ast(phi_bindings 伝播)
最低限の生成物:
- blocks:
preheader_bb, header_bb, body_bb, then_bb, else_bb, merge_bb, step_bb, after_bb - header PHI:
loop_var_currentinputs:(preheader_bb, i_init),(step_bb, i_next)carrier_currentinputs:(preheader_bb, carrier_init),(step_bb, carrier_next)
- merge PHI:
carrier_nextinputs:(then_bb, carrier_then),(else_bb, carrier_else)
- frag branches/wires:
- header:
if cond_loop then body else after - body:
if if_condition then then_bb else else_bb - then_bb: jump → merge_bb
- else_bb: jump → merge_bb
- merge_bb: jump → step_bb
- step_bb: jump → header_bb(back-edge)
- header:
- final_values: loop_var と carrier は header PHI の値を返す(既存パターンに合わせる)
2.2 router の Pattern3 特例撤去(Fail-Fast 統一)
対象: src/mir/builder/control_flow/joinir/patterns/router.rs
現状の特例(Pattern3 だけ normalize Err を握りつぶす)を削除し、以下へ統一する:
- extractor が
Some(domain_plan)を返したらlower_via_plan(...)の Err はそのまま伝播 - fallback は extractor が
Ok(None)の場合のみ
3) 検証手順(コマンド)
3.1 Pattern3 の integration smoke(VM)
bash tools/smokes/v2/profiles/integration/apps/phase118_pattern3_if_sum_vm.sh
3.2 quick regression
./tools/smokes/v2/run.sh --profile quick
3.3 Plan 完走ログ(任意)
HAKO_JOINIR_DEBUG=1 ./target/release/hakorune --backend vm apps/tests/phase118_pattern3_if_sum_min.hako 2>&1 | rg \"route=plan.*Pattern3\"
4) ドキュメント更新(完了時)
完走したら、以下を更新する(本文は短く、成果物リンク中心):
docs/development/current/main/phases/phase-286/README.md- P2.6 の Status を
COMPLETEに更新 - “router の Pattern3 特例撤去(Fail-Fast 統一)” を設計決定として記載
- P2.6 の Status を
docs/development/current/main/10-Now.md- Current Focus の次対象を更新(例: Pattern2 の設計相談 / Pattern5 / PatternX など)