1 //===-- UnreachableBlockElim.cpp - Remove unreachable blocks for codegen --===// 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 // This pass is an extremely simple version of the SimplifyCFG pass. Its sole 10 // job is to delete LLVM basic blocks that are not reachable from the entry 11 // node. To do this, it performs a simple depth first traversal of the CFG, 12 // then deletes any unvisited nodes. 13 // 14 // Note that this pass is really a hack. In particular, the instruction 15 // selectors for various targets should just not generate code for unreachable 16 // blocks. Until LLVM has a more systematic way of defining instruction 17 // selectors, however, we cannot really expect them to handle additional 18 // complexity. 19 // 20 //===----------------------------------------------------------------------===// 21 22 #include "llvm/CodeGen/UnreachableBlockElim.h" 23 #include "llvm/ADT/DepthFirstIterator.h" 24 #include "llvm/ADT/SmallPtrSet.h" 25 #include "llvm/CodeGen/MachineDominators.h" 26 #include "llvm/CodeGen/MachineFunctionPass.h" 27 #include "llvm/CodeGen/MachineInstrBuilder.h" 28 #include "llvm/CodeGen/MachineLoopInfo.h" 29 #include "llvm/CodeGen/MachineModuleInfo.h" 30 #include "llvm/CodeGen/MachineRegisterInfo.h" 31 #include "llvm/CodeGen/Passes.h" 32 #include "llvm/CodeGen/TargetInstrInfo.h" 33 #include "llvm/IR/CFG.h" 34 #include "llvm/IR/Constant.h" 35 #include "llvm/IR/Dominators.h" 36 #include "llvm/IR/Function.h" 37 #include "llvm/IR/Instructions.h" 38 #include "llvm/IR/Type.h" 39 #include "llvm/Pass.h" 40 using namespace llvm; 41 42 static bool eliminateUnreachableBlock(Function &F) { 43 df_iterator_default_set<BasicBlock*> Reachable; 44 45 // Mark all reachable blocks. 46 for (BasicBlock *BB : depth_first_ext(&F, Reachable)) 47 (void)BB/* Mark all reachable blocks */; 48 49 // Loop over all dead blocks, remembering them and deleting all instructions 50 // in them. 51 std::vector<BasicBlock*> DeadBlocks; 52 for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) 53 if (!Reachable.count(&*I)) { 54 BasicBlock *BB = &*I; 55 DeadBlocks.push_back(BB); 56 while (PHINode *PN = dyn_cast<PHINode>(BB->begin())) { 57 PN->replaceAllUsesWith(Constant::getNullValue(PN->getType())); 58 BB->getInstList().pop_front(); 59 } 60 for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI) 61 (*SI)->removePredecessor(BB); 62 BB->dropAllReferences(); 63 } 64 65 // Actually remove the blocks now. 66 for (unsigned i = 0, e = DeadBlocks.size(); i != e; ++i) { 67 DeadBlocks[i]->eraseFromParent(); 68 } 69 70 return !DeadBlocks.empty(); 71 } 72 73 namespace { 74 class UnreachableBlockElimLegacyPass : public FunctionPass { 75 bool runOnFunction(Function &F) override { 76 return eliminateUnreachableBlock(F); 77 } 78 79 public: 80 static char ID; // Pass identification, replacement for typeid 81 UnreachableBlockElimLegacyPass() : FunctionPass(ID) { 82 initializeUnreachableBlockElimLegacyPassPass( 83 *PassRegistry::getPassRegistry()); 84 } 85 86 void getAnalysisUsage(AnalysisUsage &AU) const override { 87 AU.addPreserved<DominatorTreeWrapperPass>(); 88 } 89 }; 90 } 91 char UnreachableBlockElimLegacyPass::ID = 0; 92 INITIALIZE_PASS(UnreachableBlockElimLegacyPass, "unreachableblockelim", 93 "Remove unreachable blocks from the CFG", false, false) 94 95 FunctionPass *llvm::createUnreachableBlockEliminationPass() { 96 return new UnreachableBlockElimLegacyPass(); 97 } 98 99 PreservedAnalyses UnreachableBlockElimPass::run(Function &F, 100 FunctionAnalysisManager &AM) { 101 bool Changed = eliminateUnreachableBlock(F); 102 if (!Changed) 103 return PreservedAnalyses::all(); 104 PreservedAnalyses PA; 105 PA.preserve<DominatorTreeAnalysis>(); 106 return PA; 107 } 108 109 namespace { 110 class UnreachableMachineBlockElim : public MachineFunctionPass { 111 bool runOnMachineFunction(MachineFunction &F) override; 112 void getAnalysisUsage(AnalysisUsage &AU) const override; 113 MachineModuleInfo *MMI; 114 public: 115 static char ID; // Pass identification, replacement for typeid 116 UnreachableMachineBlockElim() : MachineFunctionPass(ID) {} 117 }; 118 } 119 char UnreachableMachineBlockElim::ID = 0; 120 121 INITIALIZE_PASS(UnreachableMachineBlockElim, "unreachable-mbb-elimination", 122 "Remove unreachable machine basic blocks", false, false) 123 124 char &llvm::UnreachableMachineBlockElimID = UnreachableMachineBlockElim::ID; 125 126 void UnreachableMachineBlockElim::getAnalysisUsage(AnalysisUsage &AU) const { 127 AU.addPreserved<MachineLoopInfo>(); 128 AU.addPreserved<MachineDominatorTree>(); 129 MachineFunctionPass::getAnalysisUsage(AU); 130 } 131 132 bool UnreachableMachineBlockElim::runOnMachineFunction(MachineFunction &F) { 133 df_iterator_default_set<MachineBasicBlock*> Reachable; 134 bool ModifiedPHI = false; 135 136 MMI = getAnalysisIfAvailable<MachineModuleInfo>(); 137 MachineDominatorTree *MDT = getAnalysisIfAvailable<MachineDominatorTree>(); 138 MachineLoopInfo *MLI = getAnalysisIfAvailable<MachineLoopInfo>(); 139 140 // Mark all reachable blocks. 141 for (MachineBasicBlock *BB : depth_first_ext(&F, Reachable)) 142 (void)BB/* Mark all reachable blocks */; 143 144 // Loop over all dead blocks, remembering them and deleting all instructions 145 // in them. 146 std::vector<MachineBasicBlock*> DeadBlocks; 147 for (MachineFunction::iterator I = F.begin(), E = F.end(); I != E; ++I) { 148 MachineBasicBlock *BB = &*I; 149 150 // Test for deadness. 151 if (!Reachable.count(BB)) { 152 DeadBlocks.push_back(BB); 153 154 // Update dominator and loop info. 155 if (MLI) MLI->removeBlock(BB); 156 if (MDT && MDT->getNode(BB)) MDT->eraseNode(BB); 157 158 while (BB->succ_begin() != BB->succ_end()) { 159 MachineBasicBlock* succ = *BB->succ_begin(); 160 161 MachineBasicBlock::iterator start = succ->begin(); 162 while (start != succ->end() && start->isPHI()) { 163 for (unsigned i = start->getNumOperands() - 1; i >= 2; i-=2) 164 if (start->getOperand(i).isMBB() && 165 start->getOperand(i).getMBB() == BB) { 166 start->RemoveOperand(i); 167 start->RemoveOperand(i-1); 168 } 169 170 start++; 171 } 172 173 BB->removeSuccessor(BB->succ_begin()); 174 } 175 } 176 } 177 178 // Actually remove the blocks now. 179 for (unsigned i = 0, e = DeadBlocks.size(); i != e; ++i) 180 DeadBlocks[i]->eraseFromParent(); 181 182 // Cleanup PHI nodes. 183 for (MachineFunction::iterator I = F.begin(), E = F.end(); I != E; ++I) { 184 MachineBasicBlock *BB = &*I; 185 // Prune unneeded PHI entries. 186 SmallPtrSet<MachineBasicBlock*, 8> preds(BB->pred_begin(), 187 BB->pred_end()); 188 MachineBasicBlock::iterator phi = BB->begin(); 189 while (phi != BB->end() && phi->isPHI()) { 190 for (unsigned i = phi->getNumOperands() - 1; i >= 2; i-=2) 191 if (!preds.count(phi->getOperand(i).getMBB())) { 192 phi->RemoveOperand(i); 193 phi->RemoveOperand(i-1); 194 ModifiedPHI = true; 195 } 196 197 if (phi->getNumOperands() == 3) { 198 const MachineOperand &Input = phi->getOperand(1); 199 const MachineOperand &Output = phi->getOperand(0); 200 unsigned InputReg = Input.getReg(); 201 unsigned OutputReg = Output.getReg(); 202 assert(Output.getSubReg() == 0 && "Cannot have output subregister"); 203 ModifiedPHI = true; 204 205 if (InputReg != OutputReg) { 206 MachineRegisterInfo &MRI = F.getRegInfo(); 207 unsigned InputSub = Input.getSubReg(); 208 if (InputSub == 0 && 209 MRI.constrainRegClass(InputReg, MRI.getRegClass(OutputReg)) && 210 !Input.isUndef()) { 211 MRI.replaceRegWith(OutputReg, InputReg); 212 } else { 213 // The input register to the PHI has a subregister or it can't be 214 // constrained to the proper register class or it is undef: 215 // insert a COPY instead of simply replacing the output 216 // with the input. 217 const TargetInstrInfo *TII = F.getSubtarget().getInstrInfo(); 218 BuildMI(*BB, BB->getFirstNonPHI(), phi->getDebugLoc(), 219 TII->get(TargetOpcode::COPY), OutputReg) 220 .addReg(InputReg, getRegState(Input), InputSub); 221 } 222 phi++->eraseFromParent(); 223 } 224 continue; 225 } 226 227 ++phi; 228 } 229 } 230 231 F.RenumberBlocks(); 232 233 return (!DeadBlocks.empty() || ModifiedPHI); 234 } 235