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

@ -53,6 +53,8 @@ pub(in crate::mir::builder) enum DomainPlan {
Pattern9AccumConstLoop(Pattern9AccumConstLoopPlan),
/// Pattern8: Boolean Predicate Scan (Phase 286 P2.4)
Pattern8BoolPredicateScan(Pattern8BoolPredicateScanPlan),
/// Pattern3: Loop with If-Phi (Phase 286 P2.6)
Pattern3IfPhi(Pattern3IfPhiPlan),
}
/// Phase 273 P0: Scan direction for forward/reverse scan
@ -176,6 +178,53 @@ pub(in crate::mir::builder) struct Pattern8BoolPredicateScanPlan {
pub step_lit: i64,
}
/// Phase 286 P2.6: Extracted structure for Pattern3 (Loop with If-Phi)
///
/// This structure contains all the information needed to lower an if-phi merge loop.
/// Pattern3 is a loop with conditional carrier update via if-else branching.
///
/// # Structure
/// ```text
/// loop(i < N) {
/// if (condition) {
/// carrier = then_update
/// } else {
/// carrier = else_update
/// }
/// i = i + step
/// }
/// ```
///
/// # CFG Layout
/// ```text
/// preheader → header(PHI: i, carrier) → body(if_condition)
/// ↓ ↓
/// after then | else
/// ↓ ↓
/// merge(PHI: carrier)
/// ↓
/// step(i_next)
/// ↓
/// back-edge to header
/// ```
#[derive(Debug, Clone)]
pub(in crate::mir::builder) struct Pattern3IfPhiPlan {
/// Loop variable name (e.g., "i")
pub loop_var: String,
/// Carrier variable name (e.g., "sum")
pub carrier_var: String,
/// Loop condition AST (e.g., `i < 3`)
pub condition: ASTNode,
/// If condition AST (e.g., `i > 0`)
pub if_condition: ASTNode,
/// Then branch update AST (e.g., `sum + 1`)
pub then_update: ASTNode,
/// Else branch update AST (e.g., `sum + 0`)
pub else_update: ASTNode,
/// Loop increment expression AST (e.g., `i + 1`)
pub loop_increment: ASTNode,
}
// ============================================================================
// CorePlan (固定語彙 - 構造ノードのみ)
// ============================================================================

View File

@ -14,7 +14,7 @@
use super::{
CoreEffectPlan, CoreLoopPlan, CorePhiInfo, CorePlan, DomainPlan,
ScanWithInitPlan, SplitScanPlan, Pattern1SimpleWhilePlan, Pattern9AccumConstLoopPlan,
Pattern8BoolPredicateScanPlan,
Pattern8BoolPredicateScanPlan, Pattern3IfPhiPlan,
};
use crate::mir::builder::control_flow::joinir::patterns::router::LoopPatternContext;
use crate::mir::builder::MirBuilder;
@ -44,6 +44,7 @@ impl PlanNormalizer {
DomainPlan::Pattern1SimpleWhile(parts) => Self::normalize_pattern1_simple_while(builder, parts, ctx),
DomainPlan::Pattern9AccumConstLoop(parts) => Self::normalize_pattern9_accum_const_loop(builder, parts, ctx),
DomainPlan::Pattern8BoolPredicateScan(parts) => Self::normalize_pattern8_bool_predicate_scan(builder, parts, ctx),
DomainPlan::Pattern3IfPhi(parts) => Self::normalize_pattern3_if_phi(builder, parts, ctx),
}
}
@ -2044,4 +2045,35 @@ impl PlanNormalizer {
Ok(CorePlan::Loop(loop_plan))
}
/// Phase 286 P2.6: Pattern3 (Loop with If-Phi) → CorePlan 変換
///
/// # Status: PoC Stub
///
/// This is a minimal stub implementation for Phase 286 P2.6 PoC.
/// The extractor works and will be called, but this normalizer
/// returns an error to fallback to the legacy Pattern3 implementation.
///
/// # CFG Structure (Design - not yet implemented)
/// ```text
/// preheader → header(PHI: i, carrier) → body(if_condition)
/// ↓ ↓
/// after then | else
/// ↓ ↓
/// merge(PHI: carrier)
/// ↓
/// step(i_next)
/// ↓
/// back-edge to header
/// ```
fn normalize_pattern3_if_phi(
_builder: &mut MirBuilder,
_parts: Pattern3IfPhiPlan,
_ctx: &LoopPatternContext,
) -> Result<CorePlan, String> {
// Phase 286 P2.6 PoC: Stub implementation
// Extractor validates Pattern3 structure, but normalization is deferred
// Fallback to legacy Pattern3 implementation via Ok(None) in router
Err("Pattern3 Plan normalization not yet implemented (PoC stub - fallback to legacy)".to_string())
}
}