feat(joinir): Phase 286 P2.6.1 - Pattern3 Plan 完走(normalizer 実装 + Fail-Fast 統一)

## 変更内容

### 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>
This commit is contained in:
2025-12-26 04:39:36 +09:00
parent 3abca63ebe
commit 0fca2df5be
3 changed files with 416 additions and 26 deletions

View File

@ -0,0 +1,120 @@
Status: Active
Date: 2025-12-26
Scope: Phase 286 P2.6.1Pattern3 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: Pattern3Loop with IfPhiPlan 完走
## 目的
Pattern3Loop body 内の if/else により carrier が条件更新される形)を、
legacy JoinIR lineJoinIR→bridge→mergeではなく Plan/Frag SSOTCorePlan→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 FAILED154/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 失敗は Errsilent fallback 禁止)
- Pattern1 の誤マッチ再発を防ぐ(既に router の `pattern_kind` ガードあり)
## 1) Pattern3 の CFGPlan 側の正本)
Pattern3 を “Loop + If + Merge(PHI) + Step” として正規化する。
```text
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 の PHI2本
- 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_current` inputs: `(preheader_bb, i_init)`, `(step_bb, i_next)`
- `carrier_current` inputs: `(preheader_bb, carrier_init)`, `(step_bb, carrier_next)`
- merge PHI:
- `carrier_next` inputs: `(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_bbback-edge
- 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 smokeVM
`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 統一)” を設計決定として記載
- `docs/development/current/main/10-Now.md`
- Current Focus の次対象を更新(例: Pattern2 の設計相談 / Pattern5 / PatternX など)