24
24
#include " BPFInstrInfo.h"
25
25
#include " BPFTargetMachine.h"
26
26
#include " llvm/ADT/Statistic.h"
27
+ #include " llvm/ADT/StringExtras.h"
27
28
#include " llvm/CodeGen/LivePhysRegs.h"
28
29
#include " llvm/CodeGen/MachineFrameInfo.h"
29
30
#include " llvm/CodeGen/MachineFunctionPass.h"
@@ -322,6 +323,7 @@ struct BPFMIPreEmitPeephole : public MachineFunctionPass {
322
323
bool eliminateRedundantMov ();
323
324
bool adjustBranch ();
324
325
bool insertMissingCallerSavedSpills ();
326
+ bool removeMayGotoZero ();
325
327
326
328
public:
327
329
@@ -337,6 +339,7 @@ struct BPFMIPreEmitPeephole : public MachineFunctionPass {
337
339
if (SupportGotol)
338
340
Changed = adjustBranch () || Changed;
339
341
Changed |= insertMissingCallerSavedSpills ();
342
+ Changed |= removeMayGotoZero ();
340
343
return Changed;
341
344
}
342
345
};
@@ -682,6 +685,59 @@ bool BPFMIPreEmitPeephole::insertMissingCallerSavedSpills() {
682
685
return Changed;
683
686
}
684
687
688
+ bool BPFMIPreEmitPeephole::removeMayGotoZero () {
689
+ bool Changed = false ;
690
+ MachineBasicBlock *Prev_MBB, *Curr_MBB = nullptr ;
691
+
692
+ for (MachineBasicBlock &MBB : make_early_inc_range (reverse (*MF))) {
693
+ Prev_MBB = Curr_MBB;
694
+ Curr_MBB = &MBB;
695
+ if (Prev_MBB == nullptr || Curr_MBB->empty ())
696
+ continue ;
697
+
698
+ MachineInstr &MI = Curr_MBB->back ();
699
+ if (MI.getOpcode () != TargetOpcode::INLINEASM_BR)
700
+ continue ;
701
+
702
+ const char *AsmStr = MI.getOperand (0 ).getSymbolName ();
703
+ SmallVector<StringRef, 4 > AsmPieces;
704
+ SplitString (AsmStr, AsmPieces, " ;\n " );
705
+
706
+ // Do not support multiple insns in one inline asm.
707
+ if (AsmPieces.size () != 1 )
708
+ continue ;
709
+
710
+ // The asm insn must be a may_goto insn.
711
+ SmallVector<StringRef, 4 > AsmOpPieces;
712
+ SplitString (AsmPieces[0 ], AsmOpPieces, " " );
713
+ if (AsmOpPieces.size () != 2 || AsmOpPieces[0 ] != " may_goto" )
714
+ continue ;
715
+ // Enforce the format of 'may_goto <label>'.
716
+ if (AsmOpPieces[1 ] != " ${0:l}" && AsmOpPieces[1 ] != " $0" )
717
+ continue ;
718
+
719
+ // Get the may_goto branch target.
720
+ MachineOperand &MO = MI.getOperand (InlineAsm::MIOp_FirstOperand + 1 );
721
+ if (!MO.isMBB () || MO.getMBB () != Prev_MBB)
722
+ continue ;
723
+
724
+ Changed = true ;
725
+ if (Curr_MBB->begin () == MI) {
726
+ // Single 'may_goto' insn in the same basic block.
727
+ Curr_MBB->removeSuccessor (Prev_MBB);
728
+ for (MachineBasicBlock *Pred : Curr_MBB->predecessors ())
729
+ Pred->replaceSuccessor (Curr_MBB, Prev_MBB);
730
+ Curr_MBB->eraseFromParent ();
731
+ Curr_MBB = Prev_MBB;
732
+ } else {
733
+ // Remove 'may_goto' insn.
734
+ MI.eraseFromParent ();
735
+ }
736
+ }
737
+
738
+ return Changed;
739
+ }
740
+
685
741
} // end default namespace
686
742
687
743
INITIALIZE_PASS (BPFMIPreEmitPeephole, " bpf-mi-pemit-peephole" ,
0 commit comments