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" 22 23 using namespace llvm; 24 25 #define DEBUG_TYPE "gc-empty-basic-blocks" 26 27 STATISTIC(NumEmptyBlocksRemoved, "Number of empty blocks removed"); 28 29 class GCEmptyBasicBlocks : public MachineFunctionPass { 30 public: 31 static char ID; 32 33 GCEmptyBasicBlocks() : MachineFunctionPass(ID) { 34 initializeGCEmptyBasicBlocksPass(*PassRegistry::getPassRegistry()); 35 } 36 37 StringRef getPassName() const override { 38 return "Remove Empty Basic Blocks."; 39 } 40 41 bool runOnMachineFunction(MachineFunction &MF) override; 42 }; 43 44 bool GCEmptyBasicBlocks::runOnMachineFunction(MachineFunction &MF) { 45 if (MF.size() < 2) 46 return false; 47 MachineJumpTableInfo *JTI = MF.getJumpTableInfo(); 48 int NumRemoved = 0; 49 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; 69 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; 86 } 87 NumEmptyBlocksRemoved += NumRemoved; 88 return NumRemoved != 0; 89 } 90 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) 96 97 MachineFunctionPass *llvm::createGCEmptyBasicBlocksPass() { 98 return new GCEmptyBasicBlocks(); 99 } 100