fix(cse): Include callee in Call instruction key generation
Previously, CSE's instruction_key() ignored the callee field, which could
cause different method calls on the same receiver to be incorrectly merged:
%r1 = call Method { receiver: %obj, method: "upper" } ()
%r2 = call Method { receiver: %obj, method: "lower" } ()
// Both had key "call_<obj>_" - WRONG!
Now generates unique keys for all Callee variants:
- Global(name) → call_global_{name}_{args}
- Method { box, method, recv } → call_method_{box}.{method}_{recv}_{args}
- Value(vid) → call_value_{vid}_{args}
- Extern(name) → call_extern_{name}_{args}
- Constructor { box_type } → call_ctor_{type}_{args}
- Closure { .. } → call_closure_{func}_{args}
- None (legacy) → call_legacy_{func}_{args}
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -78,13 +78,51 @@ fn instruction_key(i: &MirInstruction) -> String {
|
||||
MirInstruction::Compare { op, lhs, rhs, .. } => {
|
||||
format!("cmp_{:?}_{}_{}", op, lhs.as_u32(), rhs.as_u32())
|
||||
}
|
||||
MirInstruction::Call { func, args, .. } => {
|
||||
MirInstruction::Call { callee, func, args, .. } => {
|
||||
let args_str = args
|
||||
.iter()
|
||||
.map(|v| v.as_u32().to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
format!("call_{}_{}", func.as_u32(), args_str)
|
||||
|
||||
// Include callee information to distinguish different call targets
|
||||
if let Some(c) = callee {
|
||||
use crate::mir::Callee;
|
||||
match c {
|
||||
Callee::Global(name) => {
|
||||
format!("call_global_{}_{}", name, args_str)
|
||||
}
|
||||
Callee::Method {
|
||||
box_name,
|
||||
method,
|
||||
receiver,
|
||||
..
|
||||
} => {
|
||||
let recv_str = receiver
|
||||
.map(|r| r.as_u32().to_string())
|
||||
.unwrap_or_else(|| "static".to_string());
|
||||
format!("call_method_{}.{}_{}_{}",
|
||||
box_name, method, recv_str, args_str)
|
||||
}
|
||||
Callee::Value(v) => {
|
||||
format!("call_value_{}_{}", v.as_u32(), args_str)
|
||||
}
|
||||
Callee::Extern(name) => {
|
||||
format!("call_extern_{}_{}", name, args_str)
|
||||
}
|
||||
Callee::Constructor { box_type } => {
|
||||
format!("call_ctor_{}_{}", box_type, args_str)
|
||||
}
|
||||
Callee::Closure { .. } => {
|
||||
// Closures are unique by definition (captures, params may differ)
|
||||
// Use func as distinguisher
|
||||
format!("call_closure_{}_{}", func.as_u32(), args_str)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Legacy path: no callee information, use func
|
||||
format!("call_legacy_{}_{}", func.as_u32(), args_str)
|
||||
}
|
||||
}
|
||||
other => format!("other_{:?}", other),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user