|
|
|
|
@ -408,11 +408,51 @@ namespace mir
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int dst = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
|
|
|
|
|
// Madd 折叠:sum + (a * b) → madd sum, a, b, sum(必须在 EmitIntValue 之前)
|
|
|
|
|
if (opcode == Opcode::AddRR)
|
|
|
|
|
{
|
|
|
|
|
auto *mul_rhs = dynamic_cast<const ir::BinaryInst *>(bin->GetRhs());
|
|
|
|
|
auto *mul_lhs = dynamic_cast<const ir::BinaryInst *>(bin->GetLhs());
|
|
|
|
|
const ir::BinaryInst *mul_op = nullptr;
|
|
|
|
|
bool mul_is_rhs = true;
|
|
|
|
|
|
|
|
|
|
if (mul_rhs && mul_rhs->GetOpcode() == ir::Opcode::Mul)
|
|
|
|
|
mul_op = mul_rhs;
|
|
|
|
|
else if (mul_lhs && mul_lhs->GetOpcode() == ir::Opcode::Mul)
|
|
|
|
|
{ mul_op = mul_lhs; mul_is_rhs = false; }
|
|
|
|
|
|
|
|
|
|
if (mul_op)
|
|
|
|
|
{
|
|
|
|
|
// 仅当 Mul 两端都不是常量时才折叠(常量有 shift/强度削减更优)
|
|
|
|
|
int dummy;
|
|
|
|
|
if (!TryGetConstantInt(mul_op->GetRhs(), dummy) &&
|
|
|
|
|
!TryGetConstantInt(mul_op->GetLhs(), dummy))
|
|
|
|
|
{
|
|
|
|
|
int a = EmitIntValue(mul_op->GetLhs(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
int b = EmitIntValue(mul_op->GetRhs(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
int acc = EmitIntValue(mul_is_rhs ? bin->GetLhs() : bin->GetRhs(),
|
|
|
|
|
function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
block.Append(Opcode::Madd,
|
|
|
|
|
{Operand::VReg(dst, VRegClass::Int),
|
|
|
|
|
Operand::VReg(a, VRegClass::Int),
|
|
|
|
|
Operand::VReg(b, VRegClass::Int),
|
|
|
|
|
Operand::VReg(acc, VRegClass::Int)});
|
|
|
|
|
value_vregs[value] = dst;
|
|
|
|
|
value_vregs[mul_op] = dst;
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int lhs = EmitIntValue(bin->GetLhs(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
int rhs = EmitIntValue(bin->GetRhs(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
int dst = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
|
|
|
|
|
if (opcode == Opcode::MulRR)
|
|
|
|
|
{
|
|
|
|
|
|