feat(joinir): Phase 228 - CarrierInit for ConditionOnly header PHI initialization
- Add CarrierInit enum (FromHost/BoolConst) for explicit initialization policy - LoopHeaderPhiBuilder generates Const instruction for BoolConst carriers - merge/mod.rs uses carrier_info to include ALL carriers in header PHI - Pattern 2/4 pass carrier_info to boundary builder - ConditionOnly carriers (is_digit_pos) now included in header PHI Remaining: latch incoming for ConditionOnly carriers (Phase 228-8) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -51,13 +51,19 @@ impl LoopHeaderPhiBuilder {
|
|||||||
///
|
///
|
||||||
/// LoopHeaderPhiInfo with allocated PHI dsts.
|
/// LoopHeaderPhiInfo with allocated PHI dsts.
|
||||||
/// Note: latch_incoming is not yet set - that happens in instruction_rewriter.
|
/// Note: latch_incoming is not yet set - that happens in instruction_rewriter.
|
||||||
|
///
|
||||||
|
/// # Phase 228 Update
|
||||||
|
///
|
||||||
|
/// Added CarrierInit and CarrierRole to carrier tuples:
|
||||||
|
/// * `CarrierInit::FromHost` - Use host_id directly as PHI init value
|
||||||
|
/// * `CarrierInit::BoolConst(val)` - Generate explicit bool constant for ConditionOnly carriers
|
||||||
pub fn build(
|
pub fn build(
|
||||||
builder: &mut crate::mir::builder::MirBuilder,
|
builder: &mut crate::mir::builder::MirBuilder,
|
||||||
header_block: BasicBlockId,
|
header_block: BasicBlockId,
|
||||||
entry_block: BasicBlockId,
|
entry_block: BasicBlockId,
|
||||||
loop_var_name: &str,
|
loop_var_name: &str,
|
||||||
loop_var_init: ValueId,
|
loop_var_init: ValueId,
|
||||||
carriers: &[(String, ValueId)], // (name, init_value) pairs
|
carriers: &[(String, ValueId, crate::mir::join_ir::lowering::carrier_info::CarrierInit, crate::mir::join_ir::lowering::carrier_info::CarrierRole)], // Phase 228: Added CarrierInit and CarrierRole
|
||||||
expr_result_is_loop_var: bool,
|
expr_result_is_loop_var: bool,
|
||||||
debug: bool,
|
debug: bool,
|
||||||
) -> Result<LoopHeaderPhiInfo, String> {
|
) -> Result<LoopHeaderPhiInfo, String> {
|
||||||
@ -96,15 +102,35 @@ impl LoopHeaderPhiBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Allocate PHIs for other carriers
|
// Allocate PHIs for other carriers
|
||||||
for (name, init_value) in carriers {
|
for (name, host_id, init, role) in carriers {
|
||||||
|
// Phase 228-5: Generate explicit const for BoolConst, use host_id for FromHost
|
||||||
|
let init_value = match init {
|
||||||
|
crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost => *host_id,
|
||||||
|
crate::mir::join_ir::lowering::carrier_info::CarrierInit::BoolConst(val) => {
|
||||||
|
// Phase 228: Generate explicit bool constant for ConditionOnly carriers
|
||||||
|
let const_id = builder.next_value_id();
|
||||||
|
builder.emit_instruction(MirInstruction::Const {
|
||||||
|
dst: const_id,
|
||||||
|
value: crate::mir::types::ConstValue::Bool(*val),
|
||||||
|
});
|
||||||
|
if debug {
|
||||||
|
eprintln!(
|
||||||
|
"[cf_loop/joinir] Phase 228: Generated const {:?} = Bool({}) for ConditionOnly carrier '{}'",
|
||||||
|
const_id, val, name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const_id
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let phi_dst = builder.next_value_id();
|
let phi_dst = builder.next_value_id();
|
||||||
info.carrier_phis.insert(
|
info.carrier_phis.insert(
|
||||||
name.clone(),
|
name.clone(),
|
||||||
CarrierPhiEntry {
|
CarrierPhiEntry {
|
||||||
phi_dst,
|
phi_dst,
|
||||||
entry_incoming: (entry_block, *init_value),
|
entry_incoming: (entry_block, init_value),
|
||||||
latch_incoming: None,
|
latch_incoming: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState, // Phase 227: Default to LoopState (will be updated later if needed)
|
role: *role, // Phase 228: Use role from carrier_info
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
// Phase 177-STRUCT-2: Record insertion order
|
// Phase 177-STRUCT-2: Record insertion order
|
||||||
@ -112,8 +138,8 @@ impl LoopHeaderPhiBuilder {
|
|||||||
|
|
||||||
if debug {
|
if debug {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"[cf_loop/joinir] Carrier '{}' PHI: {:?} = phi [(from {:?}, {:?}), (latch TBD)]",
|
"[cf_loop/joinir] Carrier '{}' PHI: {:?} = phi [(from {:?}, {:?}), (latch TBD)], role={:?}",
|
||||||
name, phi_dst, entry_block, init_value
|
name, phi_dst, entry_block, init_value, role
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -141,12 +141,23 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
|
|||||||
"Phase 201-A: No host_inputs in boundary for loop_var_init"
|
"Phase 201-A: No host_inputs in boundary for loop_var_init"
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Extract other carriers from exit_bindings
|
// Phase 228-4: Extract carriers with their initialization strategy
|
||||||
let other_carriers: Vec<(String, ValueId)> = boundary.exit_bindings
|
let other_carriers: Vec<(String, ValueId, crate::mir::join_ir::lowering::carrier_info::CarrierInit, crate::mir::join_ir::lowering::carrier_info::CarrierRole)> =
|
||||||
|
if let Some(ref carrier_info) = boundary.carrier_info {
|
||||||
|
// Use carrier_info if available (Phase 228)
|
||||||
|
carrier_info.carriers
|
||||||
|
.iter()
|
||||||
|
.filter(|c| c.name != *loop_var_name)
|
||||||
|
.map(|c| (c.name.clone(), c.host_id, c.init, c.role))
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
// Fallback: exit_bindings から取得(既存動作)
|
||||||
|
boundary.exit_bindings
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|b| b.carrier_name != *loop_var_name)
|
.filter(|b| b.carrier_name != *loop_var_name)
|
||||||
.map(|b| (b.carrier_name.clone(), b.host_slot))
|
.map(|b| (b.carrier_name.clone(), b.host_slot, crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState))
|
||||||
.collect();
|
.collect()
|
||||||
|
};
|
||||||
|
|
||||||
if debug {
|
if debug {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
@ -156,7 +167,7 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
|
|||||||
eprintln!(
|
eprintln!(
|
||||||
"[cf_loop/joinir] loop_var_init={:?}, carriers={:?}",
|
"[cf_loop/joinir] loop_var_init={:?}, carriers={:?}",
|
||||||
loop_var_init,
|
loop_var_init,
|
||||||
other_carriers.iter().map(|(n, _)| n.as_str()).collect::<Vec<_>>()
|
other_carriers.iter().map(|(n, _, _, _)| n.as_str()).collect::<Vec<_>>()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -163,6 +163,7 @@ impl CommonPatternInitializer {
|
|||||||
host_id: ValueId(0), // Dummy
|
host_id: ValueId(0), // Dummy
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState, // Phase 227: Default
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState, // Phase 227: Default
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228: Default
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|||||||
@ -143,6 +143,7 @@ mod tests {
|
|||||||
host_id: ValueId(10),
|
host_id: ValueId(10),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
}],
|
}],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -183,12 +184,14 @@ mod tests {
|
|||||||
host_id: ValueId(11),
|
host_id: ValueId(11),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
},
|
},
|
||||||
CarrierVar {
|
CarrierVar {
|
||||||
name: "sum".to_string(),
|
name: "sum".to_string(),
|
||||||
host_id: ValueId(10),
|
host_id: ValueId(10),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -232,6 +235,7 @@ mod tests {
|
|||||||
host_id: ValueId(10),
|
host_id: ValueId(10),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
}],
|
}],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -261,6 +265,7 @@ mod tests {
|
|||||||
host_id: ValueId(10),
|
host_id: ValueId(10),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
}],
|
}],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -290,6 +295,7 @@ mod tests {
|
|||||||
host_id: ValueId(10),
|
host_id: ValueId(10),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
}],
|
}],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -322,6 +328,7 @@ mod tests {
|
|||||||
host_id: ValueId(10),
|
host_id: ValueId(10),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
}],
|
}],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -352,6 +359,7 @@ mod tests {
|
|||||||
condition_bindings: vec![], // Phase 171-fix: Add missing field
|
condition_bindings: vec![], // Phase 171-fix: Add missing field
|
||||||
expr_result: None, // Phase 33-14: Add missing field
|
expr_result: None, // Phase 33-14: Add missing field
|
||||||
loop_var_name: None, // Phase 33-16: Add missing field
|
loop_var_name: None, // Phase 33-16: Add missing field
|
||||||
|
carrier_info: None, // Phase 228: Add missing field
|
||||||
};
|
};
|
||||||
|
|
||||||
builder.apply_to_boundary(&mut boundary)
|
builder.apply_to_boundary(&mut boundary)
|
||||||
|
|||||||
@ -108,6 +108,7 @@ mod tests {
|
|||||||
host_id: ValueId(10),
|
host_id: ValueId(10),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
}],
|
}],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -134,6 +135,7 @@ mod tests {
|
|||||||
condition_bindings: vec![], // Phase 171-fix: Add missing field
|
condition_bindings: vec![], // Phase 171-fix: Add missing field
|
||||||
expr_result: None, // Phase 33-14: Add missing field
|
expr_result: None, // Phase 33-14: Add missing field
|
||||||
loop_var_name: None, // Phase 33-16: Add missing field
|
loop_var_name: None, // Phase 33-16: Add missing field
|
||||||
|
carrier_info: None, // Phase 228: Add missing field
|
||||||
};
|
};
|
||||||
|
|
||||||
apply_exit_bindings_to_boundary(&carrier_info, &exit_meta, &variable_map, &mut boundary)
|
apply_exit_bindings_to_boundary(&carrier_info, &exit_meta, &variable_map, &mut boundary)
|
||||||
|
|||||||
@ -92,6 +92,7 @@ mod tests {
|
|||||||
host_id: ValueId(10),
|
host_id: ValueId(10),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
}],
|
}],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -130,12 +131,14 @@ mod tests {
|
|||||||
host_id: ValueId(11),
|
host_id: ValueId(11),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
},
|
},
|
||||||
CarrierVar {
|
CarrierVar {
|
||||||
name: "sum".to_string(),
|
name: "sum".to_string(),
|
||||||
host_id: ValueId(10),
|
host_id: ValueId(10),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@ -70,6 +70,7 @@ mod tests {
|
|||||||
host_id: ValueId(10),
|
host_id: ValueId(10),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
}],
|
}],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -90,12 +91,14 @@ mod tests {
|
|||||||
host_id: ValueId(11),
|
host_id: ValueId(11),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
},
|
},
|
||||||
CarrierVar {
|
CarrierVar {
|
||||||
name: "sum".to_string(),
|
name: "sum".to_string(),
|
||||||
host_id: ValueId(10),
|
host_id: ValueId(10),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -119,6 +122,7 @@ mod tests {
|
|||||||
host_id: ValueId(10),
|
host_id: ValueId(10),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
}],
|
}],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -140,6 +144,7 @@ mod tests {
|
|||||||
host_id: ValueId(10),
|
host_id: ValueId(10),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
}],
|
}],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -161,6 +166,7 @@ mod tests {
|
|||||||
host_id: ValueId(10),
|
host_id: ValueId(10),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
}],
|
}],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -578,6 +578,7 @@ impl MirBuilder {
|
|||||||
.with_exit_bindings(exit_bindings.clone())
|
.with_exit_bindings(exit_bindings.clone())
|
||||||
.with_expr_result(fragment_meta.expr_result) // Phase 33-14: Pass expr_result to merger
|
.with_expr_result(fragment_meta.expr_result) // Phase 33-14: Pass expr_result to merger
|
||||||
.with_loop_var_name(Some(loop_var_name.clone())) // Phase 33-16: For LoopHeaderPhiBuilder
|
.with_loop_var_name(Some(loop_var_name.clone())) // Phase 33-16: For LoopHeaderPhiBuilder
|
||||||
|
.with_carrier_info(carrier_info.clone()) // Phase 228-6: Pass carrier_info for ConditionOnly header PHI init
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Phase 33-22: Use JoinIRConversionPipeline for unified conversion flow
|
// Phase 33-22: Use JoinIRConversionPipeline for unified conversion flow
|
||||||
|
|||||||
@ -277,18 +277,21 @@ mod tests {
|
|||||||
host_id: ValueId(1),
|
host_id: ValueId(1),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
},
|
},
|
||||||
CarrierVar {
|
CarrierVar {
|
||||||
name: "sum".to_string(),
|
name: "sum".to_string(),
|
||||||
host_id: ValueId(2),
|
host_id: ValueId(2),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
},
|
},
|
||||||
CarrierVar {
|
CarrierVar {
|
||||||
name: "M".to_string(),
|
name: "M".to_string(),
|
||||||
host_id: ValueId(3),
|
host_id: ValueId(3),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
trim_helper: None,
|
trim_helper: None,
|
||||||
|
|||||||
@ -378,6 +378,7 @@ impl MirBuilder {
|
|||||||
.with_inputs(join_inputs, host_inputs) // Dynamic carrier count
|
.with_inputs(join_inputs, host_inputs) // Dynamic carrier count
|
||||||
.with_exit_bindings(exit_bindings)
|
.with_exit_bindings(exit_bindings)
|
||||||
.with_loop_var_name(Some(loop_var_name.clone())) // Phase 33-19: Enable exit PHI collection
|
.with_loop_var_name(Some(loop_var_name.clone())) // Phase 33-19: Enable exit PHI collection
|
||||||
|
.with_carrier_info(carrier_info.clone()) // Phase 228-6: Pass carrier_info for ConditionOnly header PHI init
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Phase 33-22: Use JoinIRConversionPipeline for unified conversion flow
|
// Phase 33-22: Use JoinIRConversionPipeline for unified conversion flow
|
||||||
|
|||||||
@ -397,12 +397,14 @@ mod tests {
|
|||||||
host_id: ValueId(10),
|
host_id: ValueId(10),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
},
|
},
|
||||||
CarrierVar {
|
CarrierVar {
|
||||||
name: "count".to_string(),
|
name: "count".to_string(),
|
||||||
host_id: ValueId(11),
|
host_id: ValueId(11),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
trim_helper: None,
|
trim_helper: None,
|
||||||
|
|||||||
@ -54,6 +54,29 @@ pub enum CarrierRole {
|
|||||||
ConditionOnly,
|
ConditionOnly,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Phase 228: Initialization policy for carrier variables
|
||||||
|
///
|
||||||
|
/// When carriers participate in header PHI, they need an initial value.
|
||||||
|
/// Most carriers use their host_id value (FromHost), but promoted LoopBodyLocal
|
||||||
|
/// carriers need explicit bool initialization (BoolConst).
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// // Regular carrier (sum): Use host_id value
|
||||||
|
/// CarrierVar { name: "sum", host_id: ValueId(10), init: FromHost, .. }
|
||||||
|
///
|
||||||
|
/// // ConditionOnly carrier (is_digit_pos): Initialize with false
|
||||||
|
/// CarrierVar { name: "is_digit_pos", host_id: ValueId(15), init: BoolConst(false), .. }
|
||||||
|
/// ```
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum CarrierInit {
|
||||||
|
/// No explicit initialization (use host_id value)
|
||||||
|
FromHost,
|
||||||
|
/// Initialize with bool constant (for ConditionOnly carriers)
|
||||||
|
BoolConst(bool),
|
||||||
|
}
|
||||||
|
|
||||||
/// Phase 224-D: Alias for promoted LoopBodyLocal in condition expressions
|
/// Phase 224-D: Alias for promoted LoopBodyLocal in condition expressions
|
||||||
///
|
///
|
||||||
/// When a LoopBodyLocal variable is promoted to a carrier, the original variable
|
/// When a LoopBodyLocal variable is promoted to a carrier, the original variable
|
||||||
@ -97,6 +120,11 @@ pub struct CarrierVar {
|
|||||||
/// - `LoopState`: Value needed after loop (participates in exit PHI)
|
/// - `LoopState`: Value needed after loop (participates in exit PHI)
|
||||||
/// - `ConditionOnly`: Only used for loop condition (no exit PHI)
|
/// - `ConditionOnly`: Only used for loop condition (no exit PHI)
|
||||||
pub role: CarrierRole,
|
pub role: CarrierRole,
|
||||||
|
/// Phase 228: Initialization policy for header PHI
|
||||||
|
///
|
||||||
|
/// - `FromHost`: Use host_id value (regular carriers)
|
||||||
|
/// - `BoolConst(false)`: Initialize with false (promoted LoopBodyLocal carriers)
|
||||||
|
pub init: CarrierInit,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CarrierVar {
|
impl CarrierVar {
|
||||||
@ -110,6 +138,7 @@ impl CarrierVar {
|
|||||||
host_id,
|
host_id,
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: CarrierRole::LoopState,
|
role: CarrierRole::LoopState,
|
||||||
|
init: CarrierInit::FromHost, // Phase 228: Default to FromHost
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +149,23 @@ impl CarrierVar {
|
|||||||
host_id,
|
host_id,
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role,
|
role,
|
||||||
|
init: CarrierInit::FromHost, // Phase 228: Default to FromHost
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Phase 228: Create a CarrierVar with explicit role and init policy
|
||||||
|
pub fn with_role_and_init(
|
||||||
|
name: String,
|
||||||
|
host_id: ValueId,
|
||||||
|
role: CarrierRole,
|
||||||
|
init: CarrierInit,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
name,
|
||||||
|
host_id,
|
||||||
|
join_id: None,
|
||||||
|
role,
|
||||||
|
init,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,6 +243,7 @@ impl CarrierInfo {
|
|||||||
host_id: id,
|
host_id: id,
|
||||||
join_id: None, // Phase 177-STRUCT-1: Set by header PHI generation
|
join_id: None, // Phase 177-STRUCT-1: Set by header PHI generation
|
||||||
role: CarrierRole::LoopState, // Phase 227: Default to LoopState
|
role: CarrierRole::LoopState, // Phase 227: Default to LoopState
|
||||||
|
init: CarrierInit::FromHost, // Phase 228: Default to FromHost
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -257,6 +304,7 @@ impl CarrierInfo {
|
|||||||
host_id,
|
host_id,
|
||||||
join_id: None, // Phase 177-STRUCT-1: Set by header PHI generation
|
join_id: None, // Phase 177-STRUCT-1: Set by header PHI generation
|
||||||
role: CarrierRole::LoopState, // Phase 227: Default to LoopState
|
role: CarrierRole::LoopState, // Phase 227: Default to LoopState
|
||||||
|
init: CarrierInit::FromHost, // Phase 228: Default to FromHost
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,6 +624,7 @@ mod tests {
|
|||||||
host_id: ValueId(id),
|
host_id: ValueId(id),
|
||||||
join_id: None, // Phase 177-STRUCT-1
|
join_id: None, // Phase 177-STRUCT-1
|
||||||
role: CarrierRole::LoopState, // Phase 227: Default to LoopState
|
role: CarrierRole::LoopState, // Phase 227: Default to LoopState
|
||||||
|
init: CarrierInit::FromHost, // Phase 228: Default to FromHost
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -422,6 +422,7 @@ mod tests {
|
|||||||
host_id: ValueId(host_id),
|
host_id: ValueId(host_id),
|
||||||
join_id: None, // Phase 177-STRUCT-1
|
join_id: None, // Phase 177-STRUCT-1
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -246,6 +246,16 @@ pub struct JoinInlineBoundary {
|
|||||||
/// The name of the loop control variable (e.g., "i" in `loop(i < 3)`).
|
/// The name of the loop control variable (e.g., "i" in `loop(i < 3)`).
|
||||||
/// Used to track which PHI corresponds to the loop variable.
|
/// Used to track which PHI corresponds to the loop variable.
|
||||||
pub loop_var_name: Option<String>,
|
pub loop_var_name: Option<String>,
|
||||||
|
|
||||||
|
/// Phase 228: Carrier metadata (for header PHI generation)
|
||||||
|
///
|
||||||
|
/// Contains full carrier information including initialization policies.
|
||||||
|
/// This allows header PHI generation to handle ConditionOnly carriers
|
||||||
|
/// with explicit bool initialization.
|
||||||
|
///
|
||||||
|
/// - `Some(CarrierInfo)`: Full carrier metadata available
|
||||||
|
/// - `None`: Legacy path (derive carriers from exit_bindings)
|
||||||
|
pub carrier_info: Option<super::carrier_info::CarrierInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JoinInlineBoundary {
|
impl JoinInlineBoundary {
|
||||||
@ -272,6 +282,7 @@ impl JoinInlineBoundary {
|
|||||||
condition_bindings: vec![], // Phase 171-fix: Default to empty
|
condition_bindings: vec![], // Phase 171-fix: Default to empty
|
||||||
expr_result: None, // Phase 33-14: Default to carrier-only pattern
|
expr_result: None, // Phase 33-14: Default to carrier-only pattern
|
||||||
loop_var_name: None, // Phase 33-16
|
loop_var_name: None, // Phase 33-16
|
||||||
|
carrier_info: None, // Phase 228: Default to None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,6 +325,7 @@ impl JoinInlineBoundary {
|
|||||||
condition_bindings: vec![], // Phase 171-fix: Default to empty
|
condition_bindings: vec![], // Phase 171-fix: Default to empty
|
||||||
expr_result: None, // Phase 33-14
|
expr_result: None, // Phase 33-14
|
||||||
loop_var_name: None, // Phase 33-16
|
loop_var_name: None, // Phase 33-16
|
||||||
|
carrier_info: None, // Phase 228
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,6 +385,7 @@ impl JoinInlineBoundary {
|
|||||||
condition_bindings: vec![], // Phase 171-fix: Default to empty
|
condition_bindings: vec![], // Phase 171-fix: Default to empty
|
||||||
expr_result: None, // Phase 33-14
|
expr_result: None, // Phase 33-14
|
||||||
loop_var_name: None, // Phase 33-16
|
loop_var_name: None, // Phase 33-16
|
||||||
|
carrier_info: None, // Phase 228
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,6 +431,7 @@ impl JoinInlineBoundary {
|
|||||||
condition_bindings: vec![], // Phase 171-fix: Will be populated by new constructor
|
condition_bindings: vec![], // Phase 171-fix: Will be populated by new constructor
|
||||||
expr_result: None, // Phase 33-14
|
expr_result: None, // Phase 33-14
|
||||||
loop_var_name: None, // Phase 33-16
|
loop_var_name: None, // Phase 33-16
|
||||||
|
carrier_info: None, // Phase 228
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,6 +481,7 @@ impl JoinInlineBoundary {
|
|||||||
condition_bindings: vec![], // Phase 171-fix: Will be populated by new constructor
|
condition_bindings: vec![], // Phase 171-fix: Will be populated by new constructor
|
||||||
expr_result: None, // Phase 33-14
|
expr_result: None, // Phase 33-14
|
||||||
loop_var_name: None, // Phase 33-16
|
loop_var_name: None, // Phase 33-16
|
||||||
|
carrier_info: None, // Phase 228
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,6 +538,7 @@ impl JoinInlineBoundary {
|
|||||||
condition_bindings,
|
condition_bindings,
|
||||||
expr_result: None, // Phase 33-14
|
expr_result: None, // Phase 33-14
|
||||||
loop_var_name: None, // Phase 33-16
|
loop_var_name: None, // Phase 33-16
|
||||||
|
carrier_info: None, // Phase 228
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
use crate::mir::ValueId;
|
use crate::mir::ValueId;
|
||||||
use super::inline_boundary::{JoinInlineBoundary, LoopExitBinding};
|
use super::inline_boundary::{JoinInlineBoundary, LoopExitBinding};
|
||||||
use super::condition_to_joinir::ConditionBinding;
|
use super::condition_to_joinir::ConditionBinding;
|
||||||
use super::carrier_info::CarrierRole;
|
use super::carrier_info::CarrierRole; // Phase 228: Restored for test code
|
||||||
|
|
||||||
/// Role of a parameter in JoinIR lowering (Phase 200-A)
|
/// Role of a parameter in JoinIR lowering (Phase 200-A)
|
||||||
///
|
///
|
||||||
@ -96,6 +96,7 @@ impl JoinInlineBoundaryBuilder {
|
|||||||
condition_bindings: vec![],
|
condition_bindings: vec![],
|
||||||
expr_result: None,
|
expr_result: None,
|
||||||
loop_var_name: None,
|
loop_var_name: None,
|
||||||
|
carrier_info: None, // Phase 228: Initialize as None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -261,6 +262,29 @@ impl JoinInlineBoundaryBuilder {
|
|||||||
.find(|b| b.name == name)
|
.find(|b| b.name == name)
|
||||||
.map(|b| b.join_value)
|
.map(|b| b.join_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Phase 228: Set carrier metadata
|
||||||
|
///
|
||||||
|
/// Provides full carrier information including initialization policies.
|
||||||
|
/// This allows header PHI generation to handle ConditionOnly carriers
|
||||||
|
/// with explicit bool initialization.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `carrier_info` - Complete carrier metadata from pattern lowerer
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// let boundary = JoinInlineBoundaryBuilder::new()
|
||||||
|
/// .with_inputs(join_inputs, host_inputs)
|
||||||
|
/// .with_carrier_info(ctx.carrier_info.clone())
|
||||||
|
/// .build();
|
||||||
|
/// ```
|
||||||
|
pub fn with_carrier_info(mut self, carrier_info: super::carrier_info::CarrierInfo) -> Self {
|
||||||
|
self.boundary.carrier_info = Some(carrier_info);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for JoinInlineBoundaryBuilder {
|
impl Default for JoinInlineBoundaryBuilder {
|
||||||
|
|||||||
@ -299,6 +299,7 @@ mod tests {
|
|||||||
host_id: crate::mir::ValueId(0),
|
host_id: crate::mir::ValueId(0),
|
||||||
join_id: None, // Phase 177-STRUCT-1
|
join_id: None, // Phase 177-STRUCT-1
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let updates = LoopUpdateAnalyzer::analyze_carrier_updates(&body, &carriers);
|
let updates = LoopUpdateAnalyzer::analyze_carrier_updates(&body, &carriers);
|
||||||
@ -357,6 +358,7 @@ mod tests {
|
|||||||
host_id: crate::mir::ValueId(0),
|
host_id: crate::mir::ValueId(0),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let updates = LoopUpdateAnalyzer::analyze_carrier_updates(&body, &carriers);
|
let updates = LoopUpdateAnalyzer::analyze_carrier_updates(&body, &carriers);
|
||||||
@ -416,6 +418,7 @@ mod tests {
|
|||||||
host_id: crate::mir::ValueId(0),
|
host_id: crate::mir::ValueId(0),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let updates = LoopUpdateAnalyzer::analyze_carrier_updates(&body, &carriers);
|
let updates = LoopUpdateAnalyzer::analyze_carrier_updates(&body, &carriers);
|
||||||
@ -475,6 +478,7 @@ mod tests {
|
|||||||
host_id: crate::mir::ValueId(0),
|
host_id: crate::mir::ValueId(0),
|
||||||
join_id: None,
|
join_id: None,
|
||||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||||
|
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let updates = LoopUpdateAnalyzer::analyze_carrier_updates(&body, &carriers);
|
let updates = LoopUpdateAnalyzer::analyze_carrier_updates(&body, &carriers);
|
||||||
|
|||||||
@ -183,12 +183,13 @@ impl DigitPosPromoter {
|
|||||||
// For DigitPos pattern, we add a NEW carrier (not replace loop_var)
|
// For DigitPos pattern, we add a NEW carrier (not replace loop_var)
|
||||||
let carrier_name = format!("is_{}", var_in_cond);
|
let carrier_name = format!("is_{}", var_in_cond);
|
||||||
|
|
||||||
use crate::mir::join_ir::lowering::carrier_info::{CarrierVar, CarrierRole};
|
use crate::mir::join_ir::lowering::carrier_info::{CarrierVar, CarrierRole, CarrierInit};
|
||||||
let promoted_carrier = CarrierVar {
|
let promoted_carrier = CarrierVar {
|
||||||
name: carrier_name.clone(),
|
name: carrier_name.clone(),
|
||||||
host_id: ValueId(0), // Placeholder (will be remapped)
|
host_id: ValueId(0), // Placeholder (will be remapped)
|
||||||
join_id: None, // Will be allocated later
|
join_id: None, // Will be allocated later
|
||||||
role: CarrierRole::ConditionOnly, // Phase 227: DigitPos is condition-only
|
role: CarrierRole::ConditionOnly, // Phase 227: DigitPos is condition-only
|
||||||
|
init: CarrierInit::BoolConst(false), // Phase 228: Initialize with false
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create CarrierInfo with a dummy loop_var_name (will be ignored during merge)
|
// Create CarrierInfo with a dummy loop_var_name (will be ignored during merge)
|
||||||
|
|||||||
Reference in New Issue
Block a user