perf(mir): 添加 AddShiftRR/SubShiftRR 支持——lsl+add 合并为 add lsl

- MIR.h: 新增 AddShiftRR/SubShiftRR 操作码(4 操作数: dst, src1, src2, shift)
- RegAlloc: 更新 def/use 分析
- AsmPrinter: 发射 add/sub dst, src1, src2, lsl #shift
- Peephole: 相邻 ShlRR+AddRR/SubRR → AddShiftRR/SubShiftRR

为后续在 Lowering 阶段直接生成移位操作数铺路。
lzk
lzkk 2 days ago
parent e1944acc6b
commit 8d0c5ebcd0

@ -147,6 +147,8 @@ namespace mir
StoreMem,
AddRR,
SubRR,
AddShiftRR,
SubShiftRR,
MulRR,
DivRR,
ModRR,

@ -42,8 +42,10 @@ namespace mir
case Opcode::StoreStack:
return "stur";
case Opcode::AddRR:
case Opcode::AddShiftRR:
return "add";
case Opcode::SubRR:
case Opcode::SubShiftRR:
return "sub";
case Opcode::MulRR:
return "mul";
@ -812,6 +814,20 @@ namespace mir
}
return;
case Opcode::AddShiftRR:
case Opcode::SubShiftRR:
if (operands.size() >= 4)
{
os << " " << asm_op << " ";
PrintOperand(operands[0], os);
os << ", ";
PrintOperand(operands[1], os);
os << ", ";
PrintOperand(operands[2], os);
os << ", lsl #" << operands[3].GetImm() << "\n";
}
return;
default:
break;
}

@ -123,6 +123,8 @@ namespace mir
case Opcode::AddRR:
case Opcode::SubRR:
case Opcode::AddShiftRR:
case Opcode::SubShiftRR:
case Opcode::MulRR:
case Opcode::DivRR:
case Opcode::ModRR:

@ -256,6 +256,56 @@ namespace mir
}
}
// ShlRR + AddRR/SubRR → AddShiftRR/SubShiftRR (lsl wA,wB,#n; add wC,wB,wA → add wC,wB,wB,lsl#n)
if (!changed)
{
for (auto it = insts.begin(); it != insts.end(); ++it)
{
if (it->GetOpcode() != Opcode::ShlRR) continue;
auto next = std::next(it);
if (next == insts.end()) continue;
if (next->GetOpcode() != Opcode::AddRR && next->GetOpcode() != Opcode::SubRR)
continue;
const auto &shl_ops = it->GetOperands();
const auto &arith_ops = next->GetOperands();
if (shl_ops.size() < 3 || arith_ops.size() < 3) continue;
// shl: [dst(A), src(B), shift_imm]
// add/sub: [dst(C), src1, src2]
// 检查 shl 的 dst 是否等于 add/sub 的一个 src且 shl 的 src 等于 add/sub 的另一个 src
PhysReg shl_dst = shl_ops[0].GetReg();
PhysReg shl_src = shl_ops[1].GetReg();
int shift = shl_ops[2].GetImm();
PhysReg arith_src1 = arith_ops[1].GetReg();
PhysReg arith_src2 = arith_ops[2].GetReg();
if (shl_dst == arith_src1 && shl_src == arith_src2)
{
// lsl A, B, #n; add C, A, B → add C, B, B, lsl #n
auto new_op = (next->GetOpcode() == Opcode::AddRR)
? Opcode::AddShiftRR : Opcode::SubShiftRR;
*next = MachineInstr(new_op, {arith_ops[0], shl_ops[1], shl_ops[1],
Operand::Imm(shift)});
it = insts.erase(it);
changed = true;
break;
}
if (shl_dst == arith_src2 && shl_src == arith_src1)
{
// lsl A, B, #n; add C, B, A → add C, B, B, lsl #n
auto new_op = (next->GetOpcode() == Opcode::AddRR)
? Opcode::AddShiftRR : Opcode::SubShiftRR;
*next = MachineInstr(new_op, {arith_ops[0], shl_ops[1], shl_ops[1],
Operand::Imm(shift)});
it = insts.erase(it);
changed = true;
break;
}
}
}
// 消除冗余 adrp同一符号、同一寄存器的重复 adrp
if (!changed)
{

Loading…
Cancel
Save