strength reduce constant integer multiplies
This commit is contained in:
@@ -368,6 +368,33 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|||||||
int dst_slot = function.CreateFrameIndex(4);
|
int dst_slot = function.CreateFrameIndex(4);
|
||||||
slots.emplace(&inst, dst_slot);
|
slots.emplace(&inst, dst_slot);
|
||||||
|
|
||||||
|
if (inst.GetOpcode() == ir::Opcode::Mul) {
|
||||||
|
const ir::Value* variable = nullptr;
|
||||||
|
int constant = 0;
|
||||||
|
if (auto* lhs_const = dynamic_cast<const ir::ConstantInt*>(bin.GetLhs())) {
|
||||||
|
variable = bin.GetRhs();
|
||||||
|
constant = lhs_const->GetValue();
|
||||||
|
} else if (auto* rhs_const = dynamic_cast<const ir::ConstantInt*>(bin.GetRhs())) {
|
||||||
|
variable = bin.GetLhs();
|
||||||
|
constant = rhs_const->GetValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (variable && constant > 1) {
|
||||||
|
EmitValueToReg(variable, PhysReg::W8, slots, block);
|
||||||
|
if (IsPowerOfTwo(static_cast<uint32_t>(constant))) {
|
||||||
|
block.Append(Opcode::LslImm, {Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W8), Operand::Imm(Log2(static_cast<uint32_t>(constant)))});
|
||||||
|
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (IsPowerOfTwo(static_cast<uint32_t>(constant - 1))) {
|
||||||
|
block.Append(Opcode::LslImm, {Operand::Reg(PhysReg::W9), Operand::Reg(PhysReg::W8), Operand::Imm(Log2(static_cast<uint32_t>(constant - 1)))});
|
||||||
|
block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W9), Operand::Reg(PhysReg::W8)});
|
||||||
|
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EmitValueToReg(bin.GetLhs(), PhysReg::W8, slots, block);
|
EmitValueToReg(bin.GetLhs(), PhysReg::W8, slots, block);
|
||||||
EmitValueToReg(bin.GetRhs(), PhysReg::W9, slots, block);
|
EmitValueToReg(bin.GetRhs(), PhysReg::W9, slots, block);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user