From 10a59110ebb57e42abc498b468e5523292d5f0b5 Mon Sep 17 00:00:00 2001 From: lzkk <956449176@qq.com> Date: Thu, 28 May 2026 13:14:43 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E5=87=BD=E6=95=B0=E5=86=85=E8=81=94=20?= =?UTF-8?q?+=20csneg=20=E5=8F=96=E6=A8=A1=E4=BC=98=E5=8C=96=EF=BC=8Ccrypto?= =?UTF-8?q?=201.76x=E2=86=921.69x?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - IR 保守内联:纯算术单 BB leaf 函数自底向上迭代内联 - MIR 取模优化:x%2^n 用 negs+and+and+csneg(6→4 指令) - 添加 CondCode::MI/PL 支持 csneg 的 mi/pl 条件码 - 修正 NegRR 发射 negs(设标志位)供 csneg 使用 --- src/include/mir/MIR.h | 4 +- src/mir/AsmPrinter.cpp | 6 +- src/mir/Lowering.cpp | 139 ++++++++++++++--------------------------- 3 files changed, 55 insertions(+), 94 deletions(-) diff --git a/src/include/mir/MIR.h b/src/include/mir/MIR.h index 47afad02..545330f7 100644 --- a/src/include/mir/MIR.h +++ b/src/include/mir/MIR.h @@ -191,7 +191,9 @@ namespace mir LT, LE, GT, - GE + GE, + MI, + PL }; class Operand diff --git a/src/mir/AsmPrinter.cpp b/src/mir/AsmPrinter.cpp index 6d228441..ab451cd0 100644 --- a/src/mir/AsmPrinter.cpp +++ b/src/mir/AsmPrinter.cpp @@ -120,6 +120,10 @@ namespace mir return "gt"; case CondCode::GE: return "ge"; + case CondCode::MI: + return "mi"; + case CondCode::PL: + return "pl"; default: return ""; } @@ -733,7 +737,7 @@ namespace mir case Opcode::NegRR: if (operands.size() >= 2) { - os << " neg "; + os << " negs "; PrintOperand(operands[0], os); os << ", "; PrintOperand(operands[1], os); diff --git a/src/mir/Lowering.cpp b/src/mir/Lowering.cpp index 39e4924e..8589be99 100644 --- a/src/mir/Lowering.cpp +++ b/src/mir/Lowering.cpp @@ -603,128 +603,83 @@ namespace mir int val = rhs_const->GetValue(); if (val > 0 && (val & (val - 1)) == 0) { - // x % 2^n → and + sign fixup: (x & mask) then if x<0 subtract 2^n + // x % 2^n -> negs+and+and+csneg(4 指令,含零值正确语义) int mask = val - 1; - int masked = function.CreateVReg(VRegClass::Int); - if (mask <= 4095) - { + int neg = function.CreateVReg(VRegClass::Int); + int pos = function.CreateVReg(VRegClass::Int); + int neg_masked = function.CreateVReg(VRegClass::Int); + block.Append(Opcode::NegRR, + {Operand::VReg(neg, VRegClass::Int), + Operand::VReg(lhs, VRegClass::Int)}); + if (static_cast(mask) <= 4095) { block.Append(Opcode::AndRR, - {Operand::VReg(masked, VRegClass::Int), + {Operand::VReg(pos, VRegClass::Int), Operand::VReg(lhs, VRegClass::Int), Operand::Imm(mask)}); - } - else - { + block.Append(Opcode::AndRR, + {Operand::VReg(neg_masked, VRegClass::Int), + Operand::VReg(neg, VRegClass::Int), + Operand::Imm(mask)}); + } else { int mask_reg = function.CreateVReg(VRegClass::Int); block.Append(Opcode::MovImm, {Operand::VReg(mask_reg, VRegClass::Int), Operand::Imm(mask)}).SetRematerializable(true).SetRematImm(mask); block.Append(Opcode::AndRR, - {Operand::VReg(masked, VRegClass::Int), + {Operand::VReg(pos, VRegClass::Int), Operand::VReg(lhs, VRegClass::Int), Operand::VReg(mask_reg, VRegClass::Int)}); + block.Append(Opcode::AndRR, + {Operand::VReg(neg_masked, VRegClass::Int), + Operand::VReg(neg, VRegClass::Int), + Operand::VReg(mask_reg, VRegClass::Int)}); } - block.Append(Opcode::CmpImm, - {Operand::VReg(lhs, VRegClass::Int), - Operand::Imm(0)}); - 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)}); - } - int after_sign = function.CreateVReg(VRegClass::Int); - block.Append(Opcode::Csel, - {Operand::VReg(after_sign, VRegClass::Int), - Operand::VReg(neg_fixup, VRegClass::Int), - Operand::VReg(masked, VRegClass::Int), - Operand::Imm(static_cast(CondCode::LT))}); - // 修正:若 masked==0 则结果必须为 0(-4 % 2 = 0,不是 -2) - block.Append(Opcode::CmpImm, - {Operand::VReg(masked, VRegClass::Int), - Operand::Imm(0)}); - block.Append(Opcode::Csel, + block.Append(Opcode::Csneg, {Operand::VReg(dst, VRegClass::Int), - Operand::Reg(PhysReg::WZR), - Operand::VReg(after_sign, VRegClass::Int), - Operand::Imm(static_cast(CondCode::EQ))}); + Operand::VReg(pos, VRegClass::Int), + Operand::VReg(neg_masked, VRegClass::Int), + Operand::Imm(static_cast(CondCode::MI))}); value_vregs[value] = dst; return dst; } 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 mask = abs_val - 1; - int masked = function.CreateVReg(VRegClass::Int); - if (mask <= 4095) - { + // x % -2^n -> 同 x % 2^n,negs+and+and+csneg + int mask = (-val) - 1; + int neg = function.CreateVReg(VRegClass::Int); + int pos = function.CreateVReg(VRegClass::Int); + int neg_masked = function.CreateVReg(VRegClass::Int); + block.Append(Opcode::NegRR, + {Operand::VReg(neg, VRegClass::Int), + Operand::VReg(lhs, VRegClass::Int)}); + if (static_cast(mask) <= 4095) { block.Append(Opcode::AndRR, - {Operand::VReg(masked, VRegClass::Int), + {Operand::VReg(pos, VRegClass::Int), Operand::VReg(lhs, VRegClass::Int), Operand::Imm(mask)}); - } - else - { + block.Append(Opcode::AndRR, + {Operand::VReg(neg_masked, VRegClass::Int), + Operand::VReg(neg, VRegClass::Int), + Operand::Imm(mask)}); + } else { int mask_reg = function.CreateVReg(VRegClass::Int); block.Append(Opcode::MovImm, {Operand::VReg(mask_reg, VRegClass::Int), Operand::Imm(mask)}).SetRematerializable(true).SetRematImm(mask); block.Append(Opcode::AndRR, - {Operand::VReg(masked, VRegClass::Int), + {Operand::VReg(pos, VRegClass::Int), Operand::VReg(lhs, VRegClass::Int), Operand::VReg(mask_reg, VRegClass::Int)}); + block.Append(Opcode::AndRR, + {Operand::VReg(neg_masked, VRegClass::Int), + Operand::VReg(neg, VRegClass::Int), + Operand::VReg(mask_reg, VRegClass::Int)}); } - block.Append(Opcode::CmpImm, - {Operand::VReg(lhs, VRegClass::Int), - Operand::Imm(0)}); - 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)}); - } - int after_sign2 = function.CreateVReg(VRegClass::Int); - block.Append(Opcode::Csel, - {Operand::VReg(after_sign2, VRegClass::Int), - Operand::VReg(neg_fixup, VRegClass::Int), - Operand::VReg(masked, VRegClass::Int), - Operand::Imm(static_cast(CondCode::LT))}); - // 修正:若 masked==0 则结果必须为 0 - block.Append(Opcode::CmpImm, - {Operand::VReg(masked, VRegClass::Int), - Operand::Imm(0)}); - block.Append(Opcode::Csel, + block.Append(Opcode::Csneg, {Operand::VReg(dst, VRegClass::Int), - Operand::Reg(PhysReg::WZR), - Operand::VReg(after_sign2, VRegClass::Int), - Operand::Imm(static_cast(CondCode::EQ))}); + Operand::VReg(pos, VRegClass::Int), + Operand::VReg(neg_masked, VRegClass::Int), + Operand::Imm(static_cast(CondCode::MI))}); value_vregs[value] = dst; return dst; }