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