|
|
|
|
@ -659,6 +659,69 @@ namespace mir
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Div/Mod/And/Or 常量提前处理——避免先 emit rhs 再发现不需要的死 MovImm
|
|
|
|
|
if (opcode == Opcode::DivRR || opcode == Opcode::ModRR ||
|
|
|
|
|
opcode == Opcode::AndRR || opcode == Opcode::OrRR)
|
|
|
|
|
{
|
|
|
|
|
if (auto *rhs_const = dynamic_cast<const ir::ConstantInt *>(bin->GetRhs()))
|
|
|
|
|
{
|
|
|
|
|
int val = rhs_const->GetValue();
|
|
|
|
|
// 提前处理 Div/Mod 的 1/-1 和 %2 情况,不 emit rhs
|
|
|
|
|
if (opcode == Opcode::DivRR && val == 1)
|
|
|
|
|
{
|
|
|
|
|
value_vregs[value] = lhs;
|
|
|
|
|
return lhs;
|
|
|
|
|
}
|
|
|
|
|
if (opcode == Opcode::DivRR && val == -1)
|
|
|
|
|
{
|
|
|
|
|
block.Append(Opcode::NegRR,
|
|
|
|
|
{Operand::VReg(dst, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int)});
|
|
|
|
|
value_vregs[value] = dst;
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
// Mod by 2(含正负):and+cmp+csneg,不 emit rhs
|
|
|
|
|
if (opcode == Opcode::ModRR && (val == 2 || val == -2))
|
|
|
|
|
{
|
|
|
|
|
int pos = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::AndRR,
|
|
|
|
|
{Operand::VReg(pos, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(1)});
|
|
|
|
|
block.Append(Opcode::CmpImm,
|
|
|
|
|
{Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(0)});
|
|
|
|
|
block.Append(Opcode::Csneg,
|
|
|
|
|
{Operand::VReg(dst, VRegClass::Int),
|
|
|
|
|
Operand::VReg(pos, VRegClass::Int),
|
|
|
|
|
Operand::VReg(pos, VRegClass::Int),
|
|
|
|
|
Operand::Imm(static_cast<int>(CondCode::GE))});
|
|
|
|
|
value_vregs[value] = dst;
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
// And with constant → 直接嵌入立即数,不 emit rhs
|
|
|
|
|
if (opcode == Opcode::AndRR && val >= 0 && static_cast<unsigned int>(val) <= 4095)
|
|
|
|
|
{
|
|
|
|
|
block.Append(Opcode::AndRR,
|
|
|
|
|
{Operand::VReg(dst, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(val)});
|
|
|
|
|
value_vregs[value] = dst;
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
// Or with constant → 直接嵌入立即数,不 emit rhs
|
|
|
|
|
if (opcode == Opcode::OrRR && val >= 0 && static_cast<unsigned int>(val) <= 4095)
|
|
|
|
|
{
|
|
|
|
|
block.Append(Opcode::OrRR,
|
|
|
|
|
{Operand::VReg(dst, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(val)});
|
|
|
|
|
value_vregs[value] = dst;
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int rhs = EmitIntValue(bin->GetRhs(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
|
|
|
|
|
@ -806,8 +869,30 @@ namespace mir
|
|
|
|
|
int val = rhs_const->GetValue();
|
|
|
|
|
if (val > 0 && (val & (val - 1)) == 0)
|
|
|
|
|
{
|
|
|
|
|
// x % 2^n -> negs+and+and+csneg(4 指令,含零值正确语义)
|
|
|
|
|
int mask = val - 1;
|
|
|
|
|
|
|
|
|
|
// x % 2 快速路径:and+cmp+csneg ge(3 指令)
|
|
|
|
|
// bit 0 在取反下不变,无需第二个 and
|
|
|
|
|
if (mask == 1)
|
|
|
|
|
{
|
|
|
|
|
int pos = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::AndRR,
|
|
|
|
|
{Operand::VReg(pos, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(1)});
|
|
|
|
|
block.Append(Opcode::CmpImm,
|
|
|
|
|
{Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(0)});
|
|
|
|
|
block.Append(Opcode::Csneg,
|
|
|
|
|
{Operand::VReg(dst, VRegClass::Int),
|
|
|
|
|
Operand::VReg(pos, VRegClass::Int),
|
|
|
|
|
Operand::VReg(pos, VRegClass::Int),
|
|
|
|
|
Operand::Imm(static_cast<int>(CondCode::GE))});
|
|
|
|
|
value_vregs[value] = dst;
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// x % 2^n (n>1) -> negs+and+and+csneg(4 指令,含零值正确语义)
|
|
|
|
|
int neg = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
int pos = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
int neg_masked = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
@ -847,8 +932,29 @@ namespace mir
|
|
|
|
|
}
|
|
|
|
|
if (val < 0 && (-val & (-val - 1)) == 0 && val != -1)
|
|
|
|
|
{
|
|
|
|
|
// x % -2^n -> 同 x % 2^n,negs+and+and+csneg
|
|
|
|
|
int mask = (-val) - 1;
|
|
|
|
|
|
|
|
|
|
// x % -2 快速路径:and+cmp+csneg ge(3 指令)
|
|
|
|
|
if (mask == 1)
|
|
|
|
|
{
|
|
|
|
|
int pos = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::AndRR,
|
|
|
|
|
{Operand::VReg(pos, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(1)});
|
|
|
|
|
block.Append(Opcode::CmpImm,
|
|
|
|
|
{Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(0)});
|
|
|
|
|
block.Append(Opcode::Csneg,
|
|
|
|
|
{Operand::VReg(dst, VRegClass::Int),
|
|
|
|
|
Operand::VReg(pos, VRegClass::Int),
|
|
|
|
|
Operand::VReg(pos, VRegClass::Int),
|
|
|
|
|
Operand::Imm(static_cast<int>(CondCode::GE))});
|
|
|
|
|
value_vregs[value] = dst;
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// x % -2^n (n>1) -> 同 x % 2^n,negs+and+and+csneg
|
|
|
|
|
int neg = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
int pos = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
int neg_masked = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
@ -1839,9 +1945,27 @@ namespace mir
|
|
|
|
|
case ir::Opcode::GEP:
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case ir::Opcode::Mul:
|
|
|
|
|
{
|
|
|
|
|
auto &bin = static_cast<const ir::BinaryInst &>(inst);
|
|
|
|
|
if (IsFloatType(bin.GetType()))
|
|
|
|
|
{
|
|
|
|
|
EmitFloatValue(&bin, function, value_vregs, block);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 若 Mul 的唯一用户是 Add,推迟到 Add 的 Madd 折叠处理
|
|
|
|
|
if (bin.GetUses().size() == 1)
|
|
|
|
|
{
|
|
|
|
|
auto *user = dynamic_cast<const ir::BinaryInst *>(bin.GetUses().begin()->GetUser());
|
|
|
|
|
if (user && user->GetOpcode() == ir::Opcode::Add)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
EmitIntValue(&bin, function, value_vregs, scalar_slots, array_slots, block);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case ir::Opcode::Add:
|
|
|
|
|
case ir::Opcode::Sub:
|
|
|
|
|
case ir::Opcode::Mul:
|
|
|
|
|
case ir::Opcode::Div:
|
|
|
|
|
case ir::Opcode::Mod:
|
|
|
|
|
case ir::Opcode::And:
|
|
|
|
|
|