feat(joinir): Phase 286 P2.6 - Pattern3 Plan 基盤 + Pattern1 退行修正

## Pattern1 退行修正(構造的 Fail-Fast)
- Router に pattern_kind ガード追加(ctx.pattern_kind != Pattern1SimpleWhile → skip)
- has_if_else_statement() ヘルパー追加(再帰版、ScopeBox/Loop 内もチェック)
- Pattern1 extractor に if-else 拒否追加

## Pattern3 Plan 基盤
- DomainPlan: Pattern3IfPhiPlan 構造体追加
- Extractor: extract_pattern3_plan() 追加
- Normalizer: normalize_pattern3_if_phi() スタブ追加(レガシー JoinIR へフォールバック)
- Router: PLAN_EXTRACTORS に Pattern3 追加

## テスト結果
- quick 154 PASS
- Phase 118 smoke PASS(出力 12、退行解消)

🤖 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:01:11 +09:00
parent 21daf1b7dd
commit 4d17e3d812
7 changed files with 307 additions and 2 deletions

View File

@ -1,6 +1,6 @@
# Phase 286: JoinIR Line AbsorptionJoinIR→CorePlan/Frag 収束)
Status: In Progress (P0, P1, P2, P2.1, P2.2, P2.3, P3, 286C-2 COMPLETE)
Status: In Progress (P0, P1, P2, P2.1, P2.2, P2.3, P3, 286C-2 COMPLETE, P2.6 IN PROGRESS)
## Goal
@ -249,6 +249,41 @@ Phase 286 では JoinIR line を “第2の lowerer” として放置せず、*
- Regression test: quick smoke 0 failed
- Debug log: `route=plan strategy=extract pattern=Pattern8_BoolPredicateScan` 確認
### P2.6 (Pattern3 Plan化 PoC + Pattern1 退行修正) 🚧 IN PROGRESS (2025-12-26)
**背景**:
- **退行バグ発見**: `apps/tests/phase118_pattern3_if_sum_min.hako` が FAIL (期待 12、実際 10)
- **原因**: Pattern1 Plan が Pattern3 fixture を誤ってマッチ
- Pattern1 extractor の `has_control_flow_statement()` が if/else をチェックしていない
- pattern_kind ガードもなく、Pattern1 Plan が Pattern3 にマッチしていた
**実装内容**:
**Step 0: Pattern1 退行修正(最優先)** ✅ COMPLETE
- **0.1 Router guard**: `router.rs``try_plan_extractors()` で Pattern1 Plan は `ctx.pattern_kind == Pattern1SimpleWhile` のみマッチ
- **0.2 has_if_statement 追加**: `common_helpers.rs` に再帰的 if 検出ヘルパー追加
- **0.3 Pattern1 extractor 強化**: `has_if_statement()` による if-else 拒否を追加防御in深さ
- **検証**: phase118 PASS (出力 12)、legacy Pattern3 ルートが正しく動作
**Step 1: Pattern3 Plan line 実装** (予定)
- **DomainPlan 追加**: `Pattern3IfPhiPlan { loop_var, carrier_var, condition, if_condition, then_update, else_update, loop_increment }`
- **Extractor**: `extract_pattern3_plan()` - 既存 `extract_loop_with_if_phi_parts()` を活用
- **Normalizer**: CFG構造 `preheader → header(PHI: i, sum) → body → then/else → merge(PHI: sum) → step → header → after`
- **Router**: PLAN_EXTRACTORS に Pattern3 追加Pattern1 より前、Pattern4 より後)
**成果物** (予定):
- `src/mir/builder/control_flow/joinir/patterns/router.rs` (変更: Pattern1 guard ✅)
- `src/mir/builder/control_flow/joinir/patterns/extractors/common_helpers.rs` (変更: has_if_statement ✅)
- `src/mir/builder/control_flow/joinir/patterns/extractors/pattern1.rs` (変更: if 拒否 ✅)
- `src/mir/builder/control_flow/plan/mod.rs` (変更: Pattern3IfPhiPlan + DomainPlan variant)
- `src/mir/builder/control_flow/joinir/patterns/extractors/pattern3.rs` (変更: extract_pattern3_plan)
- `src/mir/builder/control_flow/plan/normalizer.rs` (変更: normalize_pattern3_if_phi)
**成功基準**:
- Regression fix: `phase118_pattern3_if_sum_vm` PASS (出力 12) ✅
- Pattern3 Plan line: `route=plan pattern=Pattern3_IfPhi` 確認
- Full regression: `tools/smokes/v2/run.sh --profile quick` 0 failed
## AcceptanceP0
- 2本の lowering が "設計として" どこで 1 本に収束するかが明文化されている