1 //===- Dominators.h - Dominator Info Calculation ----------------*- C++ -*-===// 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 file defines the DominatorTree class, which provides fast and efficient 11 // dominance queries. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_IR_DOMINATORS_H 16 #define LLVM_IR_DOMINATORS_H 17 18 #include "llvm/ADT/DenseMapInfo.h" 19 #include "llvm/ADT/GraphTraits.h" 20 #include "llvm/ADT/SmallPtrSet.h" 21 #include "llvm/IR/CFG.h" 22 #include "llvm/IR/PassManager.h" 23 #include "llvm/Pass.h" 24 #include "llvm/Support/GenericDomTree.h" 25 26 namespace llvm { 27 28 class Function; 29 class BasicBlock; 30 class raw_ostream; 31 32 extern template class DomTreeNodeBase<BasicBlock>; 33 extern template class DominatorTreeBase<BasicBlock>; 34 35 extern template void Calculate<Function, BasicBlock *>( 36 DominatorTreeBase<GraphTraits<BasicBlock *>::NodeType> &DT, Function &F); 37 extern template void Calculate<Function, Inverse<BasicBlock *>>( 38 DominatorTreeBase<GraphTraits<Inverse<BasicBlock *>>::NodeType> &DT, 39 Function &F); 40 41 typedef DomTreeNodeBase<BasicBlock> DomTreeNode; 42 43 class BasicBlockEdge { 44 const BasicBlock *Start; 45 const BasicBlock *End; 46 public: BasicBlockEdge(const BasicBlock * Start_,const BasicBlock * End_)47 BasicBlockEdge(const BasicBlock *Start_, const BasicBlock *End_) : 48 Start(Start_), End(End_) { } getStart()49 const BasicBlock *getStart() const { 50 return Start; 51 } getEnd()52 const BasicBlock *getEnd() const { 53 return End; 54 } 55 bool isSingleEdge() const; 56 }; 57 58 template <> struct DenseMapInfo<BasicBlockEdge> { 59 static unsigned getHashValue(const BasicBlockEdge *V); 60 typedef DenseMapInfo<const BasicBlock *> BBInfo; 61 static inline BasicBlockEdge getEmptyKey() { 62 return BasicBlockEdge(BBInfo::getEmptyKey(), BBInfo::getEmptyKey()); 63 } 64 static inline BasicBlockEdge getTombstoneKey() { 65 return BasicBlockEdge(BBInfo::getTombstoneKey(), BBInfo::getTombstoneKey()); 66 } 67 68 static unsigned getHashValue(const BasicBlockEdge &Edge) { 69 return hash_combine(BBInfo::getHashValue(Edge.getStart()), 70 BBInfo::getHashValue(Edge.getEnd())); 71 } 72 static bool isEqual(const BasicBlockEdge &LHS, const BasicBlockEdge &RHS) { 73 return BBInfo::isEqual(LHS.getStart(), RHS.getStart()) && 74 BBInfo::isEqual(LHS.getEnd(), RHS.getEnd()); 75 } 76 }; 77 78 /// \brief Concrete subclass of DominatorTreeBase that is used to compute a 79 /// normal dominator tree. 80 /// 81 /// Definition: A block is said to be forward statically reachable if there is 82 /// a path from the entry of the function to the block. A statically reachable 83 /// block may become statically unreachable during optimization. 84 /// 85 /// A forward unreachable block may appear in the dominator tree, or it may 86 /// not. If it does, dominance queries will return results as if all reachable 87 /// blocks dominate it. When asking for a Node corresponding to a potentially 88 /// unreachable block, calling code must handle the case where the block was 89 /// unreachable and the result of getNode() is nullptr. 90 /// 91 /// Generally, a block known to be unreachable when the dominator tree is 92 /// constructed will not be in the tree. One which becomes unreachable after 93 /// the dominator tree is initially constructed may still exist in the tree, 94 /// even if the tree is properly updated. Calling code should not rely on the 95 /// preceding statements; this is stated only to assist human understanding. 96 class DominatorTree : public DominatorTreeBase<BasicBlock> { 97 public: 98 typedef DominatorTreeBase<BasicBlock> Base; 99 100 DominatorTree() : DominatorTreeBase<BasicBlock>(false) {} 101 explicit DominatorTree(Function &F) : DominatorTreeBase<BasicBlock>(false) { 102 recalculate(F); 103 } 104 105 DominatorTree(DominatorTree &&Arg) 106 : Base(std::move(static_cast<Base &>(Arg))) {} 107 DominatorTree &operator=(DominatorTree &&RHS) { 108 Base::operator=(std::move(static_cast<Base &>(RHS))); 109 return *this; 110 } 111 112 /// \brief Returns *false* if the other dominator tree matches this dominator 113 /// tree. 114 inline bool compare(const DominatorTree &Other) const { 115 const DomTreeNode *R = getRootNode(); 116 const DomTreeNode *OtherR = Other.getRootNode(); 117 118 if (!R || !OtherR || R->getBlock() != OtherR->getBlock()) 119 return true; 120 121 if (Base::compare(Other)) 122 return true; 123 124 return false; 125 } 126 127 // Ensure base-class overloads are visible. 128 using Base::dominates; 129 130 /// \brief Return true if Def dominates a use in User. 131 /// 132 /// This performs the special checks necessary if Def and User are in the same 133 /// basic block. Note that Def doesn't dominate a use in Def itself! 134 bool dominates(const Instruction *Def, const Use &U) const; 135 bool dominates(const Instruction *Def, const Instruction *User) const; 136 bool dominates(const Instruction *Def, const BasicBlock *BB) const; 137 bool dominates(const BasicBlockEdge &BBE, const Use &U) const; 138 bool dominates(const BasicBlockEdge &BBE, const BasicBlock *BB) const; 139 140 // Ensure base class overloads are visible. 141 using Base::isReachableFromEntry; 142 143 /// \brief Provide an overload for a Use. 144 bool isReachableFromEntry(const Use &U) const; 145 146 /// \brief Verify the correctness of the domtree by re-computing it. 147 /// 148 /// This should only be used for debugging as it aborts the program if the 149 /// verification fails. 150 void verifyDomTree() const; 151 }; 152 153 //===------------------------------------- 154 // DominatorTree GraphTraits specializations so the DominatorTree can be 155 // iterable by generic graph iterators. 156 157 template <class Node, class ChildIterator> struct DomTreeGraphTraitsBase { 158 typedef Node NodeType; 159 typedef ChildIterator ChildIteratorType; 160 typedef df_iterator<Node *, SmallPtrSet<NodeType *, 8>> nodes_iterator; 161 162 static NodeType *getEntryNode(NodeType *N) { return N; } 163 static inline ChildIteratorType child_begin(NodeType *N) { 164 return N->begin(); 165 } 166 static inline ChildIteratorType child_end(NodeType *N) { return N->end(); } 167 168 static nodes_iterator nodes_begin(NodeType *N) { 169 return df_begin(getEntryNode(N)); 170 } 171 172 static nodes_iterator nodes_end(NodeType *N) { 173 return df_end(getEntryNode(N)); 174 } 175 }; 176 177 template <> 178 struct GraphTraits<DomTreeNode *> 179 : public DomTreeGraphTraitsBase<DomTreeNode, DomTreeNode::iterator> {}; 180 181 template <> 182 struct GraphTraits<const DomTreeNode *> 183 : public DomTreeGraphTraitsBase<const DomTreeNode, 184 DomTreeNode::const_iterator> {}; 185 186 template <> struct GraphTraits<DominatorTree*> 187 : public GraphTraits<DomTreeNode*> { 188 static NodeType *getEntryNode(DominatorTree *DT) { 189 return DT->getRootNode(); 190 } 191 192 static nodes_iterator nodes_begin(DominatorTree *N) { 193 return df_begin(getEntryNode(N)); 194 } 195 196 static nodes_iterator nodes_end(DominatorTree *N) { 197 return df_end(getEntryNode(N)); 198 } 199 }; 200 201 /// \brief Analysis pass which computes a \c DominatorTree. 202 class DominatorTreeAnalysis : public AnalysisInfoMixin<DominatorTreeAnalysis> { 203 friend AnalysisInfoMixin<DominatorTreeAnalysis>; 204 static char PassID; 205 206 public: 207 /// \brief Provide the result typedef for this analysis pass. 208 typedef DominatorTree Result; 209 210 /// \brief Run the analysis pass over a function and produce a dominator tree. 211 DominatorTree run(Function &F, AnalysisManager<Function> &); 212 }; 213 214 /// \brief Printer pass for the \c DominatorTree. 215 class DominatorTreePrinterPass 216 : public PassInfoMixin<DominatorTreePrinterPass> { 217 raw_ostream &OS; 218 219 public: 220 explicit DominatorTreePrinterPass(raw_ostream &OS); 221 PreservedAnalyses run(Function &F, AnalysisManager<Function> &AM); 222 }; 223 224 /// \brief Verifier pass for the \c DominatorTree. 225 struct DominatorTreeVerifierPass : PassInfoMixin<DominatorTreeVerifierPass> { 226 PreservedAnalyses run(Function &F, AnalysisManager<Function> &AM); 227 }; 228 229 /// \brief Legacy analysis pass which computes a \c DominatorTree. 230 class DominatorTreeWrapperPass : public FunctionPass { 231 DominatorTree DT; 232 233 public: 234 static char ID; 235 236 DominatorTreeWrapperPass() : FunctionPass(ID) { 237 initializeDominatorTreeWrapperPassPass(*PassRegistry::getPassRegistry()); 238 } 239 240 DominatorTree &getDomTree() { return DT; } 241 const DominatorTree &getDomTree() const { return DT; } 242 243 bool runOnFunction(Function &F) override; 244 245 void verifyAnalysis() const override; 246 247 void getAnalysisUsage(AnalysisUsage &AU) const override { 248 AU.setPreservesAll(); 249 } 250 251 void releaseMemory() override { DT.releaseMemory(); } 252 253 void print(raw_ostream &OS, const Module *M = nullptr) const override; 254 }; 255 256 } // End llvm namespace 257 258 #endif 259