Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 1 | //===- Dominators.h - Dominator Info Calculation ----------------*- C++ -*-===// |
| 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 file defines the DominatorTree class, which provides fast and efficient |
||
| 10 | // dominance queries. |
||
| 11 | // |
||
| 12 | //===----------------------------------------------------------------------===// |
||
| 13 | |||
| 14 | #ifndef LLVM_IR_DOMINATORS_H |
||
| 15 | #define LLVM_IR_DOMINATORS_H |
||
| 16 | |||
| 17 | #include "llvm/ADT/APInt.h" |
||
| 18 | #include "llvm/ADT/ArrayRef.h" |
||
| 19 | #include "llvm/ADT/DenseMap.h" |
||
| 20 | #include "llvm/ADT/DenseMapInfo.h" |
||
| 21 | #include "llvm/ADT/DepthFirstIterator.h" |
||
| 22 | #include "llvm/ADT/Hashing.h" |
||
| 23 | #include "llvm/ADT/PointerIntPair.h" |
||
| 24 | #include "llvm/ADT/SmallVector.h" |
||
| 25 | #include "llvm/ADT/Twine.h" |
||
| 26 | #include "llvm/ADT/ilist_iterator.h" |
||
| 27 | #include "llvm/ADT/iterator_range.h" |
||
| 28 | #include "llvm/IR/BasicBlock.h" |
||
| 29 | #include "llvm/IR/CFG.h" |
||
| 30 | #include "llvm/IR/PassManager.h" |
||
| 31 | #include "llvm/IR/Use.h" |
||
| 32 | #include "llvm/Pass.h" |
||
| 33 | #include "llvm/Support/CFGDiff.h" |
||
| 34 | #include "llvm/Support/CFGUpdate.h" |
||
| 35 | #include "llvm/Support/GenericDomTree.h" |
||
| 36 | #include "llvm/Support/GenericDomTreeConstruction.h" |
||
| 37 | #include <algorithm> |
||
| 38 | #include <utility> |
||
| 39 | #include <vector> |
||
| 40 | |||
| 41 | namespace llvm { |
||
| 42 | |||
| 43 | class Function; |
||
| 44 | class Instruction; |
||
| 45 | class Module; |
||
| 46 | class Value; |
||
| 47 | class raw_ostream; |
||
| 48 | template <class GraphType> struct GraphTraits; |
||
| 49 | |||
| 50 | extern template class DomTreeNodeBase<BasicBlock>; |
||
| 51 | extern template class DominatorTreeBase<BasicBlock, false>; // DomTree |
||
| 52 | extern template class DominatorTreeBase<BasicBlock, true>; // PostDomTree |
||
| 53 | |||
| 54 | extern template class cfg::Update<BasicBlock *>; |
||
| 55 | |||
| 56 | namespace DomTreeBuilder { |
||
| 57 | using BBDomTree = DomTreeBase<BasicBlock>; |
||
| 58 | using BBPostDomTree = PostDomTreeBase<BasicBlock>; |
||
| 59 | |||
| 60 | using BBUpdates = ArrayRef<llvm::cfg::Update<BasicBlock *>>; |
||
| 61 | |||
| 62 | using BBDomTreeGraphDiff = GraphDiff<BasicBlock *, false>; |
||
| 63 | using BBPostDomTreeGraphDiff = GraphDiff<BasicBlock *, true>; |
||
| 64 | |||
| 65 | extern template void Calculate<BBDomTree>(BBDomTree &DT); |
||
| 66 | extern template void CalculateWithUpdates<BBDomTree>(BBDomTree &DT, |
||
| 67 | BBUpdates U); |
||
| 68 | |||
| 69 | extern template void Calculate<BBPostDomTree>(BBPostDomTree &DT); |
||
| 70 | |||
| 71 | extern template void InsertEdge<BBDomTree>(BBDomTree &DT, BasicBlock *From, |
||
| 72 | BasicBlock *To); |
||
| 73 | extern template void InsertEdge<BBPostDomTree>(BBPostDomTree &DT, |
||
| 74 | BasicBlock *From, |
||
| 75 | BasicBlock *To); |
||
| 76 | |||
| 77 | extern template void DeleteEdge<BBDomTree>(BBDomTree &DT, BasicBlock *From, |
||
| 78 | BasicBlock *To); |
||
| 79 | extern template void DeleteEdge<BBPostDomTree>(BBPostDomTree &DT, |
||
| 80 | BasicBlock *From, |
||
| 81 | BasicBlock *To); |
||
| 82 | |||
| 83 | extern template void ApplyUpdates<BBDomTree>(BBDomTree &DT, |
||
| 84 | BBDomTreeGraphDiff &, |
||
| 85 | BBDomTreeGraphDiff *); |
||
| 86 | extern template void ApplyUpdates<BBPostDomTree>(BBPostDomTree &DT, |
||
| 87 | BBPostDomTreeGraphDiff &, |
||
| 88 | BBPostDomTreeGraphDiff *); |
||
| 89 | |||
| 90 | extern template bool Verify<BBDomTree>(const BBDomTree &DT, |
||
| 91 | BBDomTree::VerificationLevel VL); |
||
| 92 | extern template bool Verify<BBPostDomTree>(const BBPostDomTree &DT, |
||
| 93 | BBPostDomTree::VerificationLevel VL); |
||
| 94 | } // namespace DomTreeBuilder |
||
| 95 | |||
| 96 | using DomTreeNode = DomTreeNodeBase<BasicBlock>; |
||
| 97 | |||
| 98 | class BasicBlockEdge { |
||
| 99 | const BasicBlock *Start; |
||
| 100 | const BasicBlock *End; |
||
| 101 | |||
| 102 | public: |
||
| 103 | BasicBlockEdge(const BasicBlock *Start_, const BasicBlock *End_) : |
||
| 104 | Start(Start_), End(End_) {} |
||
| 105 | |||
| 106 | BasicBlockEdge(const std::pair<BasicBlock *, BasicBlock *> &Pair) |
||
| 107 | : Start(Pair.first), End(Pair.second) {} |
||
| 108 | |||
| 109 | BasicBlockEdge(const std::pair<const BasicBlock *, const BasicBlock *> &Pair) |
||
| 110 | : Start(Pair.first), End(Pair.second) {} |
||
| 111 | |||
| 112 | const BasicBlock *getStart() const { |
||
| 113 | return Start; |
||
| 114 | } |
||
| 115 | |||
| 116 | const BasicBlock *getEnd() const { |
||
| 117 | return End; |
||
| 118 | } |
||
| 119 | |||
| 120 | /// Check if this is the only edge between Start and End. |
||
| 121 | bool isSingleEdge() const; |
||
| 122 | }; |
||
| 123 | |||
| 124 | template <> struct DenseMapInfo<BasicBlockEdge> { |
||
| 125 | using BBInfo = DenseMapInfo<const BasicBlock *>; |
||
| 126 | |||
| 127 | static unsigned getHashValue(const BasicBlockEdge *V); |
||
| 128 | |||
| 129 | static inline BasicBlockEdge getEmptyKey() { |
||
| 130 | return BasicBlockEdge(BBInfo::getEmptyKey(), BBInfo::getEmptyKey()); |
||
| 131 | } |
||
| 132 | |||
| 133 | static inline BasicBlockEdge getTombstoneKey() { |
||
| 134 | return BasicBlockEdge(BBInfo::getTombstoneKey(), BBInfo::getTombstoneKey()); |
||
| 135 | } |
||
| 136 | |||
| 137 | static unsigned getHashValue(const BasicBlockEdge &Edge) { |
||
| 138 | return hash_combine(BBInfo::getHashValue(Edge.getStart()), |
||
| 139 | BBInfo::getHashValue(Edge.getEnd())); |
||
| 140 | } |
||
| 141 | |||
| 142 | static bool isEqual(const BasicBlockEdge &LHS, const BasicBlockEdge &RHS) { |
||
| 143 | return BBInfo::isEqual(LHS.getStart(), RHS.getStart()) && |
||
| 144 | BBInfo::isEqual(LHS.getEnd(), RHS.getEnd()); |
||
| 145 | } |
||
| 146 | }; |
||
| 147 | |||
| 148 | /// Concrete subclass of DominatorTreeBase that is used to compute a |
||
| 149 | /// normal dominator tree. |
||
| 150 | /// |
||
| 151 | /// Definition: A block is said to be forward statically reachable if there is |
||
| 152 | /// a path from the entry of the function to the block. A statically reachable |
||
| 153 | /// block may become statically unreachable during optimization. |
||
| 154 | /// |
||
| 155 | /// A forward unreachable block may appear in the dominator tree, or it may |
||
| 156 | /// not. If it does, dominance queries will return results as if all reachable |
||
| 157 | /// blocks dominate it. When asking for a Node corresponding to a potentially |
||
| 158 | /// unreachable block, calling code must handle the case where the block was |
||
| 159 | /// unreachable and the result of getNode() is nullptr. |
||
| 160 | /// |
||
| 161 | /// Generally, a block known to be unreachable when the dominator tree is |
||
| 162 | /// constructed will not be in the tree. One which becomes unreachable after |
||
| 163 | /// the dominator tree is initially constructed may still exist in the tree, |
||
| 164 | /// even if the tree is properly updated. Calling code should not rely on the |
||
| 165 | /// preceding statements; this is stated only to assist human understanding. |
||
| 166 | class DominatorTree : public DominatorTreeBase<BasicBlock, false> { |
||
| 167 | public: |
||
| 168 | using Base = DominatorTreeBase<BasicBlock, false>; |
||
| 169 | |||
| 170 | DominatorTree() = default; |
||
| 171 | explicit DominatorTree(Function &F) { recalculate(F); } |
||
| 172 | explicit DominatorTree(DominatorTree &DT, DomTreeBuilder::BBUpdates U) { |
||
| 173 | recalculate(*DT.Parent, U); |
||
| 174 | } |
||
| 175 | |||
| 176 | /// Handle invalidation explicitly. |
||
| 177 | bool invalidate(Function &F, const PreservedAnalyses &PA, |
||
| 178 | FunctionAnalysisManager::Invalidator &); |
||
| 179 | |||
| 180 | // Ensure base-class overloads are visible. |
||
| 181 | using Base::dominates; |
||
| 182 | |||
| 183 | /// Return true if the (end of the) basic block BB dominates the use U. |
||
| 184 | bool dominates(const BasicBlock *BB, const Use &U) const; |
||
| 185 | |||
| 186 | /// Return true if value Def dominates use U, in the sense that Def is |
||
| 187 | /// available at U, and could be substituted as the used value without |
||
| 188 | /// violating the SSA dominance requirement. |
||
| 189 | /// |
||
| 190 | /// In particular, it is worth noting that: |
||
| 191 | /// * Non-instruction Defs dominate everything. |
||
| 192 | /// * Def does not dominate a use in Def itself (outside of degenerate cases |
||
| 193 | /// like unreachable code or trivial phi cycles). |
||
| 194 | /// * Invoke/callbr Defs only dominate uses in their default destination. |
||
| 195 | bool dominates(const Value *Def, const Use &U) const; |
||
| 196 | /// Return true if value Def dominates all possible uses inside instruction |
||
| 197 | /// User. Same comments as for the Use-based API apply. |
||
| 198 | bool dominates(const Value *Def, const Instruction *User) const; |
||
| 199 | |||
| 200 | /// Returns true if Def would dominate a use in any instruction in BB. |
||
| 201 | /// If Def is an instruction in BB, then Def does not dominate BB. |
||
| 202 | /// |
||
| 203 | /// Does not accept Value to avoid ambiguity with dominance checks between |
||
| 204 | /// two basic blocks. |
||
| 205 | bool dominates(const Instruction *Def, const BasicBlock *BB) const; |
||
| 206 | |||
| 207 | /// Return true if an edge dominates a use. |
||
| 208 | /// |
||
| 209 | /// If BBE is not a unique edge between start and end of the edge, it can |
||
| 210 | /// never dominate the use. |
||
| 211 | bool dominates(const BasicBlockEdge &BBE, const Use &U) const; |
||
| 212 | bool dominates(const BasicBlockEdge &BBE, const BasicBlock *BB) const; |
||
| 213 | /// Returns true if edge \p BBE1 dominates edge \p BBE2. |
||
| 214 | bool dominates(const BasicBlockEdge &BBE1, const BasicBlockEdge &BBE2) const; |
||
| 215 | |||
| 216 | // Ensure base class overloads are visible. |
||
| 217 | using Base::isReachableFromEntry; |
||
| 218 | |||
| 219 | /// Provide an overload for a Use. |
||
| 220 | bool isReachableFromEntry(const Use &U) const; |
||
| 221 | |||
| 222 | // Ensure base class overloads are visible. |
||
| 223 | using Base::findNearestCommonDominator; |
||
| 224 | |||
| 225 | /// Find the nearest instruction I that dominates both I1 and I2, in the sense |
||
| 226 | /// that a result produced before I will be available at both I1 and I2. |
||
| 227 | Instruction *findNearestCommonDominator(Instruction *I1, |
||
| 228 | Instruction *I2) const; |
||
| 229 | |||
| 230 | // Pop up a GraphViz/gv window with the Dominator Tree rendered using `dot`. |
||
| 231 | void viewGraph(const Twine &Name, const Twine &Title); |
||
| 232 | void viewGraph(); |
||
| 233 | }; |
||
| 234 | |||
| 235 | //===------------------------------------- |
||
| 236 | // DominatorTree GraphTraits specializations so the DominatorTree can be |
||
| 237 | // iterable by generic graph iterators. |
||
| 238 | |||
| 239 | template <class Node, class ChildIterator> struct DomTreeGraphTraitsBase { |
||
| 240 | using NodeRef = Node *; |
||
| 241 | using ChildIteratorType = ChildIterator; |
||
| 242 | using nodes_iterator = df_iterator<Node *, df_iterator_default_set<Node*>>; |
||
| 243 | |||
| 244 | static NodeRef getEntryNode(NodeRef N) { return N; } |
||
| 245 | static ChildIteratorType child_begin(NodeRef N) { return N->begin(); } |
||
| 246 | static ChildIteratorType child_end(NodeRef N) { return N->end(); } |
||
| 247 | |||
| 248 | static nodes_iterator nodes_begin(NodeRef N) { |
||
| 249 | return df_begin(getEntryNode(N)); |
||
| 250 | } |
||
| 251 | |||
| 252 | static nodes_iterator nodes_end(NodeRef N) { return df_end(getEntryNode(N)); } |
||
| 253 | }; |
||
| 254 | |||
| 255 | template <> |
||
| 256 | struct GraphTraits<DomTreeNode *> |
||
| 257 | : public DomTreeGraphTraitsBase<DomTreeNode, DomTreeNode::const_iterator> { |
||
| 258 | }; |
||
| 259 | |||
| 260 | template <> |
||
| 261 | struct GraphTraits<const DomTreeNode *> |
||
| 262 | : public DomTreeGraphTraitsBase<const DomTreeNode, |
||
| 263 | DomTreeNode::const_iterator> {}; |
||
| 264 | |||
| 265 | template <> struct GraphTraits<DominatorTree*> |
||
| 266 | : public GraphTraits<DomTreeNode*> { |
||
| 267 | static NodeRef getEntryNode(DominatorTree *DT) { return DT->getRootNode(); } |
||
| 268 | |||
| 269 | static nodes_iterator nodes_begin(DominatorTree *N) { |
||
| 270 | return df_begin(getEntryNode(N)); |
||
| 271 | } |
||
| 272 | |||
| 273 | static nodes_iterator nodes_end(DominatorTree *N) { |
||
| 274 | return df_end(getEntryNode(N)); |
||
| 275 | } |
||
| 276 | }; |
||
| 277 | |||
| 278 | /// Analysis pass which computes a \c DominatorTree. |
||
| 279 | class DominatorTreeAnalysis : public AnalysisInfoMixin<DominatorTreeAnalysis> { |
||
| 280 | friend AnalysisInfoMixin<DominatorTreeAnalysis>; |
||
| 281 | static AnalysisKey Key; |
||
| 282 | |||
| 283 | public: |
||
| 284 | /// Provide the result typedef for this analysis pass. |
||
| 285 | using Result = DominatorTree; |
||
| 286 | |||
| 287 | /// Run the analysis pass over a function and produce a dominator tree. |
||
| 288 | DominatorTree run(Function &F, FunctionAnalysisManager &); |
||
| 289 | }; |
||
| 290 | |||
| 291 | /// Printer pass for the \c DominatorTree. |
||
| 292 | class DominatorTreePrinterPass |
||
| 293 | : public PassInfoMixin<DominatorTreePrinterPass> { |
||
| 294 | raw_ostream &OS; |
||
| 295 | |||
| 296 | public: |
||
| 297 | explicit DominatorTreePrinterPass(raw_ostream &OS); |
||
| 298 | |||
| 299 | PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); |
||
| 300 | }; |
||
| 301 | |||
| 302 | /// Verifier pass for the \c DominatorTree. |
||
| 303 | struct DominatorTreeVerifierPass : PassInfoMixin<DominatorTreeVerifierPass> { |
||
| 304 | PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); |
||
| 305 | }; |
||
| 306 | |||
| 307 | /// Enables verification of dominator trees. |
||
| 308 | /// |
||
| 309 | /// This check is expensive and is disabled by default. `-verify-dom-info` |
||
| 310 | /// allows selectively enabling the check without needing to recompile. |
||
| 311 | extern bool VerifyDomInfo; |
||
| 312 | |||
| 313 | /// Legacy analysis pass which computes a \c DominatorTree. |
||
| 314 | class DominatorTreeWrapperPass : public FunctionPass { |
||
| 315 | DominatorTree DT; |
||
| 316 | |||
| 317 | public: |
||
| 318 | static char ID; |
||
| 319 | |||
| 320 | DominatorTreeWrapperPass(); |
||
| 321 | |||
| 322 | DominatorTree &getDomTree() { return DT; } |
||
| 323 | const DominatorTree &getDomTree() const { return DT; } |
||
| 324 | |||
| 325 | bool runOnFunction(Function &F) override; |
||
| 326 | |||
| 327 | void verifyAnalysis() const override; |
||
| 328 | |||
| 329 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
||
| 330 | AU.setPreservesAll(); |
||
| 331 | } |
||
| 332 | |||
| 333 | void releaseMemory() override { DT.reset(); } |
||
| 334 | |||
| 335 | void print(raw_ostream &OS, const Module *M = nullptr) const override; |
||
| 336 | }; |
||
| 337 | } // end namespace llvm |
||
| 338 | |||
| 339 | #endif // LLVM_IR_DOMINATORS_H |