LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UnreachableBlockElim.cpp
Go to the documentation of this file.
1 //===-- UnreachableBlockElim.cpp - Remove unreachable blocks for codegen --===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This pass is an extremely simple version of the SimplifyCFG pass. Its sole
11 // job is to delete LLVM basic blocks that are not reachable from the entry
12 // node. To do this, it performs a simple depth first traversal of the CFG,
13 // then deletes any unvisited nodes.
14 //
15 // Note that this pass is really a hack. In particular, the instruction
16 // selectors for various targets should just not generate code for unreachable
17 // blocks. Until LLVM has a more systematic way of defining instruction
18 // selectors, however, we cannot really expect them to handle additional
19 // complexity.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 #include "llvm/CodeGen/Passes.h"
25 #include "llvm/ADT/SmallPtrSet.h"
32 #include "llvm/IR/Constant.h"
33 #include "llvm/IR/Function.h"
34 #include "llvm/IR/Instructions.h"
35 #include "llvm/IR/Type.h"
36 #include "llvm/Pass.h"
37 #include "llvm/Support/CFG.h"
39 using namespace llvm;
40 
41 namespace {
42  class UnreachableBlockElim : public FunctionPass {
43  virtual bool runOnFunction(Function &F);
44  public:
45  static char ID; // Pass identification, replacement for typeid
46  UnreachableBlockElim() : FunctionPass(ID) {
48  }
49 
50  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
52  }
53  };
54 }
56 INITIALIZE_PASS(UnreachableBlockElim, "unreachableblockelim",
57  "Remove unreachable blocks from the CFG", false, false)
58 
60  return new UnreachableBlockElim();
61 }
62 
63 bool UnreachableBlockElim::runOnFunction(Function &F) {
65 
66  // Mark all reachable blocks.
68  df_ext_begin(&F, Reachable), E = df_ext_end(&F, Reachable); I != E; ++I)
69  /* Mark all reachable blocks */;
70 
71  // Loop over all dead blocks, remembering them and deleting all instructions
72  // in them.
73  std::vector<BasicBlock*> DeadBlocks;
74  for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
75  if (!Reachable.count(I)) {
76  BasicBlock *BB = I;
77  DeadBlocks.push_back(BB);
78  while (PHINode *PN = dyn_cast<PHINode>(BB->begin())) {
79  PN->replaceAllUsesWith(Constant::getNullValue(PN->getType()));
80  BB->getInstList().pop_front();
81  }
82  for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI)
83  (*SI)->removePredecessor(BB);
84  BB->dropAllReferences();
85  }
86 
87  // Actually remove the blocks now.
88  for (unsigned i = 0, e = DeadBlocks.size(); i != e; ++i) {
89  DeadBlocks[i]->eraseFromParent();
90  }
91 
92  return DeadBlocks.size();
93 }
94 
95 
96 namespace {
97  class UnreachableMachineBlockElim : public MachineFunctionPass {
98  virtual bool runOnMachineFunction(MachineFunction &F);
99  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
100  MachineModuleInfo *MMI;
101  public:
102  static char ID; // Pass identification, replacement for typeid
103  UnreachableMachineBlockElim() : MachineFunctionPass(ID) {}
104  };
105 }
107 
108 INITIALIZE_PASS(UnreachableMachineBlockElim, "unreachable-mbb-elimination",
109  "Remove unreachable machine basic blocks", false, false)
110 
111 char &llvm::UnreachableMachineBlockElimID = UnreachableMachineBlockElim::ID;
112 
113 void UnreachableMachineBlockElim::getAnalysisUsage(AnalysisUsage &AU) const {
114  AU.addPreserved<MachineLoopInfo>();
115  AU.addPreserved<MachineDominatorTree>();
117 }
118 
119 bool UnreachableMachineBlockElim::runOnMachineFunction(MachineFunction &F) {
121  bool ModifiedPHI = false;
122 
123  MMI = getAnalysisIfAvailable<MachineModuleInfo>();
124  MachineDominatorTree *MDT = getAnalysisIfAvailable<MachineDominatorTree>();
125  MachineLoopInfo *MLI = getAnalysisIfAvailable<MachineLoopInfo>();
126 
127  // Mark all reachable blocks.
129  I = df_ext_begin(&F, Reachable), E = df_ext_end(&F, Reachable);
130  I != E; ++I)
131  /* Mark all reachable blocks */;
132 
133  // Loop over all dead blocks, remembering them and deleting all instructions
134  // in them.
135  std::vector<MachineBasicBlock*> DeadBlocks;
136  for (MachineFunction::iterator I = F.begin(), E = F.end(); I != E; ++I) {
137  MachineBasicBlock *BB = I;
138 
139  // Test for deadness.
140  if (!Reachable.count(BB)) {
141  DeadBlocks.push_back(BB);
142 
143  // Update dominator and loop info.
144  if (MLI) MLI->removeBlock(BB);
145  if (MDT && MDT->getNode(BB)) MDT->eraseNode(BB);
146 
147  while (BB->succ_begin() != BB->succ_end()) {
148  MachineBasicBlock* succ = *BB->succ_begin();
149 
150  MachineBasicBlock::iterator start = succ->begin();
151  while (start != succ->end() && start->isPHI()) {
152  for (unsigned i = start->getNumOperands() - 1; i >= 2; i-=2)
153  if (start->getOperand(i).isMBB() &&
154  start->getOperand(i).getMBB() == BB) {
155  start->RemoveOperand(i);
156  start->RemoveOperand(i-1);
157  }
158 
159  start++;
160  }
161 
162  BB->removeSuccessor(BB->succ_begin());
163  }
164  }
165  }
166 
167  // Actually remove the blocks now.
168  for (unsigned i = 0, e = DeadBlocks.size(); i != e; ++i)
169  DeadBlocks[i]->eraseFromParent();
170 
171  // Cleanup PHI nodes.
172  for (MachineFunction::iterator I = F.begin(), E = F.end(); I != E; ++I) {
173  MachineBasicBlock *BB = I;
174  // Prune unneeded PHI entries.
176  BB->pred_end());
178  while (phi != BB->end() && phi->isPHI()) {
179  for (unsigned i = phi->getNumOperands() - 1; i >= 2; i-=2)
180  if (!preds.count(phi->getOperand(i).getMBB())) {
181  phi->RemoveOperand(i);
182  phi->RemoveOperand(i-1);
183  ModifiedPHI = true;
184  }
185 
186  if (phi->getNumOperands() == 3) {
187  unsigned Input = phi->getOperand(1).getReg();
188  unsigned Output = phi->getOperand(0).getReg();
189 
190  MachineInstr* temp = phi;
191  ++phi;
192  temp->eraseFromParent();
193  ModifiedPHI = true;
194 
195  if (Input != Output) {
197  MRI.constrainRegClass(Input, MRI.getRegClass(Output));
198  MRI.replaceRegWith(Output, Input);
199  }
200 
201  continue;
202  }
203 
204  ++phi;
205  }
206  }
207 
208  F.RenumberBlocks();
209 
210  return (DeadBlocks.size() || ModifiedPHI);
211 }
AnalysisUsage & addPreserved()
static PassRegistry * getPassRegistry()
iterator end()
Definition: Function.h:397
F(f)
static Constant * getNullValue(Type *Ty)
Definition: Constants.cpp:111
iterator begin()
Definition: BasicBlock.h:193
const TargetRegisterClass * getRegClass(unsigned Reg) const
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
Interval::succ_iterator succ_begin(Interval *I)
Definition: Interval.h:107
char & UnreachableMachineBlockElimID
bool count(PtrType Ptr) const
count - Return true if the specified pointer is in the set.
Definition: SmallPtrSet.h:264
void RenumberBlocks(MachineBasicBlock *MBBFrom=0)
FunctionPass * createUnreachableBlockEliminationPass()
iterator begin()
Definition: Function.h:395
const TargetRegisterClass * constrainRegClass(unsigned Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
Interval::succ_iterator succ_end(Interval *I)
Definition: Interval.h:110
bundle_iterator< MachineInstr, instr_iterator > iterator
LLVM Basic Block Representation.
Definition: BasicBlock.h:72
df_ext_iterator< T, SetTy > df_ext_end(const T &G, SetTy &S)
df_ext_iterator< T, SetTy > df_ext_begin(const T &G, SetTy &S)
const InstListType & getInstList() const
Return the underlying instruction list container.
Definition: BasicBlock.h:214
void initializeUnreachableBlockElimPass(PassRegistry &)
void removeSuccessor(MachineBasicBlock *succ)
INITIALIZE_PASS(UnreachableBlockElim,"unreachableblockelim","Remove unreachable blocks from the CFG", false, false) FunctionPass *llvm
void replaceRegWith(unsigned FromReg, unsigned ToReg)
MachineRegisterInfo & getRegInfo()
virtual void getAnalysisUsage(AnalysisUsage &AU) const
#define I(x, y, z)
Definition: MD5.cpp:54
void pop_front()
Definition: ilist.h:555
BasicBlockListType::iterator iterator
const MCRegisterInfo & MRI
void dropAllReferences()
Cause all subinstructions to "let go" of all the references that said subinstructions are maintaining...
Definition: BasicBlock.cpp:176