Files
hakorune/docs/development/current/main/phase213-progress-checkpoint-1.md
nyash-codex d4f90976da refactor(joinir): Phase 244 - ConditionLoweringBox trait unification
Unify condition lowering logic across Pattern 2/4 with trait-based API.

New infrastructure:
- condition_lowering_box.rs: ConditionLoweringBox trait + ConditionContext (293 lines)
- ExprLowerer implements ConditionLoweringBox trait (+51 lines)

Pattern migrations:
- Pattern 2 (loop_with_break_minimal.rs): Use trait API
- Pattern 4 (loop_with_continue_minimal.rs): Use trait API

Benefits:
- Unified condition lowering interface
- Extensible for future lowering strategies
- Clean API boundary between patterns and lowering logic
- Zero code duplication

Test results: 911/911 PASS (+2 new tests)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-11 02:35:31 +09:00

6.5 KiB
Raw Blame History

Phase 213: Progress Checkpoint 1

Date: 2025-12-09 Status: Foundation Complete, Ready for Lowerer Refactoring Commit: d7805e59


🎯 Completed Work

Task 213-2-2: PatternPipelineContext Extension

File: src/mir/builder/control_flow/joinir/patterns/pattern_pipeline.rs

Changes:

  1. Added new fields for Pattern 3:

    • loop_condition: Option<ASTNode> - Loop condition AST
    • loop_body: Option<Vec<ASTNode>> - Loop body AST
    • loop_update_summary: Option<LoopUpdateSummary> - Update expressions
  2. Updated build_pattern_context() for Pattern3:

    • Stores condition.clone() in loop_condition
    • Stores body.to_vec() in loop_body
    • Placeholder None for loop_update_summary (TODO: Task 213-2-4)
  3. Updated test cases with new fields

Task 213-2-3: CarrierUpdateInfo Extension

File: src/mir/join_ir/lowering/loop_update_summary.rs

Changes:

  1. Extended CarrierUpdateInfo struct:

    • then_expr: Option<ASTNode> - Then branch update expression
    • else_expr: Option<ASTNode> - Else branch update expression
  2. Updated analyze_loop_updates():

    • Default None for then_expr/else_expr
    • Comment: "Will be populated by Pattern 3 analyzer"

📊 Current State Analysis

MIR Analysis for phase212_if_sum_min.hako

Expected vs Actual:

Element Expected Actual (Hardcoded)
Loop limit i < 3 i <= 5
Loop cond icmp Lt %8, %18 icmp Le %8, %18
If cond i > 0 i % 2 == 1
If cond code icmp Gt %8, %zero %8 Mod %2; icmp Eq ... %1
Then update sum + 1 sum + i
Then code %9 Add %const_1 %9 Add %8

Root Cause: loop_with_if_phi_minimal.rs lines 217-385 are completely hardcoded for loop_if_phi.hako test pattern.


🔄 Next Steps (3 Approaches)

Approach A: Full AST-Based Generalization (Phase 213 Original Plan)

Tasks:

  1. Create Pattern3IfAnalyzer module
  2. Extract if statement from loop body
  3. Parse then/else branches for carrier updates
  4. Populate LoopUpdateSummary with AST expressions
  5. Replace hardcoded conditions in lowerer
  6. Replace hardcoded updates in lowerer
  7. Return ExitMeta instead of hardcoded ValueIds

Pros: Complete generalization, supports all if-sum patterns Cons: Large scope, ~500-800 lines of new code

Approach B: Minimal Incremental (80/20 Rule)

Tasks:

  1. Just replace the 3 hardcoded constants:
    • Loop limit: 5 → extract from AST condition
    • If condition: i % 2 == 1 → extract from AST if statement
    • Update value: i → extract from AST assignment
  2. Keep existing structure, minimal changes

Pros: Small scope, fast to implement, gets phase212_if_sum_min.hako working Cons: Still not fully generic, will need refactoring later

Approach C: Hybrid - BoolExprLowerer First

Tasks:

  1. Focus on condition lowering only (loop + if)
  2. Keep update expressions hardcoded for now
  3. Use existing condition_to_joinir infrastructure
  4. Defer update generalization to Phase 214

Pros: Leverages existing infrastructure, cleaner architecture Cons: phase212_if_sum_min.hako still won't work fully


💭 Analysis & Recommendation

Key Insight from Phase 212.5

Phase 212.5 discovered that:

  1. Pattern routing works correctly ( Pattern 3 detected)
  2. MIR PHI generation works ( %31 = phi created)
  3. Only the lowerer's hardcoded values are wrong

This means the JoinIR → MIR pipeline is solid. We just need to feed it the right JoinIR.

Recommendation: Approach B (Minimal Incremental)

Rationale:

  1. User's 80/20 philosophy: "完璧より進捗" (progress over perfection)
  2. Fail-Fast principle: Get phase212_if_sum_min.hako working first
  3. Box Theory: Make minimal, reversible change
  4. Evidence-based: Phase 212.5 proved the pipeline works

Implementation Plan:

  1. Extract loop condition from ctx.loop_condition AST
  2. Extract if condition from ctx.loop_body if statement
  3. Extract update expression from if-then assignment
  4. Replace 3 hardcoded sections in loop_with_if_phi_minimal.rs
  5. Test with phase212_if_sum_min.hako → RC=2
  6. Keep existing tests working (backward compatibility)

Estimated effort: 2-3 hours (vs 8-10 hours for Approach A)


🔍 Technical Details for Approach B

What Needs to Change

File: src/mir/join_ir/lowering/loop_with_if_phi_minimal.rs

Section 1: Loop Condition (lines 217-233)

// Before (hardcoded):
loop_step_func.body.push(JoinInst::Compute(MirLikeInst::Const {
    dst: const_5,
    value: ConstValue::Integer(5),  // ← Hardcoded!
}));
loop_step_func.body.push(JoinInst::Compute(MirLikeInst::Compare {
    dst: cmp_le,
    op: CompareOp::Le,  // ← Hardcoded!
    lhs: i_param,
    rhs: const_5,
}));

// After (AST-based):
// Extract from ctx.loop_condition: "i < 3"
// Lower to JoinIR using existing infrastructure

Section 2: If Condition (lines 254-288)

// Before (hardcoded):
// const 2, mod, const 1, eq → (i % 2 == 1)

// After (AST-based):
// Extract from loop_body if statement: "i > 0"
// Lower to JoinIR: const 0, cmp Gt

Section 3: Update Expression (lines 290-298)

// Before (hardcoded):
loop_step_func.body.push(JoinInst::Compute(MirLikeInst::BinOp {
    dst: sum_then,
    op: BinOpKind::Add,
    lhs: sum_param,
    rhs: i_param,  // ← Hardcoded! Should be const 1
}));

// After (AST-based):
// Extract from then-branch assignment: "sum = sum + 1"
// Lower to JoinIR: sum_param Add const_1

Helper Functions Needed

// Extract loop condition details
fn extract_loop_condition(condition: &ASTNode)
    -> Result<(CompareOp, i64), String>

// Extract if statement from loop body
fn extract_if_statement(body: &[ASTNode])
    -> Result<&ASTNode, String>

// Extract if condition details
fn extract_if_condition(if_node: &ASTNode)
    -> Result<(CompareOp, i64), String>

// Extract update value from assignment
fn extract_update_value(assignment: &ASTNode)
    -> Result<i64, String>

📋 Decision Point

Question for user: Which approach should we take?

A. Full AST-based generalization (Approach A) B. Minimal incremental replacement (Approach B) ← Recommended C. Hybrid BoolExprLowerer-first (Approach C) D. Different approach?

Current blockers: None - foundation is complete Current branch: main (d7805e59) Build status: Passing Status: Active
Scope: If-sum 進捗チェックポイントJoinIR v2