diff --git a/llvm/lib/Target/BPF/BPFMIPeephole.cpp b/llvm/lib/Target/BPF/BPFMIPeephole.cpp index 2b17f2aaefe2b..106572cdeb840 100644 --- a/llvm/lib/Target/BPF/BPFMIPeephole.cpp +++ b/llvm/lib/Target/BPF/BPFMIPeephole.cpp @@ -24,6 +24,7 @@ #include "BPFInstrInfo.h" #include "BPFTargetMachine.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/CodeGen/LivePhysRegs.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -322,6 +323,7 @@ struct BPFMIPreEmitPeephole : public MachineFunctionPass { bool eliminateRedundantMov(); bool adjustBranch(); bool insertMissingCallerSavedSpills(); + bool removeMayGotoZero(); public: @@ -337,6 +339,7 @@ struct BPFMIPreEmitPeephole : public MachineFunctionPass { if (SupportGotol) Changed = adjustBranch() || Changed; Changed |= insertMissingCallerSavedSpills(); + Changed |= removeMayGotoZero(); return Changed; } }; @@ -682,6 +685,59 @@ bool BPFMIPreEmitPeephole::insertMissingCallerSavedSpills() { return Changed; } +bool BPFMIPreEmitPeephole::removeMayGotoZero() { + bool Changed = false; + MachineBasicBlock *Prev_MBB, *Curr_MBB = nullptr; + + for (MachineBasicBlock &MBB : make_early_inc_range(reverse(*MF))) { + Prev_MBB = Curr_MBB; + Curr_MBB = &MBB; + if (Prev_MBB == nullptr || Curr_MBB->empty()) + continue; + + MachineInstr &MI = Curr_MBB->back(); + if (MI.getOpcode() != TargetOpcode::INLINEASM_BR) + continue; + + const char *AsmStr = MI.getOperand(0).getSymbolName(); + SmallVector AsmPieces; + SplitString(AsmStr, AsmPieces, ";\n"); + + // Do not support multiple insns in one inline asm. + if (AsmPieces.size() != 1) + continue; + + // The asm insn must be a may_goto insn. + SmallVector AsmOpPieces; + SplitString(AsmPieces[0], AsmOpPieces, " "); + if (AsmOpPieces.size() != 2 || AsmOpPieces[0] != "may_goto") + continue; + // Enforce the format of 'may_goto