xref: /llvm-project/llvm/lib/CodeGen/GCEmptyBasicBlocks.cpp (revision e280e406c2e34ce29e1e71da7cd3a284ea112ce8)
1 #include "llvm/ADT/SmallVector.h"
2 #include "llvm/ADT/Statistic.h"
3 #include "llvm/CodeGen/MachineBasicBlock.h"
4 #include "llvm/CodeGen/MachineFunction.h"
5 #include "llvm/CodeGen/MachineFunctionPass.h"
6 #include "llvm/CodeGen/MachineJumpTableInfo.h"
7 #include "llvm/CodeGen/Passes.h"
8 #include "llvm/CodeGen/TargetInstrInfo.h"
9 #include "llvm/InitializePasses.h"
10 
11 using namespace llvm;
12 
13 #define DEBUG_TYPE "gc-empty-basic-blocks"
14 
15 STATISTIC(NumEmptyBlocksRemoved, "Number of empty blocks removed");
16 
17 class GCEmptyBasicBlocks : public MachineFunctionPass {
18 public:
19   static char ID;
20 
21   GCEmptyBasicBlocks() : MachineFunctionPass(ID) {
22     initializeGCEmptyBasicBlocksPass(*PassRegistry::getPassRegistry());
23   }
24 
25   StringRef getPassName() const override {
26     return "Remove Empty Basic Blocks.";
27   }
28 
29   bool runOnMachineFunction(MachineFunction &MF) override;
30 };
31 
32 bool GCEmptyBasicBlocks::runOnMachineFunction(MachineFunction &MF) {
33   if (MF.size() < 2)
34     return false;
35   MachineJumpTableInfo *JTI = MF.getJumpTableInfo();
36   int NumRemoved = 0;
37 
38   // Iterate over all blocks except the last one. We can't remove the last block
39   // since it has no fallthrough block to rewire its predecessors to.
40   for (MachineFunction::iterator MBB = MF.begin(),
41                                  LastMBB = MachineFunction::iterator(MF.back()),
42                                  NextMBB;
43        MBB != LastMBB; MBB = NextMBB) {
44     NextMBB = std::next(MBB);
45     // TODO If a block is an eh pad, or it has address taken, we don't remove
46     // it. Removing such blocks is possible, but it probably requires a more
47     // complex logic.
48     if (MBB->isEHPad() || MBB->isMachineBlockAddressTaken())
49       continue;
50     // Skip blocks with real code.
51     bool HasAnyRealCode = llvm::any_of(*MBB, [](const MachineInstr &MI) {
52       return !MI.isPosition() && !MI.isImplicitDef() && !MI.isKill() &&
53              !MI.isDebugInstr();
54     });
55     if (HasAnyRealCode)
56       continue;
57 
58     LLVM_DEBUG(dbgs() << "Removing basic block " << MBB->getName()
59                       << " in function " << MF.getName() << ":\n"
60                       << *MBB << "\n");
61     SmallVector<MachineBasicBlock *, 8> Preds(MBB->predecessors());
62     // Rewire the predecessors of this block to use the next block.
63     for (auto &Pred : Preds)
64       Pred->ReplaceUsesOfBlockWith(&*MBB, &*NextMBB);
65     // Update the jump tables.
66     if (JTI)
67       JTI->ReplaceMBBInJumpTables(&*MBB, &*NextMBB);
68     // Remove this block from predecessors of all its successors.
69     while (!MBB->succ_empty())
70       MBB->removeSuccessor(MBB->succ_end() - 1);
71     // Finally, remove the block from the function.
72     MBB->eraseFromParent();
73     ++NumRemoved;
74   }
75   NumEmptyBlocksRemoved += NumRemoved;
76   return NumRemoved != 0;
77 }
78 
79 char GCEmptyBasicBlocks::ID = 0;
80 INITIALIZE_PASS(GCEmptyBasicBlocks, "gc-empty-basic-blocks",
81                 "Removes empty basic blocks and redirects their uses to their "
82                 "fallthrough blocks.",
83                 false, false)
84 
85 MachineFunctionPass *llvm::createGCEmptyBasicBlocksPass() {
86   return new GCEmptyBasicBlocks();
87 }
88