perf: CONCAT_N 多操作数拼接单趟精确预分配替代逐次 ADD
新增 CONCAT_N opcode(0x93):连续加号左结合链摊平为单条指令, 字符串模式单趟精确总长预分配,消除 N-2 次中间串分配与逐次整串重拷贝。 - emit 只下钻 left 链、right 括号不拆(a+(b+c) 退化 ADD),求值序与 f64 结合性保持左结合原义;摊平上限 14 防超长链寄存器压力 - dispatch 两阶段:数值前缀逐项复用 ADD 判定序列(int 溢出升 double、 BigInt 混合 TypeError、对象 ToPrimitive 副作用序),遇字符串转入 字符串模式单趟预分配拼接(concat_n_strings) - RegAlloc graph/rewrite 登记 CONCAT_N ext 操作数(漏收集即错值); ic_helper ext_word_count 登记(clear_ic_caches 字节定位) - contract golden 显式 CONCAT_N 分支(规避 canonical_inst _ 兜底)
This commit is contained in:
@@ -246,6 +246,15 @@ fn rewrite_inst(
|
||||
}
|
||||
ext
|
||||
}
|
||||
// CONCAT_N:ext[1..] 每个字是完整操作数 vreg(无高位标记),直接重映射,
|
||||
// 否则 RegAlloc 后读旧 vreg 号对应物理槽(错值)。
|
||||
OpCode::CONCAT_N => {
|
||||
let mut ext = inst.ext.clone();
|
||||
for seg in ext.iter_mut().skip(1) {
|
||||
*seg = remap_ext_reg(*seg, slot_color, map);
|
||||
}
|
||||
ext
|
||||
}
|
||||
_ => inst.ext.clone(),
|
||||
};
|
||||
// 调用点首参槽改指 arg_window_base(桥接后)
|
||||
@@ -457,6 +466,23 @@ mod tests {
|
||||
assert_eq!(f.insts[0].ext.as_slice(), &[3 << 16, 0, 0x8000_0000 | 200, 1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn concat_n_ext_operands_remapped() {
|
||||
// CONCAT_N ext[1..] 操作数 vreg 必须重映射到物理号(含 spill use 点 fresh 色)
|
||||
let inst = Inst::concat_n(Operand::Reg(1), &[2, 300, 9]);
|
||||
let mut map = AllocMap::new();
|
||||
map.map.insert(1, Alloc::Phys(2));
|
||||
map.map.insert(2, Alloc::Phys(3));
|
||||
map.map.insert(300, Alloc::Phys(200));
|
||||
map.map.insert(9, Alloc::Phys(11));
|
||||
let f = rewrite_with_map(vec![inst], map);
|
||||
|
||||
assert_eq!(f.insts[0].op, OpCode::CONCAT_N);
|
||||
assert_eq!(f.insts[0].rd, Operand::Reg(2));
|
||||
assert_eq!(f.insts[0].a, Operand::Reg(3));
|
||||
assert_eq!(f.insts[0].ext.as_slice(), &[3, 200, 11]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scattered_args_insert_mov_bridge() {
|
||||
let insts = vec![Inst::call(Operand::Reg(2), Operand::Reg(3), Operand::Reg(4), 3)];
|
||||
|
||||
Reference in New Issue
Block a user