Phase 33 NORM canon test: enforce normalized dev route for P1/P2/JP mini
This commit is contained in:
@ -5,9 +5,9 @@
|
||||
//! - Entry block への Copy instruction 挿入
|
||||
//! - SSA 値空間の接続
|
||||
|
||||
use std::collections::BTreeMap; // Phase 222.5-E: HashMap → BTreeMap for determinism
|
||||
use crate::mir::{BasicBlockId, MirFunction, MirInstruction, ValueId};
|
||||
use crate::mir::join_ir::lowering::inline_boundary::JoinInlineBoundary;
|
||||
use crate::mir::{BasicBlockId, MirFunction, MirInstruction, ValueId};
|
||||
use std::collections::BTreeMap; // Phase 222.5-E: HashMap → BTreeMap for determinism
|
||||
|
||||
pub struct BoundaryInjector;
|
||||
|
||||
@ -56,10 +56,11 @@ impl BoundaryInjector {
|
||||
func: &mut MirFunction,
|
||||
entry_block_id: BasicBlockId,
|
||||
boundary: &JoinInlineBoundary,
|
||||
value_map: &BTreeMap<ValueId, ValueId>, // Phase 222.5-E: HashMap → BTreeMap for determinism
|
||||
value_map: &BTreeMap<ValueId, ValueId>, // Phase 222.5-E: HashMap → BTreeMap for determinism
|
||||
phi_dst_ids: &std::collections::HashSet<ValueId>,
|
||||
debug: bool,
|
||||
) -> Result<BTreeMap<ValueId, ValueId>, String> { // Phase 222.5-E: HashMap → BTreeMap for determinism
|
||||
) -> Result<BTreeMap<ValueId, ValueId>, String> {
|
||||
// Phase 222.5-E: HashMap → BTreeMap for determinism
|
||||
// Phase 33-20: When loop_var_name is set, ALL join_inputs are handled by header PHIs
|
||||
// This includes the loop variable AND all other carriers from exit_bindings.
|
||||
// We skip ALL join_inputs Copy instructions, only condition_bindings remain.
|
||||
@ -67,7 +68,7 @@ impl BoundaryInjector {
|
||||
|
||||
// Phase 171-fix: Check both join_inputs and condition_bindings
|
||||
let effective_join_inputs = if skip_all_join_inputs {
|
||||
0 // Phase 33-20: All join_inputs are handled by header PHIs
|
||||
0 // Phase 33-20: All join_inputs are handled by header PHIs
|
||||
} else {
|
||||
boundary.join_inputs.len()
|
||||
};
|
||||
@ -104,7 +105,10 @@ impl BoundaryInjector {
|
||||
let mut reallocations = BTreeMap::new();
|
||||
|
||||
for binding in &boundary.condition_bindings {
|
||||
let remapped_join = value_map.get(&binding.join_value).copied().unwrap_or(binding.join_value);
|
||||
let remapped_join = value_map
|
||||
.get(&binding.join_value)
|
||||
.copied()
|
||||
.unwrap_or(binding.join_value);
|
||||
|
||||
if phi_dst_ids.contains(&remapped_join) {
|
||||
// Collision detected! Allocate a fresh ValueId
|
||||
@ -132,29 +136,27 @@ impl BoundaryInjector {
|
||||
// Phase 171: Inject Copy instructions for join_inputs (loop parameters)
|
||||
// Phase 33-20: Skip ALL join_inputs when loop_var_name is set (header PHIs handle them)
|
||||
if !skip_all_join_inputs {
|
||||
for (join_input, host_input) in boundary
|
||||
.join_inputs
|
||||
.iter()
|
||||
.zip(boundary.host_inputs.iter())
|
||||
for (join_input, host_input) in
|
||||
boundary.join_inputs.iter().zip(boundary.host_inputs.iter())
|
||||
{
|
||||
// リマップ後の ValueId を取得
|
||||
let remapped_join = value_map.get(join_input).copied().unwrap_or(*join_input);
|
||||
let remapped_host = *host_input; // host_input is already in host space
|
||||
// リマップ後の ValueId を取得
|
||||
let remapped_join = value_map.get(join_input).copied().unwrap_or(*join_input);
|
||||
let remapped_host = *host_input; // host_input is already in host space
|
||||
|
||||
// Copy instruction: remapped_join = Copy remapped_host
|
||||
let copy_inst = MirInstruction::Copy {
|
||||
dst: remapped_join,
|
||||
src: remapped_host,
|
||||
};
|
||||
// Copy instruction: remapped_join = Copy remapped_host
|
||||
let copy_inst = MirInstruction::Copy {
|
||||
dst: remapped_join,
|
||||
src: remapped_host,
|
||||
};
|
||||
|
||||
copy_instructions.push(copy_inst);
|
||||
copy_instructions.push(copy_inst);
|
||||
|
||||
if debug {
|
||||
eprintln!(
|
||||
"[BoundaryInjector] Join input: Copy {:?} = Copy {:?}",
|
||||
remapped_join, remapped_host
|
||||
);
|
||||
}
|
||||
if debug {
|
||||
eprintln!(
|
||||
"[BoundaryInjector] Join input: Copy {:?} = Copy {:?}",
|
||||
remapped_join, remapped_host
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,10 +180,16 @@ impl BoundaryInjector {
|
||||
// Phase 177-3 Option B: Use pre-allocated reallocations for PHI collision cases
|
||||
for binding in &boundary.condition_bindings {
|
||||
// Look up the remapped JoinIR ValueId from value_map
|
||||
let remapped_join = value_map.get(&binding.join_value).copied().unwrap_or(binding.join_value);
|
||||
let remapped_join = value_map
|
||||
.get(&binding.join_value)
|
||||
.copied()
|
||||
.unwrap_or(binding.join_value);
|
||||
|
||||
// Phase 177-3 Option B: Check if this binding was reallocated (PHI collision case)
|
||||
let final_dst = reallocations.get(&binding.join_value).copied().unwrap_or(remapped_join);
|
||||
let final_dst = reallocations
|
||||
.get(&binding.join_value)
|
||||
.copied()
|
||||
.unwrap_or(remapped_join);
|
||||
|
||||
// Copy instruction: final_dst = Copy host_value
|
||||
let copy_inst = MirInstruction::Copy {
|
||||
@ -203,7 +211,9 @@ impl BoundaryInjector {
|
||||
// Entry block の先頭に Copy instructions を挿入
|
||||
// Reverse order to preserve original order when inserting at position 0
|
||||
// Phase 189 FIX: Also insert corresponding spans
|
||||
let default_span = entry_block.instruction_spans.first()
|
||||
let default_span = entry_block
|
||||
.instruction_spans
|
||||
.first()
|
||||
.copied()
|
||||
.unwrap_or_else(crate::ast::Span::unknown);
|
||||
for inst in copy_instructions.into_iter().rev() {
|
||||
|
||||
Reference in New Issue
Block a user