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