perf(mir): 负除数模2^n同样使用AND优化

lzk
lzkk 3 days ago
parent 421df18c81
commit e826f9ee57

@ -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<unsigned int>(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<int>(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<int>(CondCode::LT))});
value_vregs[value] = dst;
return dst;
}

Loading…
Cancel
Save