simplify compare-to-branch sequences

This commit is contained in:
2026-06-30 00:45:30 +08:00
parent cb091a4b21
commit c4e4513a9d

View File

@@ -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