phase29ag(p1): remap via boundary.join_inputs

This commit is contained in:
2025-12-29 06:28:43 +09:00
parent 6433dfcbfe
commit 62efdb631f
5 changed files with 54 additions and 48 deletions

View File

@ -285,8 +285,8 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
// Phase 33-21: Override remapper for loop_step's parameters
//
// JoinIR generates separate parameter ValueIds for each function:
// - main(): ValueId(0), ValueId(1), ... for (i_init, carrier1_init, ...)
// - loop_step(): ValueId(3), ValueId(4), ... for (i_param, carrier1_param, ...)
// - main(): boundary.join_inputs slots for (i_init, carrier1_init, ...)
// - loop_step(): loop_step params for (i_param, carrier1_param, ...)
//
// The loop body uses loop_step's parameters, so we need to remap THOSE
// to the header PHI dsts, not main()'s parameters.
@ -295,8 +295,8 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
// Phase 33-21: Override remapper for ALL functions' parameters
//
// JoinIR generates separate parameter ValueIds for each function:
// - main (join_func_0): ValueId(0), ValueId(1), ... for (i_init, carrier1_init, ...)
// - loop_step (join_func_1): ValueId(3), ValueId(4), ... for (i_param, carrier1_param, ...)
// - main (join_func_0): boundary.join_inputs slots for (i_init, carrier1_init, ...)
// - loop_step (join_func_1): loop_step params for (i_param, carrier1_param, ...)
//
// ALL of these need to be mapped to header PHI dsts so that:
// 1. condition evaluation uses PHI result
@ -370,6 +370,8 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
verbose,
);
}
let layout = boundary_carrier_layout::BoundaryCarrierLayout::from_boundary(boundary);
let layout_names = layout.ordered_names();
if let Some(main_params) = function_params.get(main_func_name) {
trace.stderr_if(
&format!(
@ -391,14 +393,11 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
verbose,
);
// Map main's parameters to header PHI dsts.
//
// IMPORTANT: Do not iterate carrier_phis (BTreeMap) here.
// JoinIR params are laid out in carrier_order, not alphabetical order.
for (idx, &main_param) in main_params.iter().enumerate() {
let (Some(carrier_name), Some(entry)) = (
loop_header_phi_info.get_carrier_at_index(idx),
loop_header_phi_info.get_entry_at_index(idx),
) else {
let Some(carrier_name) = layout_names.get(idx) else {
continue;
};
let Some(entry) = loop_header_phi_info.carrier_phis.get(*carrier_name) else {
continue;
};
@ -460,8 +459,6 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
),
verbose,
);
let layout = boundary_carrier_layout::BoundaryCarrierLayout::from_boundary(boundary);
let layout_names = layout.ordered_names();
if function_params.get(loop_step_func_name).is_none() {
trace.stderr_if(
&format!(
@ -543,27 +540,38 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
if function_params.get(main_func_name).is_none()
&& function_params.get(loop_step_func_name).is_none()
{
// Fallback: Use old behavior (ValueId(0), ValueId(1), ...)
// This handles patterns that don't have loop_step function
// Fallback: Use boundary.join_inputs for remap (no ValueId(idx) assumption).
if let Some(phi_dst) = loop_header_phi_info.get_carrier_phi(loop_var_name) {
// Phase 177-3: Don't override condition_bindings
if !condition_binding_ids.contains(&ValueId(0)) {
remapper.set_value(ValueId(0), phi_dst);
trace.stderr_if(
&format!(
"[cf_loop/joinir] Phase 33-16 fallback: Override remap ValueId(0) → {:?} (PHI dst)",
phi_dst
),
debug,
);
} else {
trace.stderr_if(
"[cf_loop/joinir] Phase 177-3 fallback: Skipping override for condition_binding ValueId(0)",
verbose,
);
let join_ids = boundary.join_inputs.as_slice();
let loop_var_idx = layout_names
.iter()
.position(|name| *name == loop_var_name);
if let Some(idx) = loop_var_idx {
if let Some(&join_value_id) = join_ids.get(idx) {
// Phase 177-3: Don't override condition_bindings
if !condition_binding_ids.contains(&join_value_id) {
remapper.set_value(join_value_id, phi_dst);
trace.stderr_if(
&format!(
"[cf_loop/joinir] Phase 33-16 fallback: Override remap {:?}{:?} (PHI dst)",
join_value_id, phi_dst
),
debug,
);
} else {
trace.stderr_if(
&format!(
"[cf_loop/joinir] Phase 177-3 fallback: Skipping override for condition_binding {:?}",
join_value_id
),
verbose,
);
}
}
}
}
// Phase 29ag P0: Use BoundaryCarrierLayout for deterministic iteration
// Phase 29ag P1: Use boundary.join_inputs for remap instead of ValueId(idx).
let join_ids = boundary.join_inputs.as_slice();
for (idx, carrier_name) in layout_names.iter().enumerate() {
if *carrier_name == loop_var_name {
continue;
@ -572,7 +580,9 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
Some(e) => e,
None => continue,
};
let join_value_id = ValueId(idx as u32);
let Some(&join_value_id) = join_ids.get(idx) else {
continue;
};
// Phase 177-3: Don't override condition_bindings
if !condition_binding_ids.contains(&join_value_id) {
remapper.set_value(join_value_id, entry.phi_dst);

View File

@ -73,20 +73,6 @@ impl LoopHeaderPhiInfo {
}
}
/// Phase 177-STRUCT-2: Get carrier name at index (in insertion order)
///
/// Used for matching loop_step params by index.
pub fn get_carrier_at_index(&self, idx: usize) -> Option<&str> {
self.carrier_order.get(idx).map(|s| s.as_str())
}
/// Phase 177-STRUCT-2: Get PHI entry at index (in insertion order)
pub fn get_entry_at_index(&self, idx: usize) -> Option<&CarrierPhiEntry> {
self.carrier_order
.get(idx)
.and_then(|name| self.carrier_phis.get(name))
}
/// Get the PHI dst for a carrier variable
pub fn get_carrier_phi(&self, name: &str) -> Option<ValueId> {
self.carrier_phis.get(name).map(|e| e.phi_dst)