From e826f9ee5771cd63f0d14bdc9d6acd7bd5e4c990 Mon Sep 17 00:00:00 2001 From: lzkk <956449176@qq.com> Date: Thu, 28 May 2026 01:45:39 +0800 Subject: [PATCH] =?UTF-8?q?perf(mir):=20=E8=B4=9F=E9=99=A4=E6=95=B0?= =?UTF-8?q?=E6=A8=A12^n=E5=90=8C=E6=A0=B7=E4=BD=BF=E7=94=A8AND=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mir/Lowering.cpp | 76 ++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 41 deletions(-) diff --git a/src/mir/Lowering.cpp b/src/mir/Lowering.cpp index b47e11ec..2efce285 100644 --- a/src/mir/Lowering.cpp +++ b/src/mir/Lowering.cpp @@ -599,61 +599,55 @@ namespace mir } if (val < 0 && (-val & (-val - 1)) == 0 && val != -1) { + // x % -2^n → 同 x % 2^n: (x & (2^n-1)) + sign fixup int abs_val = -val; - int bias = abs_val - 1; - int biased = function.CreateVReg(VRegClass::Int); - if (bias <= 4095) + int mask = abs_val - 1; + int masked = function.CreateVReg(VRegClass::Int); + if (mask <= 4095) { - block.Append(Opcode::AddRR, - {Operand::VReg(biased, VRegClass::Int), + block.Append(Opcode::AndRR, + {Operand::VReg(masked, VRegClass::Int), Operand::VReg(lhs, VRegClass::Int), - Operand::Imm(bias)}); + Operand::Imm(mask)}); } else { - int bias_reg = function.CreateVReg(VRegClass::Int); + int mask_reg = function.CreateVReg(VRegClass::Int); block.Append(Opcode::MovImm, - {Operand::VReg(bias_reg, VRegClass::Int), - Operand::Imm(bias)}).SetRematerializable(true).SetRematImm(bias); - block.Append(Opcode::AddRR, - {Operand::VReg(biased, VRegClass::Int), + {Operand::VReg(mask_reg, VRegClass::Int), + Operand::Imm(mask)}).SetRematerializable(true).SetRematImm(mask); + block.Append(Opcode::AndRR, + {Operand::VReg(masked, VRegClass::Int), Operand::VReg(lhs, VRegClass::Int), - Operand::VReg(bias_reg, VRegClass::Int)}); - } - int shift = 0; - int tmp = abs_val; - while (tmp > 1) - { - tmp >>= 1; - ++shift; + Operand::VReg(mask_reg, VRegClass::Int)}); } block.Append(Opcode::CmpImm, {Operand::VReg(lhs, VRegClass::Int), Operand::Imm(0)}); - int selected = function.CreateVReg(VRegClass::Int); + int neg_fixup = function.CreateVReg(VRegClass::Int); + if (static_cast(abs_val) <= 4095) + { + block.Append(Opcode::SubRR, + {Operand::VReg(neg_fixup, VRegClass::Int), + Operand::VReg(masked, VRegClass::Int), + Operand::Imm(abs_val)}); + } + else + { + int val_reg = function.CreateVReg(VRegClass::Int); + block.Append(Opcode::MovImm, + {Operand::VReg(val_reg, VRegClass::Int), + Operand::Imm(abs_val)}).SetRematerializable(true).SetRematImm(abs_val); + block.Append(Opcode::SubRR, + {Operand::VReg(neg_fixup, VRegClass::Int), + Operand::VReg(masked, VRegClass::Int), + Operand::VReg(val_reg, VRegClass::Int)}); + } block.Append(Opcode::Csel, - {Operand::VReg(selected, VRegClass::Int), - Operand::VReg(biased, VRegClass::Int), - Operand::VReg(lhs, VRegClass::Int), - Operand::Imm(static_cast(CondCode::LT))}); - int asr_result = function.CreateVReg(VRegClass::Int); - block.Append(Opcode::AsrRR, - {Operand::VReg(asr_result, VRegClass::Int), - Operand::VReg(selected, VRegClass::Int), - Operand::Imm(shift)}); - int q_dst = function.CreateVReg(VRegClass::Int); - block.Append(Opcode::NegRR, - {Operand::VReg(q_dst, VRegClass::Int), - Operand::VReg(asr_result, VRegClass::Int)}); - int d_reg = function.CreateVReg(VRegClass::Int); - block.Append(Opcode::MovImm, - {Operand::VReg(d_reg, VRegClass::Int), - Operand::Imm(val)}).SetRematerializable(true).SetRematImm(val); - block.Append(Opcode::Msub, {Operand::VReg(dst, VRegClass::Int), - Operand::VReg(q_dst, VRegClass::Int), - Operand::VReg(d_reg, VRegClass::Int), - Operand::VReg(lhs, VRegClass::Int)}); + Operand::VReg(neg_fixup, VRegClass::Int), + Operand::VReg(masked, VRegClass::Int), + Operand::Imm(static_cast(CondCode::LT))}); value_vregs[value] = dst; return dst; }