simplify compare-to-branch sequences
This commit is contained in:
@@ -46,11 +46,62 @@ bool IsFloatReg(PhysReg reg) {
|
|||||||
return reg >= PhysReg::S0 && reg <= PhysReg::S15;
|
return reg >= PhysReg::S0 && reg <= PhysReg::S15;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SameReg(const Operand& lhs, const Operand& rhs) {
|
||||||
|
return lhs.GetKind() == Operand::Kind::Reg &&
|
||||||
|
rhs.GetKind() == Operand::Kind::Reg &&
|
||||||
|
NormalizeReg(lhs.GetReg()) == NormalizeReg(rhs.GetReg());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsZeroImm(const Operand& operand) {
|
||||||
|
return operand.GetKind() == Operand::Kind::Imm && operand.GetImm() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<MachineInstr> SimplifyCompareToBranch(
|
||||||
|
const std::vector<MachineInstr>& insts) {
|
||||||
|
std::vector<MachineInstr> simplified;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < insts.size();) {
|
||||||
|
if (i + 4 < insts.size() &&
|
||||||
|
(insts[i].GetOpcode() == Opcode::CmpRR ||
|
||||||
|
insts[i].GetOpcode() == Opcode::FCmpRR) &&
|
||||||
|
insts[i + 1].GetOpcode() == Opcode::Cset &&
|
||||||
|
insts[i + 2].GetOpcode() == Opcode::MovImm &&
|
||||||
|
insts[i + 3].GetOpcode() == Opcode::CmpRR &&
|
||||||
|
insts[i + 4].GetOpcode() == Opcode::BCond) {
|
||||||
|
const auto& cset_ops = insts[i + 1].GetOperands();
|
||||||
|
const auto& mov_ops = insts[i + 2].GetOperands();
|
||||||
|
const auto& cmp2_ops = insts[i + 3].GetOperands();
|
||||||
|
const auto& br_ops = insts[i + 4].GetOperands();
|
||||||
|
|
||||||
|
if (mov_ops.size() == 2 && cmp2_ops.size() == 2 && br_ops.size() == 2 &&
|
||||||
|
SameReg(cset_ops.at(0), cmp2_ops.at(0)) &&
|
||||||
|
SameReg(mov_ops.at(0), cmp2_ops.at(1)) &&
|
||||||
|
IsZeroImm(mov_ops.at(1)) &&
|
||||||
|
br_ops.at(0).GetKind() == Operand::Kind::Cond &&
|
||||||
|
br_ops.at(0).GetCondCode() == "ne") {
|
||||||
|
simplified.push_back(insts[i]);
|
||||||
|
simplified.emplace_back(Opcode::BCond,
|
||||||
|
std::vector<Operand>{
|
||||||
|
Operand::Cond(cset_ops.at(1).GetCondCode()),
|
||||||
|
br_ops.at(1)});
|
||||||
|
i += 5;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
simplified.push_back(insts[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return simplified;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void RunPeephole(MachineFunction& function) {
|
void RunPeephole(MachineFunction& function) {
|
||||||
for (auto& block : function.GetBlocks()) {
|
for (auto& block : function.GetBlocks()) {
|
||||||
auto& insts = block.GetInstructions();
|
auto& insts = block.GetInstructions();
|
||||||
|
insts = SimplifyCompareToBranch(insts);
|
||||||
std::vector<MachineInstr> optimized;
|
std::vector<MachineInstr> optimized;
|
||||||
|
|
||||||
// Map from FrameIndex to the normalized physical register that currently holds its value
|
// Map from FrameIndex to the normalized physical register that currently holds its value
|
||||||
|
|||||||
Reference in New Issue
Block a user