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.
|
||||
/// 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(
|
||||
builder: &mut crate::mir::builder::MirBuilder,
|
||||
header_block: BasicBlockId,
|
||||
entry_block: BasicBlockId,
|
||||
loop_var_name: &str,
|
||||
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,
|
||||
debug: bool,
|
||||
) -> Result<LoopHeaderPhiInfo, String> {
|
||||
@ -96,15 +102,35 @@ impl LoopHeaderPhiBuilder {
|
||||
}
|
||||
|
||||
// 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();
|
||||
info.carrier_phis.insert(
|
||||
name.clone(),
|
||||
CarrierPhiEntry {
|
||||
phi_dst,
|
||||
entry_incoming: (entry_block, *init_value),
|
||||
entry_incoming: (entry_block, init_value),
|
||||
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
|
||||
@ -112,8 +138,8 @@ impl LoopHeaderPhiBuilder {
|
||||
|
||||
if debug {
|
||||
eprintln!(
|
||||
"[cf_loop/joinir] Carrier '{}' PHI: {:?} = phi [(from {:?}, {:?}), (latch TBD)]",
|
||||
name, phi_dst, entry_block, init_value
|
||||
"[cf_loop/joinir] Carrier '{}' PHI: {:?} = phi [(from {:?}, {:?}), (latch TBD)], role={:?}",
|
||||
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"
|
||||
)?;
|
||||
|
||||
// Extract other carriers from exit_bindings
|
||||
let other_carriers: Vec<(String, ValueId)> = boundary.exit_bindings
|
||||
.iter()
|
||||
.filter(|b| b.carrier_name != *loop_var_name)
|
||||
.map(|b| (b.carrier_name.clone(), b.host_slot))
|
||||
.collect();
|
||||
// Phase 228-4: Extract carriers with their initialization strategy
|
||||
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()
|
||||
.filter(|b| b.carrier_name != *loop_var_name)
|
||||
.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()
|
||||
};
|
||||
|
||||
if debug {
|
||||
eprintln!(
|
||||
@ -156,7 +167,7 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
|
||||
eprintln!(
|
||||
"[cf_loop/joinir] loop_var_init={:?}, carriers={:?}",
|
||||
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
|
||||
join_id: None,
|
||||
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 {
|
||||
None
|
||||
|
||||
@ -143,6 +143,7 @@ mod tests {
|
||||
host_id: ValueId(10),
|
||||
join_id: None,
|
||||
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),
|
||||
join_id: None,
|
||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||
},
|
||||
CarrierVar {
|
||||
name: "sum".to_string(),
|
||||
host_id: ValueId(10),
|
||||
join_id: None,
|
||||
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),
|
||||
join_id: None,
|
||||
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),
|
||||
join_id: None,
|
||||
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),
|
||||
join_id: None,
|
||||
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),
|
||||
join_id: None,
|
||||
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
|
||||
expr_result: None, // Phase 33-14: 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)
|
||||
|
||||
@ -108,6 +108,7 @@ mod tests {
|
||||
host_id: ValueId(10),
|
||||
join_id: None,
|
||||
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
|
||||
expr_result: None, // Phase 33-14: 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)
|
||||
|
||||
@ -92,6 +92,7 @@ mod tests {
|
||||
host_id: ValueId(10),
|
||||
join_id: None,
|
||||
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),
|
||||
join_id: None,
|
||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||
},
|
||||
CarrierVar {
|
||||
name: "sum".to_string(),
|
||||
host_id: ValueId(10),
|
||||
join_id: None,
|
||||
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),
|
||||
join_id: None,
|
||||
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),
|
||||
join_id: None,
|
||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||
},
|
||||
CarrierVar {
|
||||
name: "sum".to_string(),
|
||||
host_id: ValueId(10),
|
||||
join_id: None,
|
||||
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),
|
||||
join_id: None,
|
||||
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),
|
||||
join_id: None,
|
||||
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),
|
||||
join_id: None,
|
||||
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_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_carrier_info(carrier_info.clone()) // Phase 228-6: Pass carrier_info for ConditionOnly header PHI init
|
||||
.build();
|
||||
|
||||
// Phase 33-22: Use JoinIRConversionPipeline for unified conversion flow
|
||||
|
||||
@ -277,18 +277,21 @@ mod tests {
|
||||
host_id: ValueId(1),
|
||||
join_id: None,
|
||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||
},
|
||||
CarrierVar {
|
||||
name: "sum".to_string(),
|
||||
host_id: ValueId(2),
|
||||
join_id: None,
|
||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||
},
|
||||
CarrierVar {
|
||||
name: "M".to_string(),
|
||||
host_id: ValueId(3),
|
||||
join_id: None,
|
||||
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,
|
||||
|
||||
@ -378,6 +378,7 @@ impl MirBuilder {
|
||||
.with_inputs(join_inputs, host_inputs) // Dynamic carrier count
|
||||
.with_exit_bindings(exit_bindings)
|
||||
.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();
|
||||
|
||||
// Phase 33-22: Use JoinIRConversionPipeline for unified conversion flow
|
||||
|
||||
@ -397,12 +397,14 @@ mod tests {
|
||||
host_id: ValueId(10),
|
||||
join_id: None,
|
||||
role: crate::mir::join_ir::lowering::carrier_info::CarrierRole::LoopState,
|
||||
init: crate::mir::join_ir::lowering::carrier_info::CarrierInit::FromHost, // Phase 228
|
||||
},
|
||||
CarrierVar {
|
||||
name: "count".to_string(),
|
||||
host_id: ValueId(11),
|
||||
join_id: None,
|
||||
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,
|
||||
|
||||
@ -54,6 +54,29 @@ pub enum CarrierRole {
|
||||
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
|
||||
///
|
||||
/// 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)
|
||||
/// - `ConditionOnly`: Only used for loop condition (no exit PHI)
|
||||
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 {
|
||||
@ -110,6 +138,7 @@ impl CarrierVar {
|
||||
host_id,
|
||||
join_id: None,
|
||||
role: CarrierRole::LoopState,
|
||||
init: CarrierInit::FromHost, // Phase 228: Default to FromHost
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,6 +149,23 @@ impl CarrierVar {
|
||||
host_id,
|
||||
join_id: None,
|
||||
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,
|
||||
join_id: None, // Phase 177-STRUCT-1: Set by header PHI generation
|
||||
role: CarrierRole::LoopState, // Phase 227: Default to LoopState
|
||||
init: CarrierInit::FromHost, // Phase 228: Default to FromHost
|
||||
})
|
||||
.collect();
|
||||
|
||||
@ -257,6 +304,7 @@ impl CarrierInfo {
|
||||
host_id,
|
||||
join_id: None, // Phase 177-STRUCT-1: Set by header PHI generation
|
||||
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),
|
||||
join_id: None, // Phase 177-STRUCT-1
|
||||
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),
|
||||
join_id: None, // Phase 177-STRUCT-1
|
||||
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)`).
|
||||
/// Used to track which PHI corresponds to the loop variable.
|
||||
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 {
|
||||
@ -272,6 +282,7 @@ impl JoinInlineBoundary {
|
||||
condition_bindings: vec![], // Phase 171-fix: Default to empty
|
||||
expr_result: None, // Phase 33-14: Default to carrier-only pattern
|
||||
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
|
||||
expr_result: None, // Phase 33-14
|
||||
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
|
||||
expr_result: None, // Phase 33-14
|
||||
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
|
||||
expr_result: None, // Phase 33-14
|
||||
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
|
||||
expr_result: None, // Phase 33-14
|
||||
loop_var_name: None, // Phase 33-16
|
||||
carrier_info: None, // Phase 228
|
||||
}
|
||||
}
|
||||
|
||||
@ -523,6 +538,7 @@ impl JoinInlineBoundary {
|
||||
condition_bindings,
|
||||
expr_result: None, // Phase 33-14
|
||||
loop_var_name: None, // Phase 33-16
|
||||
carrier_info: None, // Phase 228
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
use crate::mir::ValueId;
|
||||
use super::inline_boundary::{JoinInlineBoundary, LoopExitBinding};
|
||||
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)
|
||||
///
|
||||
@ -96,6 +96,7 @@ impl JoinInlineBoundaryBuilder {
|
||||
condition_bindings: vec![],
|
||||
expr_result: None,
|
||||
loop_var_name: None,
|
||||
carrier_info: None, // Phase 228: Initialize as None
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -261,6 +262,29 @@ impl JoinInlineBoundaryBuilder {
|
||||
.find(|b| b.name == name)
|
||||
.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 {
|
||||
|
||||
@ -299,6 +299,7 @@ mod tests {
|
||||
host_id: crate::mir::ValueId(0),
|
||||
join_id: None, // Phase 177-STRUCT-1
|
||||
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);
|
||||
@ -357,6 +358,7 @@ mod tests {
|
||||
host_id: crate::mir::ValueId(0),
|
||||
join_id: None,
|
||||
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);
|
||||
@ -416,6 +418,7 @@ mod tests {
|
||||
host_id: crate::mir::ValueId(0),
|
||||
join_id: None,
|
||||
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);
|
||||
@ -475,6 +478,7 @@ mod tests {
|
||||
host_id: crate::mir::ValueId(0),
|
||||
join_id: None,
|
||||
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);
|
||||
|
||||
@ -183,12 +183,13 @@ impl DigitPosPromoter {
|
||||
// For DigitPos pattern, we add a NEW carrier (not replace loop_var)
|
||||
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 {
|
||||
name: carrier_name.clone(),
|
||||
host_id: ValueId(0), // Placeholder (will be remapped)
|
||||
join_id: None, // Will be allocated later
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user