feat(mir): Phase 69-3 Fix MIR non-determinism with BTreeSet
Replace HashSet with BTreeSet for CFG predecessors/successors: - BasicBlock.predecessors: HashSet → BTreeSet - BasicBlock.successors: HashSet → BTreeSet - LoopFormOps.get_block_predecessors(): returns BTreeSet - BasicBlock.dominates(): takes &[BTreeSet<BasicBlockId>] This ensures deterministic PHI generation and test stability. Test results: - loop_with_continue_and_break tests: now deterministic (3/3 same output) - loopform tests: 14/14 PASS (no regressions) - merge_exit_with_classification tests: 3/3 PASS Technical changes (6 files): - basic_block.rs: BTreeSet types + new() initialization - loopform_builder.rs: trait signature + 2 mock implementations - phi_ops.rs: return type - json_v0_bridge/loop_.rs: return type Same pattern as Phase 25.1 (MirFunction.blocks HashMap → BTreeMap). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -542,7 +542,11 @@ impl super::MirBuilder {
|
||||
values.insert(*v);
|
||||
}
|
||||
}
|
||||
MirInstruction::Phi { dst, inputs, type_hint: None } => {
|
||||
MirInstruction::Phi {
|
||||
dst,
|
||||
inputs,
|
||||
type_hint: None,
|
||||
} => {
|
||||
values.insert(*dst);
|
||||
for (_, val) in inputs {
|
||||
values.insert(*val);
|
||||
@ -651,7 +655,11 @@ impl super::MirBuilder {
|
||||
MirInstruction::Return { value } => MirInstruction::Return {
|
||||
value: value.map(remap_value),
|
||||
},
|
||||
MirInstruction::Phi { dst, inputs, type_hint: None } => MirInstruction::Phi {
|
||||
MirInstruction::Phi {
|
||||
dst,
|
||||
inputs,
|
||||
type_hint: None,
|
||||
} => MirInstruction::Phi {
|
||||
dst: remap_value(*dst),
|
||||
inputs: inputs
|
||||
.iter()
|
||||
|
||||
@ -22,7 +22,8 @@ impl<'a> PhiBuilderOps for ToplevelOps<'a> {
|
||||
inputs: Vec<(BasicBlockId, ValueId)>,
|
||||
) -> Result<(), String> {
|
||||
// merge ブロックの先頭に PHI を挿入
|
||||
if let (Some(func), Some(_cur_bb)) = (self.0.current_function.as_mut(), self.0.current_block)
|
||||
if let (Some(func), Some(_cur_bb)) =
|
||||
(self.0.current_function.as_mut(), self.0.current_block)
|
||||
{
|
||||
crate::mir::ssot::cf_common::insert_phi_at_head_spanned(
|
||||
func,
|
||||
@ -32,7 +33,11 @@ impl<'a> PhiBuilderOps for ToplevelOps<'a> {
|
||||
self.0.current_span,
|
||||
);
|
||||
} else {
|
||||
self.0.emit_instruction(MirInstruction::Phi { dst, inputs, type_hint: None })?;
|
||||
self.0.emit_instruction(MirInstruction::Phi {
|
||||
dst,
|
||||
inputs,
|
||||
type_hint: None,
|
||||
})?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -286,7 +291,10 @@ impl MirBuilder {
|
||||
}
|
||||
None => {
|
||||
if joinir_dryrun {
|
||||
eprintln!("[Phase 61-4] ⏭️ JoinIR pattern not matched for {}, using fallback", func_name);
|
||||
eprintln!(
|
||||
"[Phase 61-4] ⏭️ JoinIR pattern not matched for {}, using fallback",
|
||||
func_name
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user