UnreachableBlockElim.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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. #include "llvm/CodeGen/UnreachableBlockElim.h"
  22. #include "llvm/ADT/DepthFirstIterator.h"
  23. #include "llvm/ADT/SmallPtrSet.h"
  24. #include "llvm/CodeGen/MachineDominators.h"
  25. #include "llvm/CodeGen/MachineFunctionPass.h"
  26. #include "llvm/CodeGen/MachineInstrBuilder.h"
  27. #include "llvm/CodeGen/MachineLoopInfo.h"
  28. #include "llvm/CodeGen/MachineModuleInfo.h"
  29. #include "llvm/CodeGen/MachineRegisterInfo.h"
  30. #include "llvm/CodeGen/Passes.h"
  31. #include "llvm/CodeGen/TargetInstrInfo.h"
  32. #include "llvm/IR/CFG.h"
  33. #include "llvm/IR/Constant.h"
  34. #include "llvm/IR/Dominators.h"
  35. #include "llvm/IR/Function.h"
  36. #include "llvm/IR/Instructions.h"
  37. #include "llvm/IR/Type.h"
  38. #include "llvm/InitializePasses.h"
  39. #include "llvm/Pass.h"
  40. #include "llvm/Transforms/Utils/BasicBlockUtils.h"
  41. using namespace llvm;
  42. namespace {
  43. class UnreachableBlockElimLegacyPass : public FunctionPass {
  44. bool runOnFunction(Function &F) override {
  45. return llvm::EliminateUnreachableBlocks(F);
  46. }
  47. public:
  48. static char ID; // Pass identification, replacement for typeid
  49. UnreachableBlockElimLegacyPass() : FunctionPass(ID) {
  50. initializeUnreachableBlockElimLegacyPassPass(
  51. *PassRegistry::getPassRegistry());
  52. }
  53. void getAnalysisUsage(AnalysisUsage &AU) const override {
  54. AU.addPreserved<DominatorTreeWrapperPass>();
  55. }
  56. };
  57. }
  58. char UnreachableBlockElimLegacyPass::ID = 0;
  59. INITIALIZE_PASS(UnreachableBlockElimLegacyPass, "unreachableblockelim",
  60. "Remove unreachable blocks from the CFG", false, false)
  61. FunctionPass *llvm::createUnreachableBlockEliminationPass() {
  62. return new UnreachableBlockElimLegacyPass();
  63. }
  64. PreservedAnalyses UnreachableBlockElimPass::run(Function &F,
  65. FunctionAnalysisManager &AM) {
  66. bool Changed = llvm::EliminateUnreachableBlocks(F);
  67. if (!Changed)
  68. return PreservedAnalyses::all();
  69. PreservedAnalyses PA;
  70. PA.preserve<DominatorTreeAnalysis>();
  71. return PA;
  72. }
  73. namespace {
  74. class UnreachableMachineBlockElim : public MachineFunctionPass {
  75. bool runOnMachineFunction(MachineFunction &F) override;
  76. void getAnalysisUsage(AnalysisUsage &AU) const override;
  77. public:
  78. static char ID; // Pass identification, replacement for typeid
  79. UnreachableMachineBlockElim() : MachineFunctionPass(ID) {}
  80. };
  81. }
  82. char UnreachableMachineBlockElim::ID = 0;
  83. INITIALIZE_PASS(UnreachableMachineBlockElim, "unreachable-mbb-elimination",
  84. "Remove unreachable machine basic blocks", false, false)
  85. char &llvm::UnreachableMachineBlockElimID = UnreachableMachineBlockElim::ID;
  86. void UnreachableMachineBlockElim::getAnalysisUsage(AnalysisUsage &AU) const {
  87. AU.addPreserved<MachineLoopInfo>();
  88. AU.addPreserved<MachineDominatorTree>();
  89. MachineFunctionPass::getAnalysisUsage(AU);
  90. }
  91. bool UnreachableMachineBlockElim::runOnMachineFunction(MachineFunction &F) {
  92. df_iterator_default_set<MachineBasicBlock*> Reachable;
  93. bool ModifiedPHI = false;
  94. MachineDominatorTree *MDT = getAnalysisIfAvailable<MachineDominatorTree>();
  95. MachineLoopInfo *MLI = getAnalysisIfAvailable<MachineLoopInfo>();
  96. // Mark all reachable blocks.
  97. for (MachineBasicBlock *BB : depth_first_ext(&F, Reachable))
  98. (void)BB/* Mark all reachable blocks */;
  99. // Loop over all dead blocks, remembering them and deleting all instructions
  100. // in them.
  101. std::vector<MachineBasicBlock*> DeadBlocks;
  102. for (MachineBasicBlock &BB : F) {
  103. // Test for deadness.
  104. if (!Reachable.count(&BB)) {
  105. DeadBlocks.push_back(&BB);
  106. // Update dominator and loop info.
  107. if (MLI) MLI->removeBlock(&BB);
  108. if (MDT && MDT->getNode(&BB)) MDT->eraseNode(&BB);
  109. while (BB.succ_begin() != BB.succ_end()) {
  110. MachineBasicBlock* succ = *BB.succ_begin();
  111. MachineBasicBlock::iterator start = succ->begin();
  112. while (start != succ->end() && start->isPHI()) {
  113. for (unsigned i = start->getNumOperands() - 1; i >= 2; i-=2)
  114. if (start->getOperand(i).isMBB() &&
  115. start->getOperand(i).getMBB() == &BB) {
  116. start->RemoveOperand(i);
  117. start->RemoveOperand(i-1);
  118. }
  119. start++;
  120. }
  121. BB.removeSuccessor(BB.succ_begin());
  122. }
  123. }
  124. }
  125. // Actually remove the blocks now.
  126. for (MachineBasicBlock *BB : DeadBlocks) {
  127. // Remove any call site information for calls in the block.
  128. for (auto &I : BB->instrs())
  129. if (I.shouldUpdateCallSiteInfo())
  130. BB->getParent()->eraseCallSiteInfo(&I);
  131. BB->eraseFromParent();
  132. }
  133. // Cleanup PHI nodes.
  134. for (MachineBasicBlock &BB : F) {
  135. // Prune unneeded PHI entries.
  136. SmallPtrSet<MachineBasicBlock*, 8> preds(BB.pred_begin(),
  137. BB.pred_end());
  138. MachineBasicBlock::iterator phi = BB.begin();
  139. while (phi != BB.end() && phi->isPHI()) {
  140. for (unsigned i = phi->getNumOperands() - 1; i >= 2; i-=2)
  141. if (!preds.count(phi->getOperand(i).getMBB())) {
  142. phi->RemoveOperand(i);
  143. phi->RemoveOperand(i-1);
  144. ModifiedPHI = true;
  145. }
  146. if (phi->getNumOperands() == 3) {
  147. const MachineOperand &Input = phi->getOperand(1);
  148. const MachineOperand &Output = phi->getOperand(0);
  149. Register InputReg = Input.getReg();
  150. Register OutputReg = Output.getReg();
  151. assert(Output.getSubReg() == 0 && "Cannot have output subregister");
  152. ModifiedPHI = true;
  153. if (InputReg != OutputReg) {
  154. MachineRegisterInfo &MRI = F.getRegInfo();
  155. unsigned InputSub = Input.getSubReg();
  156. if (InputSub == 0 &&
  157. MRI.constrainRegClass(InputReg, MRI.getRegClass(OutputReg)) &&
  158. !Input.isUndef()) {
  159. MRI.replaceRegWith(OutputReg, InputReg);
  160. } else {
  161. // The input register to the PHI has a subregister or it can't be
  162. // constrained to the proper register class or it is undef:
  163. // insert a COPY instead of simply replacing the output
  164. // with the input.
  165. const TargetInstrInfo *TII = F.getSubtarget().getInstrInfo();
  166. BuildMI(BB, BB.getFirstNonPHI(), phi->getDebugLoc(),
  167. TII->get(TargetOpcode::COPY), OutputReg)
  168. .addReg(InputReg, getRegState(Input), InputSub);
  169. }
  170. phi++->eraseFromParent();
  171. }
  172. continue;
  173. }
  174. ++phi;
  175. }
  176. }
  177. F.RenumberBlocks();
  178. return (!DeadBlocks.empty() || ModifiedPHI);
  179. }