From 421df18c81e5dd4f7201b83ccb2723d702aa23c6 Mon Sep 17 00:00:00 2001 From: lzkk <956449176@qq.com> Date: Thu, 28 May 2026 01:44:06 +0800 Subject: [PATCH] =?UTF-8?q?perf(mir):=20=E6=A8=A12^n=E8=BF=90=E7=AE=97?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E2=80=94=E2=80=94AND+=E7=AC=A6=E5=8F=B7?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=9B=BF=E4=BB=A3=20Msub?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit x % 2^n: (x & (2^n-1)) + cmp + csel 替代 asr+msub huffman -20, crypto -33, crc -13, h-9 -7 --- src/mir/Lowering.cpp | 72 +++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/src/mir/Lowering.cpp b/src/mir/Lowering.cpp index b2dc8772..b47e11ec 100644 --- a/src/mir/Lowering.cpp +++ b/src/mir/Lowering.cpp @@ -546,56 +546,54 @@ namespace mir int val = rhs_const->GetValue(); if (val > 0 && (val & (val - 1)) == 0) { - int bias = val - 1; - int biased = function.CreateVReg(VRegClass::Int); - if (bias <= 4095) + // x % 2^n → and + sign fixup: (x & mask) then if x<0 subtract 2^n + int mask = 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 = 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(val) <= 4095) + { + block.Append(Opcode::SubRR, + {Operand::VReg(neg_fixup, VRegClass::Int), + Operand::VReg(masked, VRegClass::Int), + Operand::Imm(val)}); + } + else + { + int val_reg = function.CreateVReg(VRegClass::Int); + block.Append(Opcode::MovImm, + {Operand::VReg(val_reg, VRegClass::Int), + Operand::Imm(val)}).SetRematerializable(true).SetRematImm(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 q_dst = function.CreateVReg(VRegClass::Int); - block.Append(Opcode::AsrRR, - {Operand::VReg(q_dst, VRegClass::Int), - Operand::VReg(selected, VRegClass::Int), - Operand::Imm(shift)}); - 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; }