refactor(joinir): Unify Pattern 3 with PatternPipelineContext

Phase 179-B Task 4: Refactor Pattern 3 to use PatternPipelineContext
for unified preprocessing.

Changes:
- Use build_pattern_context() for loop variable extraction and scope construction
- Extract sum_var_id from ctx.carrier_info instead of direct initialization
- Reduce line count: 168 → 149 lines (11% reduction, lower than target due to already optimized code)
- Maintain exact same behavior and test compatibility

Benefits:
- Consistent preprocessing logic with Pattern 1
- Single source of truth for carrier analysis
- Cleaner separation of concerns (analysis vs lowering)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-08 19:44:45 +09:00
parent 48ef94e9ba
commit 94f992f574

View File

@ -50,44 +50,39 @@ pub fn lower(
} }
impl MirBuilder { impl MirBuilder {
/// Phase 188-Impl-3: Pattern 3 (Loop with If-Else PHI) minimal lowerer /// Phase 179-B: Pattern 3 (Loop with If-Else PHI) minimal lowerer
/// ///
/// Handles loops with if-else statements that assign to carrier variables. /// **Refactored**: Now uses PatternPipelineContext for unified preprocessing
/// ///
/// # Steps /// # Pipeline (Phase 179-B)
/// 1. Extract loop variables (carriers: i + sum) /// 1. Build preprocessing context → PatternPipelineContext
/// 2. Generate JoinIR using loop_with_if_phi_minimal /// 2. Call JoinIR lowerer → JoinModule
/// 3. Convert JoinModule → MirModule /// 3. Create boundary from context → JoinInlineBoundary
/// 4. Create JoinInlineBoundary for input mapping /// 4. Merge MIR blocks → JoinIRConversionPipeline
/// 5. Merge MIR blocks into current_function
/// 6. Return Void (loop doesn't produce values)
pub(in crate::mir::builder) fn cf_loop_pattern3_with_if_phi( pub(in crate::mir::builder) fn cf_loop_pattern3_with_if_phi(
&mut self, &mut self,
condition: &ASTNode, condition: &ASTNode,
_body: &[ASTNode], body: &[ASTNode],
_func_name: &str, _func_name: &str,
debug: bool, debug: bool,
) -> Result<Option<ValueId>, String> { ) -> Result<Option<ValueId>, String> {
use crate::mir::join_ir::lowering::loop_with_if_phi_minimal::lower_loop_with_if_phi_pattern; use crate::mir::join_ir::lowering::loop_with_if_phi_minimal::lower_loop_with_if_phi_pattern;
use crate::mir::BasicBlockId;
use std::collections::BTreeSet;
// Phase 195: Use unified trace // Phase 195: Use unified trace
trace::trace().debug("pattern3", "Calling Pattern 3 minimal lowerer"); trace::trace().debug("pattern3", "Calling Pattern 3 minimal lowerer");
// Phase 33-22: Use CommonPatternInitializer for loop variable extraction // Phase 179-B: Use PatternPipelineContext for unified preprocessing
use super::common_init::CommonPatternInitializer; use super::pattern_pipeline::{build_pattern_context, PatternVariant};
let (loop_var_name, loop_var_id, carrier_info) = let ctx = build_pattern_context(
CommonPatternInitializer::initialize_pattern( self,
self, condition,
condition, body,
&self.variable_map, PatternVariant::Pattern3,
None, // Pattern 3 includes all carriers (i + sum) )?;
)?;
// Phase 33-22: Extract sum_var_id from carrier_info // Phase 179-B: Extract sum_var_id from context
// Pattern 3 specifically needs the "sum" carrier // Pattern 3 specifically needs the "sum" carrier
let sum_var_id = carrier_info.carriers.iter() let sum_var_id = ctx.carrier_info.carriers.iter()
.find(|c| c.name == "sum") .find(|c| c.name == "sum")
.ok_or_else(|| { .ok_or_else(|| {
format!( format!(
@ -99,19 +94,8 @@ impl MirBuilder {
// Phase 195: Use unified trace // Phase 195: Use unified trace
trace::trace().varmap("pattern3_start", &self.variable_map); trace::trace().varmap("pattern3_start", &self.variable_map);
// Phase 171-172: Use LoopScopeShapeBuilder for unified initialization (Issue 4) // Call Pattern 3 lowerer with preprocessed scope
// Pattern 3 lowerer ignores the scope anyway, so this is just a placeholder let join_module = match lower_loop_with_if_phi_pattern(ctx.loop_scope) {
use super::loop_scope_shape_builder::LoopScopeShapeBuilder;
let scope = LoopScopeShapeBuilder::empty_body_locals(
BasicBlockId(0),
BasicBlockId(0),
BasicBlockId(0),
BasicBlockId(0),
BTreeSet::new(),
);
// Call Pattern 3 lowerer
let join_module = match lower_loop_with_if_phi_pattern(scope) {
Some(module) => module, Some(module) => module,
None => { None => {
// Phase 195: Use unified trace // Phase 195: Use unified trace
@ -120,17 +104,16 @@ impl MirBuilder {
} }
}; };
// Phase 33-22: Create boundary for JoinIR conversion // Phase 179-B: Create boundary from context
// Phase 201: Use JoinInlineBoundaryBuilder for clean construction // Phase 201: Use JoinInlineBoundaryBuilder for clean construction
// Canonical Builder pattern - see docs/development/current/main/joinir-boundary-builder-pattern.md // Canonical Builder pattern - see docs/development/current/main/joinir-boundary-builder-pattern.md
// Pattern 3 has TWO carriers: i and sum
self.trace_varmap("pattern3_before_merge"); self.trace_varmap("pattern3_before_merge");
use crate::mir::join_ir::lowering::JoinInlineBoundaryBuilder; use crate::mir::join_ir::lowering::JoinInlineBoundaryBuilder;
use crate::mir::join_ir::lowering::inline_boundary::LoopExitBinding; use crate::mir::join_ir::lowering::inline_boundary::LoopExitBinding;
let boundary = JoinInlineBoundaryBuilder::new() let boundary = JoinInlineBoundaryBuilder::new()
.with_inputs( .with_inputs(
vec![ValueId(0), ValueId(1)], // JoinIR's main() parameters (i, sum init) vec![ValueId(0), ValueId(1)], // JoinIR's main() parameters (i, sum init)
vec![loop_var_id, sum_var_id], // Host's loop variables vec![ctx.loop_var_id, sum_var_id], // Host's loop variables
) )
.with_exit_bindings(vec![ .with_exit_bindings(vec![
// Phase 33-16: Only include non-loop-variable carriers in exit_bindings // Phase 33-16: Only include non-loop-variable carriers in exit_bindings
@ -141,12 +124,12 @@ impl MirBuilder {
host_slot: sum_var_id, // variable_map["sum"] host_slot: sum_var_id, // variable_map["sum"]
} }
]) ])
.with_loop_var_name(Some(loop_var_name.clone())) // Phase 33-16: Enable header PHI generation for SSA correctness .with_loop_var_name(Some(ctx.loop_var_name.clone())) // Phase 33-16: Enable header PHI generation for SSA correctness
.build(); .build();
// Phase 33-22: Use JoinIRConversionPipeline for unified conversion flow // Phase 33-22: Use JoinIRConversionPipeline for unified conversion flow
use super::conversion_pipeline::JoinIRConversionPipeline; use super::conversion_pipeline::JoinIRConversionPipeline;
let _exit_phi_result = JoinIRConversionPipeline::execute( let _ = JoinIRConversionPipeline::execute(
self, self,
join_module, join_module,
Some(&boundary), Some(&boundary),
@ -155,9 +138,7 @@ impl MirBuilder {
)?; )?;
self.trace_varmap("pattern3_after_merge"); self.trace_varmap("pattern3_after_merge");
// Phase 189-Refine: variable_map の更新は merge_joinir_mir_blocks 内で // Phase 179-B: Return Void (loop doesn't produce values)
// JoinInlineBoundary.host_outputs を用いて行われる。
// この関数では Void を返すだけでよい(戻り値は後続の `return sum` が扱う)。
let void_val = crate::mir::builder::emission::constant::emit_void(self); let void_val = crate::mir::builder::emission::constant::emit_void(self);
// Phase 195: Use unified trace // Phase 195: Use unified trace