xref: /openbsd-src/gnu/llvm/llvm/lib/CodeGen/UnreachableBlockElim.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===-- UnreachableBlockElim.cpp - Remove unreachable blocks for codegen --===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This pass is an extremely simple version of the SimplifyCFG pass.  Its sole
1009467b48Spatrick // job is to delete LLVM basic blocks that are not reachable from the entry
1109467b48Spatrick // node.  To do this, it performs a simple depth first traversal of the CFG,
1209467b48Spatrick // then deletes any unvisited nodes.
1309467b48Spatrick //
1409467b48Spatrick // Note that this pass is really a hack.  In particular, the instruction
1509467b48Spatrick // selectors for various targets should just not generate code for unreachable
1609467b48Spatrick // blocks.  Until LLVM has a more systematic way of defining instruction
1709467b48Spatrick // selectors, however, we cannot really expect them to handle additional
1809467b48Spatrick // complexity.
1909467b48Spatrick //
2009467b48Spatrick //===----------------------------------------------------------------------===//
2109467b48Spatrick 
2209467b48Spatrick #include "llvm/CodeGen/UnreachableBlockElim.h"
2309467b48Spatrick #include "llvm/ADT/DepthFirstIterator.h"
2409467b48Spatrick #include "llvm/ADT/SmallPtrSet.h"
2509467b48Spatrick #include "llvm/CodeGen/MachineDominators.h"
2609467b48Spatrick #include "llvm/CodeGen/MachineFunctionPass.h"
2709467b48Spatrick #include "llvm/CodeGen/MachineInstrBuilder.h"
2809467b48Spatrick #include "llvm/CodeGen/MachineLoopInfo.h"
2909467b48Spatrick #include "llvm/CodeGen/MachineRegisterInfo.h"
3009467b48Spatrick #include "llvm/CodeGen/Passes.h"
3109467b48Spatrick #include "llvm/CodeGen/TargetInstrInfo.h"
3209467b48Spatrick #include "llvm/IR/Dominators.h"
3309467b48Spatrick #include "llvm/InitializePasses.h"
3409467b48Spatrick #include "llvm/Pass.h"
3509467b48Spatrick #include "llvm/Transforms/Utils/BasicBlockUtils.h"
3609467b48Spatrick using namespace llvm;
3709467b48Spatrick 
3809467b48Spatrick namespace {
3909467b48Spatrick class UnreachableBlockElimLegacyPass : public FunctionPass {
runOnFunction(Function & F)4009467b48Spatrick   bool runOnFunction(Function &F) override {
4109467b48Spatrick     return llvm::EliminateUnreachableBlocks(F);
4209467b48Spatrick   }
4309467b48Spatrick 
4409467b48Spatrick public:
4509467b48Spatrick   static char ID; // Pass identification, replacement for typeid
UnreachableBlockElimLegacyPass()4609467b48Spatrick   UnreachableBlockElimLegacyPass() : FunctionPass(ID) {
4709467b48Spatrick     initializeUnreachableBlockElimLegacyPassPass(
4809467b48Spatrick         *PassRegistry::getPassRegistry());
4909467b48Spatrick   }
5009467b48Spatrick 
getAnalysisUsage(AnalysisUsage & AU) const5109467b48Spatrick   void getAnalysisUsage(AnalysisUsage &AU) const override {
5209467b48Spatrick     AU.addPreserved<DominatorTreeWrapperPass>();
5309467b48Spatrick   }
5409467b48Spatrick };
5509467b48Spatrick }
5609467b48Spatrick char UnreachableBlockElimLegacyPass::ID = 0;
5709467b48Spatrick INITIALIZE_PASS(UnreachableBlockElimLegacyPass, "unreachableblockelim",
5809467b48Spatrick                 "Remove unreachable blocks from the CFG", false, false)
5909467b48Spatrick 
createUnreachableBlockEliminationPass()6009467b48Spatrick FunctionPass *llvm::createUnreachableBlockEliminationPass() {
6109467b48Spatrick   return new UnreachableBlockElimLegacyPass();
6209467b48Spatrick }
6309467b48Spatrick 
run(Function & F,FunctionAnalysisManager & AM)6409467b48Spatrick PreservedAnalyses UnreachableBlockElimPass::run(Function &F,
6509467b48Spatrick                                                 FunctionAnalysisManager &AM) {
6609467b48Spatrick   bool Changed = llvm::EliminateUnreachableBlocks(F);
6709467b48Spatrick   if (!Changed)
6809467b48Spatrick     return PreservedAnalyses::all();
6909467b48Spatrick   PreservedAnalyses PA;
7009467b48Spatrick   PA.preserve<DominatorTreeAnalysis>();
7109467b48Spatrick   return PA;
7209467b48Spatrick }
7309467b48Spatrick 
7409467b48Spatrick namespace {
7509467b48Spatrick   class UnreachableMachineBlockElim : public MachineFunctionPass {
7609467b48Spatrick     bool runOnMachineFunction(MachineFunction &F) override;
7709467b48Spatrick     void getAnalysisUsage(AnalysisUsage &AU) const override;
78097a140dSpatrick 
7909467b48Spatrick   public:
8009467b48Spatrick     static char ID; // Pass identification, replacement for typeid
UnreachableMachineBlockElim()8109467b48Spatrick     UnreachableMachineBlockElim() : MachineFunctionPass(ID) {}
8209467b48Spatrick   };
8309467b48Spatrick }
8409467b48Spatrick char UnreachableMachineBlockElim::ID = 0;
8509467b48Spatrick 
8609467b48Spatrick INITIALIZE_PASS(UnreachableMachineBlockElim, "unreachable-mbb-elimination",
8709467b48Spatrick   "Remove unreachable machine basic blocks", false, false)
8809467b48Spatrick 
8909467b48Spatrick char &llvm::UnreachableMachineBlockElimID = UnreachableMachineBlockElim::ID;
9009467b48Spatrick 
getAnalysisUsage(AnalysisUsage & AU) const9109467b48Spatrick void UnreachableMachineBlockElim::getAnalysisUsage(AnalysisUsage &AU) const {
9209467b48Spatrick   AU.addPreserved<MachineLoopInfo>();
9309467b48Spatrick   AU.addPreserved<MachineDominatorTree>();
9409467b48Spatrick   MachineFunctionPass::getAnalysisUsage(AU);
9509467b48Spatrick }
9609467b48Spatrick 
runOnMachineFunction(MachineFunction & F)9709467b48Spatrick bool UnreachableMachineBlockElim::runOnMachineFunction(MachineFunction &F) {
9809467b48Spatrick   df_iterator_default_set<MachineBasicBlock*> Reachable;
9909467b48Spatrick   bool ModifiedPHI = false;
10009467b48Spatrick 
10109467b48Spatrick   MachineDominatorTree *MDT = getAnalysisIfAvailable<MachineDominatorTree>();
10209467b48Spatrick   MachineLoopInfo *MLI = getAnalysisIfAvailable<MachineLoopInfo>();
10309467b48Spatrick 
10409467b48Spatrick   // Mark all reachable blocks.
10509467b48Spatrick   for (MachineBasicBlock *BB : depth_first_ext(&F, Reachable))
10609467b48Spatrick     (void)BB/* Mark all reachable blocks */;
10709467b48Spatrick 
10809467b48Spatrick   // Loop over all dead blocks, remembering them and deleting all instructions
10909467b48Spatrick   // in them.
11009467b48Spatrick   std::vector<MachineBasicBlock*> DeadBlocks;
11173471bf0Spatrick   for (MachineBasicBlock &BB : F) {
11209467b48Spatrick     // Test for deadness.
11373471bf0Spatrick     if (!Reachable.count(&BB)) {
11473471bf0Spatrick       DeadBlocks.push_back(&BB);
11509467b48Spatrick 
11609467b48Spatrick       // Update dominator and loop info.
11773471bf0Spatrick       if (MLI) MLI->removeBlock(&BB);
11873471bf0Spatrick       if (MDT && MDT->getNode(&BB)) MDT->eraseNode(&BB);
11909467b48Spatrick 
12073471bf0Spatrick       while (BB.succ_begin() != BB.succ_end()) {
12173471bf0Spatrick         MachineBasicBlock* succ = *BB.succ_begin();
12209467b48Spatrick 
12309467b48Spatrick         MachineBasicBlock::iterator start = succ->begin();
12409467b48Spatrick         while (start != succ->end() && start->isPHI()) {
12509467b48Spatrick           for (unsigned i = start->getNumOperands() - 1; i >= 2; i-=2)
12609467b48Spatrick             if (start->getOperand(i).isMBB() &&
12773471bf0Spatrick                 start->getOperand(i).getMBB() == &BB) {
128*d415bd75Srobert               start->removeOperand(i);
129*d415bd75Srobert               start->removeOperand(i-1);
13009467b48Spatrick             }
13109467b48Spatrick 
13209467b48Spatrick           start++;
13309467b48Spatrick         }
13409467b48Spatrick 
13573471bf0Spatrick         BB.removeSuccessor(BB.succ_begin());
13609467b48Spatrick       }
13709467b48Spatrick     }
13809467b48Spatrick   }
13909467b48Spatrick 
14009467b48Spatrick   // Actually remove the blocks now.
141*d415bd75Srobert   for (MachineBasicBlock *BB : DeadBlocks) {
14209467b48Spatrick     // Remove any call site information for calls in the block.
143*d415bd75Srobert     for (auto &I : BB->instrs())
144097a140dSpatrick       if (I.shouldUpdateCallSiteInfo())
145*d415bd75Srobert         BB->getParent()->eraseCallSiteInfo(&I);
14609467b48Spatrick 
147*d415bd75Srobert     BB->eraseFromParent();
14809467b48Spatrick   }
14909467b48Spatrick 
15009467b48Spatrick   // Cleanup PHI nodes.
151*d415bd75Srobert   for (MachineBasicBlock &BB : F) {
15209467b48Spatrick     // Prune unneeded PHI entries.
153*d415bd75Srobert     SmallPtrSet<MachineBasicBlock*, 8> preds(BB.pred_begin(),
154*d415bd75Srobert                                              BB.pred_end());
155*d415bd75Srobert     MachineBasicBlock::iterator phi = BB.begin();
156*d415bd75Srobert     while (phi != BB.end() && phi->isPHI()) {
15709467b48Spatrick       for (unsigned i = phi->getNumOperands() - 1; i >= 2; i-=2)
15809467b48Spatrick         if (!preds.count(phi->getOperand(i).getMBB())) {
159*d415bd75Srobert           phi->removeOperand(i);
160*d415bd75Srobert           phi->removeOperand(i-1);
16109467b48Spatrick           ModifiedPHI = true;
16209467b48Spatrick         }
16309467b48Spatrick 
16409467b48Spatrick       if (phi->getNumOperands() == 3) {
16509467b48Spatrick         const MachineOperand &Input = phi->getOperand(1);
16609467b48Spatrick         const MachineOperand &Output = phi->getOperand(0);
16709467b48Spatrick         Register InputReg = Input.getReg();
16809467b48Spatrick         Register OutputReg = Output.getReg();
16909467b48Spatrick         assert(Output.getSubReg() == 0 && "Cannot have output subregister");
17009467b48Spatrick         ModifiedPHI = true;
17109467b48Spatrick 
17209467b48Spatrick         if (InputReg != OutputReg) {
17309467b48Spatrick           MachineRegisterInfo &MRI = F.getRegInfo();
17409467b48Spatrick           unsigned InputSub = Input.getSubReg();
17509467b48Spatrick           if (InputSub == 0 &&
17609467b48Spatrick               MRI.constrainRegClass(InputReg, MRI.getRegClass(OutputReg)) &&
17709467b48Spatrick               !Input.isUndef()) {
17809467b48Spatrick             MRI.replaceRegWith(OutputReg, InputReg);
17909467b48Spatrick           } else {
18009467b48Spatrick             // The input register to the PHI has a subregister or it can't be
18109467b48Spatrick             // constrained to the proper register class or it is undef:
18209467b48Spatrick             // insert a COPY instead of simply replacing the output
18309467b48Spatrick             // with the input.
18409467b48Spatrick             const TargetInstrInfo *TII = F.getSubtarget().getInstrInfo();
185*d415bd75Srobert             BuildMI(BB, BB.getFirstNonPHI(), phi->getDebugLoc(),
18609467b48Spatrick                     TII->get(TargetOpcode::COPY), OutputReg)
18709467b48Spatrick                 .addReg(InputReg, getRegState(Input), InputSub);
18809467b48Spatrick           }
18909467b48Spatrick           phi++->eraseFromParent();
19009467b48Spatrick         }
19109467b48Spatrick         continue;
19209467b48Spatrick       }
19309467b48Spatrick 
19409467b48Spatrick       ++phi;
19509467b48Spatrick     }
19609467b48Spatrick   }
19709467b48Spatrick 
19809467b48Spatrick   F.RenumberBlocks();
19909467b48Spatrick 
20009467b48Spatrick   return (!DeadBlocks.empty() || ModifiedPHI);
20109467b48Spatrick }
202