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