From 8d0c5ebcd05ac0582e926ac68753f2f2a626ee95 Mon Sep 17 00:00:00 2001 From: lzkk <956449176@qq.com> Date: Thu, 28 May 2026 14:25:12 +0800 Subject: [PATCH] =?UTF-8?q?perf(mir):=20=E6=B7=BB=E5=8A=A0=20AddShiftRR/Su?= =?UTF-8?q?bShiftRR=20=E6=94=AF=E6=8C=81=E2=80=94=E2=80=94lsl+add=20?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=B8=BA=20add=20lsl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 阶段直接生成移位操作数铺路。 --- src/include/mir/MIR.h | 2 ++ src/mir/AsmPrinter.cpp | 16 ++++++++++++ src/mir/RegAlloc.cpp | 2 ++ src/mir/passes/Peephole.cpp | 50 +++++++++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+) diff --git a/src/include/mir/MIR.h b/src/include/mir/MIR.h index 545330f7..4d4ca52b 100644 --- a/src/include/mir/MIR.h +++ b/src/include/mir/MIR.h @@ -147,6 +147,8 @@ namespace mir StoreMem, AddRR, SubRR, + AddShiftRR, + SubShiftRR, MulRR, DivRR, ModRR, diff --git a/src/mir/AsmPrinter.cpp b/src/mir/AsmPrinter.cpp index a29d65d1..6627b1b7 100644 --- a/src/mir/AsmPrinter.cpp +++ b/src/mir/AsmPrinter.cpp @@ -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; } diff --git a/src/mir/RegAlloc.cpp b/src/mir/RegAlloc.cpp index 17d5374f..96417827 100644 --- a/src/mir/RegAlloc.cpp +++ b/src/mir/RegAlloc.cpp @@ -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: diff --git a/src/mir/passes/Peephole.cpp b/src/mir/passes/Peephole.cpp index c06f36ae..fee43f86 100644 --- a/src/mir/passes/Peephole.cpp +++ b/src/mir/passes/Peephole.cpp @@ -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) {