fix(joinir): stabilize Phase 256 merge (jump_args, DCE, func names)

This commit is contained in:
2025-12-20 11:01:48 +09:00
parent 2c4268b691
commit 1028bd419c
11 changed files with 499 additions and 50 deletions

View File

@ -188,20 +188,15 @@ impl ExitArgsCollectorBox {
Ok(0) // Best effort: try direct mapping
}
} else {
// Too long - unexpected extra args
let msg = format!(
"[joinir/exit-line] jump_args length mismatch: expected {} or {} (exit_bindings carriers ±1) but got {} in block {:?}",
exit_phi_bindings_len,
exit_phi_bindings_len + 1,
jump_args_len,
block_id
// Too long - extra args beyond carriers (e.g., invariants in Pattern 7)
// Phase 256 P1.8: Allow excess args as long as we have enough for carriers
// Direct mapping: jump_args[0..N] = exit_phi_bindings[0..N], rest ignored
#[cfg(debug_assertions)]
eprintln!(
"[joinir/exit-line] jump_args has {} extra args (block {:?}), ignoring invariants",
jump_args_len - exit_phi_bindings_len, block_id
);
if strict_exit {
Err(msg)
} else {
eprintln!("[DEBUG-177] {}", msg);
Ok(0) // Best effort: try direct mapping
}
Ok(0) // Direct mapping: first N args are carriers
}
}

View File

@ -1162,15 +1162,44 @@ pub(super) fn merge_and_rewrite(
// Choosing `.iter().next()` can therefore pick the wrong function and skip
// host→JoinIR Copy injection. Instead, pick the function whose params match
// the boundary.join_inputs (the entry env params).
let (entry_func_name, entry_func) = mir_module
.functions
.iter()
.find(|(_, func)| func.params == boundary.join_inputs)
.or_else(|| mir_module.functions.iter().next())
.ok_or("JoinIR module has no functions")?;
//
// Phase 256 P1.10.1: Prefer "main" if its params match the boundary join_inputs.
let (entry_func_name, entry_func) = {
use crate::mir::join_ir::lowering::canonical_names as cn;
if let Some(main) = mir_module.functions.get(cn::MAIN) {
if main.params == boundary.join_inputs {
(cn::MAIN, main)
} else {
mir_module
.functions
.iter()
.find(|(_, func)| func.params == boundary.join_inputs)
.or_else(|| mir_module.functions.iter().next())
.map(|(name, func)| (name.as_str(), func))
.ok_or("JoinIR module has no functions")?
}
} else {
mir_module
.functions
.iter()
.find(|(_, func)| func.params == boundary.join_inputs)
.or_else(|| mir_module.functions.iter().next())
.map(|(name, func)| (name.as_str(), func))
.ok_or("JoinIR module has no functions")?
}
};
let entry_block_remapped = remapper
.get_block(entry_func_name, entry_func.entry_block)
.ok_or_else(|| format!("Entry block not found for {}", entry_func_name))?;
log!(
true,
"[cf_loop/joinir] Phase 256 P1.10.1: Boundary entry selection: func='{}' entry_block={:?} remapped={:?} join_inputs={:?} entry_params={:?}",
entry_func_name,
entry_func.entry_block,
entry_block_remapped,
boundary.join_inputs,
entry_func.params
);
// Create BTreeMap from remapper for BoundaryInjector (temporary adapter)
// Phase 222.5-E: HashMap → BTreeMap for determinism