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