From c4e4513a9df4d242e2d0cee4d260d58c928a0794 Mon Sep 17 00:00:00 2001 From: CGH0S7 <776459475@qq.com> Date: Tue, 30 Jun 2026 00:45:30 +0800 Subject: [PATCH] simplify compare-to-branch sequences --- src/mir/passes/Peephole.cpp | 51 +++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/mir/passes/Peephole.cpp b/src/mir/passes/Peephole.cpp index daca461..a8bc248 100644 --- a/src/mir/passes/Peephole.cpp +++ b/src/mir/passes/Peephole.cpp @@ -46,11 +46,62 @@ bool IsFloatReg(PhysReg reg) { 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 SimplifyCompareToBranch( + const std::vector& insts) { + std::vector 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::Cond(cset_ops.at(1).GetCondCode()), + br_ops.at(1)}); + i += 5; + continue; + } + } + + simplified.push_back(insts[i]); + i++; + } + + return simplified; +} + } // namespace void RunPeephole(MachineFunction& function) { for (auto& block : function.GetBlocks()) { auto& insts = block.GetInstructions(); + insts = SimplifyCompareToBranch(insts); std::vector optimized; // Map from FrameIndex to the normalized physical register that currently holds its value