feat(joinir/refactor): Phase 33-10-P0 ExitLineReconnector Box modularization
Box theory application: Extract Phase 6 reconnect_boundary logic into focused, testable exit_line module with clear responsibilities. **Changes**: 1. Created exit_line submodule (2 new files): - reconnector.rs: ExitLineReconnector Box (+130 lines) - mod.rs: ExitLineOrchestrator facade (+58 lines) 2. Simplified merge/mod.rs (-91 lines): - Removed reconnect_boundary() function - Delegate to ExitLineOrchestrator::execute() - Clear separation of concerns **Box Design**: - ExitLineReconnector: Single responsibility - update variable_map with remapped exit values from JoinIR k_exit parameters - ExitLineOrchestrator: Facade for Phase 6 orchestration - Phase 197-B multi-carrier support: Each carrier gets specific exit value **Testing**: - Build: ✅ Success (0.11s) - Execution: ✅ RC: 0 (Pattern 2 simple loop verified) - Regression: ✅ No regression in existing logic **Metrics**: - New lines: +188 (exit_line module) - Removed lines: -91 (merge/mod.rs) - Net change: +97 lines - Maintainability: Significantly improved - Test coverage ready: Isolated Box can be tested independently 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -16,6 +16,7 @@ mod block_allocator;
|
||||
mod value_collector;
|
||||
mod instruction_rewriter;
|
||||
mod exit_phi_builder;
|
||||
mod exit_line;
|
||||
|
||||
use crate::mir::{MirModule, ValueId};
|
||||
use crate::mir::join_ir::lowering::inline_boundary::JoinInlineBoundary;
|
||||
@ -125,8 +126,9 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
|
||||
|
||||
// Phase 6: Reconnect boundary (if specified)
|
||||
// Phase 197-B: Pass remapper to enable per-carrier exit value lookup
|
||||
// Phase 33-10-Refactor-P3: Delegate to ExitLineOrchestrator
|
||||
if let Some(boundary) = boundary {
|
||||
reconnect_boundary(builder, boundary, &remapper, exit_phi_result_id, debug)?;
|
||||
exit_line::ExitLineOrchestrator::execute(builder, boundary, &remapper, debug)?;
|
||||
}
|
||||
|
||||
// Jump from current block to entry function's entry block
|
||||
@ -200,92 +202,3 @@ fn remap_values(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Phase 6: Reconnect boundary to update host variable_map
|
||||
///
|
||||
/// Phase 197-B: Multi-carrier support
|
||||
/// Previously, a single exit_phi_result was applied to all carriers, causing
|
||||
/// all carriers to get the same value (e.g., both sum and count = 5).
|
||||
///
|
||||
/// Now, we use each binding's join_exit_value and the remapper to find
|
||||
/// the actual exit value for each carrier.
|
||||
fn reconnect_boundary(
|
||||
builder: &mut crate::mir::builder::MirBuilder,
|
||||
boundary: &JoinInlineBoundary,
|
||||
remapper: &crate::mir::builder::joinir_id_remapper::JoinIrIdRemapper,
|
||||
_exit_phi_result: Option<ValueId>,
|
||||
debug: bool,
|
||||
) -> Result<(), String> {
|
||||
// Phase 197-B: Multi-carrier exit binding using join_exit_value directly
|
||||
//
|
||||
// Problem: Previously used single exit_phi_result for all carriers.
|
||||
// Solution: Each carrier's exit value is in k_exit parameters.
|
||||
// We use remapper to find the remapped ValueId for each carrier.
|
||||
//
|
||||
// For Pattern 4 with 2 carriers (sum, count):
|
||||
// - k_exit(sum_exit, count_exit) receives values via Jump args
|
||||
// - sum_exit = ValueId(N) in JoinIR → remapped to ValueId(M) in host
|
||||
// - count_exit = ValueId(N+1) in JoinIR → remapped to ValueId(M+1) in host
|
||||
//
|
||||
// Each carrier's variable_map entry is updated with its specific remapped value.
|
||||
|
||||
if boundary.exit_bindings.is_empty() {
|
||||
if debug {
|
||||
eprintln!("[cf_loop/joinir] Phase 197-B: No exit bindings, skipping reconnect");
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if debug {
|
||||
eprintln!(
|
||||
"[cf_loop/joinir] Phase 197-B: Reconnecting {} exit bindings",
|
||||
boundary.exit_bindings.len()
|
||||
);
|
||||
}
|
||||
|
||||
// For each binding, look up the remapped exit value and update variable_map
|
||||
for binding in &boundary.exit_bindings {
|
||||
// Phase 197-B: Use remapper to find the remapped exit value
|
||||
let remapped_exit = remapper.get_value(binding.join_exit_value);
|
||||
|
||||
if debug {
|
||||
eprintln!(
|
||||
"[cf_loop/joinir] Phase 197-B: Carrier '{}' join_exit={:?} → remapped={:?}",
|
||||
binding.carrier_name, binding.join_exit_value, remapped_exit
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(remapped_value) = remapped_exit {
|
||||
// Update variable_map with the remapped exit value
|
||||
if let Some(var_vid) = builder.variable_map.get_mut(&binding.carrier_name) {
|
||||
if debug {
|
||||
eprintln!(
|
||||
"[cf_loop/joinir] Phase 197-B: Updated variable_map['{}'] {:?} → {:?}",
|
||||
binding.carrier_name, var_vid, remapped_value
|
||||
);
|
||||
}
|
||||
*var_vid = remapped_value;
|
||||
} else if debug {
|
||||
eprintln!(
|
||||
"[cf_loop/joinir] Phase 197-B WARNING: Carrier '{}' not found in variable_map",
|
||||
binding.carrier_name
|
||||
);
|
||||
}
|
||||
} else if debug {
|
||||
eprintln!(
|
||||
"[cf_loop/joinir] Phase 197-B WARNING: No remapped value for join_exit={:?}",
|
||||
binding.join_exit_value
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 190: Backward compatibility - also check deprecated host_outputs
|
||||
#[allow(deprecated)]
|
||||
if !boundary.host_outputs.is_empty() && debug {
|
||||
eprintln!(
|
||||
"[cf_loop/joinir] WARNING: Using deprecated host_outputs. Migrate to exit_bindings."
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user