1 //===- GenericDomTree.h - Generic dominator trees for graphs ----*- 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 /// \file 10 /// 11 /// This file defines a set of templates that efficiently compute a dominator 12 /// tree over a generic graph. This is used typically in LLVM for fast 13 /// dominance queries on the CFG, but is fully generic w.r.t. the underlying 14 /// graph types. 15 /// 16 //===----------------------------------------------------------------------===// 17 18 #ifndef LLVM_SUPPORT_GENERICDOMTREE_H 19 #define LLVM_SUPPORT_GENERICDOMTREE_H 20 21 #include "llvm/ADT/DenseMap.h" 22 #include "llvm/ADT/DepthFirstIterator.h" 23 #include "llvm/ADT/GraphTraits.h" 24 #include "llvm/ADT/STLExtras.h" 25 #include "llvm/ADT/SmallPtrSet.h" 26 #include "llvm/ADT/SmallVector.h" 27 #include "llvm/Support/Compiler.h" 28 #include "llvm/Support/raw_ostream.h" 29 #include <algorithm> 30 31 namespace llvm { 32 33 /// \brief Base class that other, more interesting dominator analyses 34 /// inherit from. 35 template <class NodeT> class DominatorBase { 36 protected: 37 std::vector<NodeT *> Roots; 38 bool IsPostDominators; 39 explicit DominatorBase(bool isPostDom) 40 : Roots(), IsPostDominators(isPostDom) {} 41 DominatorBase(DominatorBase &&Arg) 42 : Roots(std::move(Arg.Roots)), 43 IsPostDominators(std::move(Arg.IsPostDominators)) { 44 Arg.Roots.clear(); 45 } 46 DominatorBase &operator=(DominatorBase &&RHS) { 47 Roots = std::move(RHS.Roots); 48 IsPostDominators = std::move(RHS.IsPostDominators); 49 RHS.Roots.clear(); 50 return *this; 51 } 52 53 public: 54 /// getRoots - Return the root blocks of the current CFG. This may include 55 /// multiple blocks if we are computing post dominators. For forward 56 /// dominators, this will always be a single block (the entry node). 57 /// 58 const std::vector<NodeT *> &getRoots() const { return Roots; } 59 60 /// isPostDominator - Returns true if analysis based of postdoms 61 /// 62 bool isPostDominator() const { return IsPostDominators; } 63 }; 64 65 template <class NodeT> class DominatorTreeBase; 66 struct PostDominatorTree; 67 68 /// \brief Base class for the actual dominator tree node. 69 template <class NodeT> class DomTreeNodeBase { 70 NodeT *TheBB; 71 DomTreeNodeBase<NodeT> *IDom; 72 std::vector<DomTreeNodeBase<NodeT> *> Children; 73 mutable int DFSNumIn, DFSNumOut; 74 75 template <class N> friend class DominatorTreeBase; 76 friend struct PostDominatorTree; 77 78 public: 79 typedef typename std::vector<DomTreeNodeBase<NodeT> *>::iterator iterator; 80 typedef typename std::vector<DomTreeNodeBase<NodeT> *>::const_iterator 81 const_iterator; 82 83 iterator begin() { return Children.begin(); } 84 iterator end() { return Children.end(); } 85 const_iterator begin() const { return Children.begin(); } 86 const_iterator end() const { return Children.end(); } 87 88 NodeT *getBlock() const { return TheBB; } 89 DomTreeNodeBase<NodeT> *getIDom() const { return IDom; } 90 const std::vector<DomTreeNodeBase<NodeT> *> &getChildren() const { 91 return Children; 92 } 93 94 DomTreeNodeBase(NodeT *BB, DomTreeNodeBase<NodeT> *iDom) 95 : TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) {} 96 97 std::unique_ptr<DomTreeNodeBase<NodeT>> 98 addChild(std::unique_ptr<DomTreeNodeBase<NodeT>> C) { 99 Children.push_back(C.get()); 100 return C; 101 } 102 103 size_t getNumChildren() const { return Children.size(); } 104 105 void clearAllChildren() { Children.clear(); } 106 107 bool compare(const DomTreeNodeBase<NodeT> *Other) const { 108 if (getNumChildren() != Other->getNumChildren()) 109 return true; 110 111 SmallPtrSet<const NodeT *, 4> OtherChildren; 112 for (const_iterator I = Other->begin(), E = Other->end(); I != E; ++I) { 113 const NodeT *Nd = (*I)->getBlock(); 114 OtherChildren.insert(Nd); 115 } 116 117 for (const_iterator I = begin(), E = end(); I != E; ++I) { 118 const NodeT *N = (*I)->getBlock(); 119 if (OtherChildren.count(N) == 0) 120 return true; 121 } 122 return false; 123 } 124 125 void setIDom(DomTreeNodeBase<NodeT> *NewIDom) { 126 assert(IDom && "No immediate dominator?"); 127 if (IDom != NewIDom) { 128 typename std::vector<DomTreeNodeBase<NodeT> *>::iterator I = 129 std::find(IDom->Children.begin(), IDom->Children.end(), this); 130 assert(I != IDom->Children.end() && 131 "Not in immediate dominator children set!"); 132 // I am no longer your child... 133 IDom->Children.erase(I); 134 135 // Switch to new dominator 136 IDom = NewIDom; 137 IDom->Children.push_back(this); 138 } 139 } 140 141 /// getDFSNumIn/getDFSNumOut - These are an internal implementation detail, do 142 /// not call them. 143 unsigned getDFSNumIn() const { return DFSNumIn; } 144 unsigned getDFSNumOut() const { return DFSNumOut; } 145 146 private: 147 // Return true if this node is dominated by other. Use this only if DFS info 148 // is valid. 149 bool DominatedBy(const DomTreeNodeBase<NodeT> *other) const { 150 return this->DFSNumIn >= other->DFSNumIn && 151 this->DFSNumOut <= other->DFSNumOut; 152 } 153 }; 154 155 template <class NodeT> 156 raw_ostream &operator<<(raw_ostream &o, const DomTreeNodeBase<NodeT> *Node) { 157 if (Node->getBlock()) 158 Node->getBlock()->printAsOperand(o, false); 159 else 160 o << " <<exit node>>"; 161 162 o << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}"; 163 164 return o << "\n"; 165 } 166 167 template <class NodeT> 168 void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &o, 169 unsigned Lev) { 170 o.indent(2 * Lev) << "[" << Lev << "] " << N; 171 for (typename DomTreeNodeBase<NodeT>::const_iterator I = N->begin(), 172 E = N->end(); 173 I != E; ++I) 174 PrintDomTree<NodeT>(*I, o, Lev + 1); 175 } 176 177 // The calculate routine is provided in a separate header but referenced here. 178 template <class FuncT, class N> 179 void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType> &DT, 180 FuncT &F); 181 182 /// \brief Core dominator tree base class. 183 /// 184 /// This class is a generic template over graph nodes. It is instantiated for 185 /// various graphs in the LLVM IR or in the code generator. 186 template <class NodeT> class DominatorTreeBase : public DominatorBase<NodeT> { 187 DominatorTreeBase(const DominatorTreeBase &) = delete; 188 DominatorTreeBase &operator=(const DominatorTreeBase &) = delete; 189 190 bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A, 191 const DomTreeNodeBase<NodeT> *B) const { 192 assert(A != B); 193 assert(isReachableFromEntry(B)); 194 assert(isReachableFromEntry(A)); 195 196 const DomTreeNodeBase<NodeT> *IDom; 197 while ((IDom = B->getIDom()) != nullptr && IDom != A && IDom != B) 198 B = IDom; // Walk up the tree 199 return IDom != nullptr; 200 } 201 202 /// \brief Wipe this tree's state without releasing any resources. 203 /// 204 /// This is essentially a post-move helper only. It leaves the object in an 205 /// assignable and destroyable state, but otherwise invalid. 206 void wipe() { 207 DomTreeNodes.clear(); 208 IDoms.clear(); 209 Vertex.clear(); 210 Info.clear(); 211 RootNode = nullptr; 212 } 213 214 protected: 215 typedef DenseMap<NodeT *, std::unique_ptr<DomTreeNodeBase<NodeT>>> 216 DomTreeNodeMapType; 217 DomTreeNodeMapType DomTreeNodes; 218 DomTreeNodeBase<NodeT> *RootNode; 219 220 mutable bool DFSInfoValid; 221 mutable unsigned int SlowQueries; 222 // Information record used during immediate dominators computation. 223 struct InfoRec { 224 unsigned DFSNum; 225 unsigned Parent; 226 unsigned Semi; 227 NodeT *Label; 228 229 InfoRec() : DFSNum(0), Parent(0), Semi(0), Label(nullptr) {} 230 }; 231 232 DenseMap<NodeT *, NodeT *> IDoms; 233 234 // Vertex - Map the DFS number to the NodeT* 235 std::vector<NodeT *> Vertex; 236 237 // Info - Collection of information used during the computation of idoms. 238 DenseMap<NodeT *, InfoRec> Info; 239 240 void reset() { 241 DomTreeNodes.clear(); 242 IDoms.clear(); 243 this->Roots.clear(); 244 Vertex.clear(); 245 RootNode = nullptr; 246 DFSInfoValid = false; 247 SlowQueries = 0; 248 } 249 250 // NewBB is split and now it has one successor. Update dominator tree to 251 // reflect this change. 252 template <class N, class GraphT> 253 void Split(DominatorTreeBase<typename GraphT::NodeType> &DT, 254 typename GraphT::NodeType *NewBB) { 255 assert(std::distance(GraphT::child_begin(NewBB), 256 GraphT::child_end(NewBB)) == 1 && 257 "NewBB should have a single successor!"); 258 typename GraphT::NodeType *NewBBSucc = *GraphT::child_begin(NewBB); 259 260 std::vector<typename GraphT::NodeType *> PredBlocks; 261 typedef GraphTraits<Inverse<N>> InvTraits; 262 for (typename InvTraits::ChildIteratorType 263 PI = InvTraits::child_begin(NewBB), 264 PE = InvTraits::child_end(NewBB); 265 PI != PE; ++PI) 266 PredBlocks.push_back(*PI); 267 268 assert(!PredBlocks.empty() && "No predblocks?"); 269 270 bool NewBBDominatesNewBBSucc = true; 271 for (typename InvTraits::ChildIteratorType 272 PI = InvTraits::child_begin(NewBBSucc), 273 E = InvTraits::child_end(NewBBSucc); 274 PI != E; ++PI) { 275 typename InvTraits::NodeType *ND = *PI; 276 if (ND != NewBB && !DT.dominates(NewBBSucc, ND) && 277 DT.isReachableFromEntry(ND)) { 278 NewBBDominatesNewBBSucc = false; 279 break; 280 } 281 } 282 283 // Find NewBB's immediate dominator and create new dominator tree node for 284 // NewBB. 285 NodeT *NewBBIDom = nullptr; 286 unsigned i = 0; 287 for (i = 0; i < PredBlocks.size(); ++i) 288 if (DT.isReachableFromEntry(PredBlocks[i])) { 289 NewBBIDom = PredBlocks[i]; 290 break; 291 } 292 293 // It's possible that none of the predecessors of NewBB are reachable; 294 // in that case, NewBB itself is unreachable, so nothing needs to be 295 // changed. 296 if (!NewBBIDom) 297 return; 298 299 for (i = i + 1; i < PredBlocks.size(); ++i) { 300 if (DT.isReachableFromEntry(PredBlocks[i])) 301 NewBBIDom = DT.findNearestCommonDominator(NewBBIDom, PredBlocks[i]); 302 } 303 304 // Create the new dominator tree node... and set the idom of NewBB. 305 DomTreeNodeBase<NodeT> *NewBBNode = DT.addNewBlock(NewBB, NewBBIDom); 306 307 // If NewBB strictly dominates other blocks, then it is now the immediate 308 // dominator of NewBBSucc. Update the dominator tree as appropriate. 309 if (NewBBDominatesNewBBSucc) { 310 DomTreeNodeBase<NodeT> *NewBBSuccNode = DT.getNode(NewBBSucc); 311 DT.changeImmediateDominator(NewBBSuccNode, NewBBNode); 312 } 313 } 314 315 public: 316 explicit DominatorTreeBase(bool isPostDom) 317 : DominatorBase<NodeT>(isPostDom), DFSInfoValid(false), SlowQueries(0) {} 318 319 DominatorTreeBase(DominatorTreeBase &&Arg) 320 : DominatorBase<NodeT>( 321 std::move(static_cast<DominatorBase<NodeT> &>(Arg))), 322 DomTreeNodes(std::move(Arg.DomTreeNodes)), 323 RootNode(std::move(Arg.RootNode)), 324 DFSInfoValid(std::move(Arg.DFSInfoValid)), 325 SlowQueries(std::move(Arg.SlowQueries)), IDoms(std::move(Arg.IDoms)), 326 Vertex(std::move(Arg.Vertex)), Info(std::move(Arg.Info)) { 327 Arg.wipe(); 328 } 329 DominatorTreeBase &operator=(DominatorTreeBase &&RHS) { 330 DominatorBase<NodeT>::operator=( 331 std::move(static_cast<DominatorBase<NodeT> &>(RHS))); 332 DomTreeNodes = std::move(RHS.DomTreeNodes); 333 RootNode = std::move(RHS.RootNode); 334 DFSInfoValid = std::move(RHS.DFSInfoValid); 335 SlowQueries = std::move(RHS.SlowQueries); 336 IDoms = std::move(RHS.IDoms); 337 Vertex = std::move(RHS.Vertex); 338 Info = std::move(RHS.Info); 339 RHS.wipe(); 340 return *this; 341 } 342 343 /// compare - Return false if the other dominator tree base matches this 344 /// dominator tree base. Otherwise return true. 345 bool compare(const DominatorTreeBase &Other) const { 346 347 const DomTreeNodeMapType &OtherDomTreeNodes = Other.DomTreeNodes; 348 if (DomTreeNodes.size() != OtherDomTreeNodes.size()) 349 return true; 350 351 for (typename DomTreeNodeMapType::const_iterator 352 I = this->DomTreeNodes.begin(), 353 E = this->DomTreeNodes.end(); 354 I != E; ++I) { 355 NodeT *BB = I->first; 356 typename DomTreeNodeMapType::const_iterator OI = 357 OtherDomTreeNodes.find(BB); 358 if (OI == OtherDomTreeNodes.end()) 359 return true; 360 361 DomTreeNodeBase<NodeT> &MyNd = *I->second; 362 DomTreeNodeBase<NodeT> &OtherNd = *OI->second; 363 364 if (MyNd.compare(&OtherNd)) 365 return true; 366 } 367 368 return false; 369 } 370 371 void releaseMemory() { reset(); } 372 373 /// getNode - return the (Post)DominatorTree node for the specified basic 374 /// block. This is the same as using operator[] on this class. The result 375 /// may (but is not required to) be null for a forward (backwards) 376 /// statically unreachable block. 377 DomTreeNodeBase<NodeT> *getNode(NodeT *BB) const { 378 auto I = DomTreeNodes.find(BB); 379 if (I != DomTreeNodes.end()) 380 return I->second.get(); 381 return nullptr; 382 } 383 384 /// See getNode. 385 DomTreeNodeBase<NodeT> *operator[](NodeT *BB) const { return getNode(BB); } 386 387 /// getRootNode - This returns the entry node for the CFG of the function. If 388 /// this tree represents the post-dominance relations for a function, however, 389 /// this root may be a node with the block == NULL. This is the case when 390 /// there are multiple exit nodes from a particular function. Consumers of 391 /// post-dominance information must be capable of dealing with this 392 /// possibility. 393 /// 394 DomTreeNodeBase<NodeT> *getRootNode() { return RootNode; } 395 const DomTreeNodeBase<NodeT> *getRootNode() const { return RootNode; } 396 397 /// Get all nodes dominated by R, including R itself. 398 void getDescendants(NodeT *R, SmallVectorImpl<NodeT *> &Result) const { 399 Result.clear(); 400 const DomTreeNodeBase<NodeT> *RN = getNode(R); 401 if (!RN) 402 return; // If R is unreachable, it will not be present in the DOM tree. 403 SmallVector<const DomTreeNodeBase<NodeT> *, 8> WL; 404 WL.push_back(RN); 405 406 while (!WL.empty()) { 407 const DomTreeNodeBase<NodeT> *N = WL.pop_back_val(); 408 Result.push_back(N->getBlock()); 409 WL.append(N->begin(), N->end()); 410 } 411 } 412 413 /// properlyDominates - Returns true iff A dominates B and A != B. 414 /// Note that this is not a constant time operation! 415 /// 416 bool properlyDominates(const DomTreeNodeBase<NodeT> *A, 417 const DomTreeNodeBase<NodeT> *B) const { 418 if (!A || !B) 419 return false; 420 if (A == B) 421 return false; 422 return dominates(A, B); 423 } 424 425 bool properlyDominates(const NodeT *A, const NodeT *B) const; 426 427 /// isReachableFromEntry - Return true if A is dominated by the entry 428 /// block of the function containing it. 429 bool isReachableFromEntry(const NodeT *A) const { 430 assert(!this->isPostDominator() && 431 "This is not implemented for post dominators"); 432 return isReachableFromEntry(getNode(const_cast<NodeT *>(A))); 433 } 434 435 bool isReachableFromEntry(const DomTreeNodeBase<NodeT> *A) const { return A; } 436 437 /// dominates - Returns true iff A dominates B. Note that this is not a 438 /// constant time operation! 439 /// 440 bool dominates(const DomTreeNodeBase<NodeT> *A, 441 const DomTreeNodeBase<NodeT> *B) const { 442 // A node trivially dominates itself. 443 if (B == A) 444 return true; 445 446 // An unreachable node is dominated by anything. 447 if (!isReachableFromEntry(B)) 448 return true; 449 450 // And dominates nothing. 451 if (!isReachableFromEntry(A)) 452 return false; 453 454 // Compare the result of the tree walk and the dfs numbers, if expensive 455 // checks are enabled. 456 #ifdef XDEBUG 457 assert((!DFSInfoValid || 458 (dominatedBySlowTreeWalk(A, B) == B->DominatedBy(A))) && 459 "Tree walk disagrees with dfs numbers!"); 460 #endif 461 462 if (DFSInfoValid) 463 return B->DominatedBy(A); 464 465 // If we end up with too many slow queries, just update the 466 // DFS numbers on the theory that we are going to keep querying. 467 SlowQueries++; 468 if (SlowQueries > 32) { 469 updateDFSNumbers(); 470 return B->DominatedBy(A); 471 } 472 473 return dominatedBySlowTreeWalk(A, B); 474 } 475 476 bool dominates(const NodeT *A, const NodeT *B) const; 477 478 NodeT *getRoot() const { 479 assert(this->Roots.size() == 1 && "Should always have entry node!"); 480 return this->Roots[0]; 481 } 482 483 /// findNearestCommonDominator - Find nearest common dominator basic block 484 /// for basic block A and B. If there is no such block then return NULL. 485 NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) { 486 assert(A->getParent() == B->getParent() && 487 "Two blocks are not in same function"); 488 489 // If either A or B is a entry block then it is nearest common dominator 490 // (for forward-dominators). 491 if (!this->isPostDominator()) { 492 NodeT &Entry = A->getParent()->front(); 493 if (A == &Entry || B == &Entry) 494 return &Entry; 495 } 496 497 // If B dominates A then B is nearest common dominator. 498 if (dominates(B, A)) 499 return B; 500 501 // If A dominates B then A is nearest common dominator. 502 if (dominates(A, B)) 503 return A; 504 505 DomTreeNodeBase<NodeT> *NodeA = getNode(A); 506 DomTreeNodeBase<NodeT> *NodeB = getNode(B); 507 508 // If we have DFS info, then we can avoid all allocations by just querying 509 // it from each IDom. Note that because we call 'dominates' twice above, we 510 // expect to call through this code at most 16 times in a row without 511 // building valid DFS information. This is important as below is a *very* 512 // slow tree walk. 513 if (DFSInfoValid) { 514 DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom(); 515 while (IDomA) { 516 if (NodeB->DominatedBy(IDomA)) 517 return IDomA->getBlock(); 518 IDomA = IDomA->getIDom(); 519 } 520 return nullptr; 521 } 522 523 // Collect NodeA dominators set. 524 SmallPtrSet<DomTreeNodeBase<NodeT> *, 16> NodeADoms; 525 NodeADoms.insert(NodeA); 526 DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom(); 527 while (IDomA) { 528 NodeADoms.insert(IDomA); 529 IDomA = IDomA->getIDom(); 530 } 531 532 // Walk NodeB immediate dominators chain and find common dominator node. 533 DomTreeNodeBase<NodeT> *IDomB = NodeB->getIDom(); 534 while (IDomB) { 535 if (NodeADoms.count(IDomB) != 0) 536 return IDomB->getBlock(); 537 538 IDomB = IDomB->getIDom(); 539 } 540 541 return nullptr; 542 } 543 544 const NodeT *findNearestCommonDominator(const NodeT *A, const NodeT *B) { 545 // Cast away the const qualifiers here. This is ok since 546 // const is re-introduced on the return type. 547 return findNearestCommonDominator(const_cast<NodeT *>(A), 548 const_cast<NodeT *>(B)); 549 } 550 551 //===--------------------------------------------------------------------===// 552 // API to update (Post)DominatorTree information based on modifications to 553 // the CFG... 554 555 /// addNewBlock - Add a new node to the dominator tree information. This 556 /// creates a new node as a child of DomBB dominator node,linking it into 557 /// the children list of the immediate dominator. 558 DomTreeNodeBase<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) { 559 assert(getNode(BB) == nullptr && "Block already in dominator tree!"); 560 DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB); 561 assert(IDomNode && "Not immediate dominator specified for block!"); 562 DFSInfoValid = false; 563 return (DomTreeNodes[BB] = IDomNode->addChild( 564 llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))).get(); 565 } 566 567 /// changeImmediateDominator - This method is used to update the dominator 568 /// tree information when a node's immediate dominator changes. 569 /// 570 void changeImmediateDominator(DomTreeNodeBase<NodeT> *N, 571 DomTreeNodeBase<NodeT> *NewIDom) { 572 assert(N && NewIDom && "Cannot change null node pointers!"); 573 DFSInfoValid = false; 574 N->setIDom(NewIDom); 575 } 576 577 void changeImmediateDominator(NodeT *BB, NodeT *NewBB) { 578 changeImmediateDominator(getNode(BB), getNode(NewBB)); 579 } 580 581 /// eraseNode - Removes a node from the dominator tree. Block must not 582 /// dominate any other blocks. Removes node from its immediate dominator's 583 /// children list. Deletes dominator node associated with basic block BB. 584 void eraseNode(NodeT *BB) { 585 DomTreeNodeBase<NodeT> *Node = getNode(BB); 586 assert(Node && "Removing node that isn't in dominator tree."); 587 assert(Node->getChildren().empty() && "Node is not a leaf node."); 588 589 // Remove node from immediate dominator's children list. 590 DomTreeNodeBase<NodeT> *IDom = Node->getIDom(); 591 if (IDom) { 592 typename std::vector<DomTreeNodeBase<NodeT> *>::iterator I = 593 std::find(IDom->Children.begin(), IDom->Children.end(), Node); 594 assert(I != IDom->Children.end() && 595 "Not in immediate dominator children set!"); 596 // I am no longer your child... 597 IDom->Children.erase(I); 598 } 599 600 DomTreeNodes.erase(BB); 601 } 602 603 /// splitBlock - BB is split and now it has one successor. Update dominator 604 /// tree to reflect this change. 605 void splitBlock(NodeT *NewBB) { 606 if (this->IsPostDominators) 607 this->Split<Inverse<NodeT *>, GraphTraits<Inverse<NodeT *>>>(*this, 608 NewBB); 609 else 610 this->Split<NodeT *, GraphTraits<NodeT *>>(*this, NewBB); 611 } 612 613 /// print - Convert to human readable form 614 /// 615 void print(raw_ostream &o) const { 616 o << "=============================--------------------------------\n"; 617 if (this->isPostDominator()) 618 o << "Inorder PostDominator Tree: "; 619 else 620 o << "Inorder Dominator Tree: "; 621 if (!this->DFSInfoValid) 622 o << "DFSNumbers invalid: " << SlowQueries << " slow queries."; 623 o << "\n"; 624 625 // The postdom tree can have a null root if there are no returns. 626 if (getRootNode()) 627 PrintDomTree<NodeT>(getRootNode(), o, 1); 628 } 629 630 protected: 631 template <class GraphT> 632 friend typename GraphT::NodeType * 633 Eval(DominatorTreeBase<typename GraphT::NodeType> &DT, 634 typename GraphT::NodeType *V, unsigned LastLinked); 635 636 template <class GraphT> 637 friend unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType> &DT, 638 typename GraphT::NodeType *V, unsigned N); 639 640 template <class FuncT, class N> 641 friend void 642 Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType> &DT, FuncT &F); 643 644 645 DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB) { 646 if (DomTreeNodeBase<NodeT> *Node = getNode(BB)) 647 return Node; 648 649 // Haven't calculated this node yet? Get or calculate the node for the 650 // immediate dominator. 651 NodeT *IDom = getIDom(BB); 652 653 assert(IDom || this->DomTreeNodes[nullptr]); 654 DomTreeNodeBase<NodeT> *IDomNode = getNodeForBlock(IDom); 655 656 // Add a new tree node for this NodeT, and link it as a child of 657 // IDomNode 658 return (this->DomTreeNodes[BB] = IDomNode->addChild( 659 llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))).get(); 660 } 661 662 NodeT *getIDom(NodeT *BB) const { return IDoms.lookup(BB); } 663 664 void addRoot(NodeT *BB) { this->Roots.push_back(BB); } 665 666 public: 667 /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking 668 /// dominator tree in dfs order. 669 void updateDFSNumbers() const { 670 671 if (DFSInfoValid) { 672 SlowQueries = 0; 673 return; 674 } 675 676 unsigned DFSNum = 0; 677 678 SmallVector<std::pair<const DomTreeNodeBase<NodeT> *, 679 typename DomTreeNodeBase<NodeT>::const_iterator>, 680 32> WorkStack; 681 682 const DomTreeNodeBase<NodeT> *ThisRoot = getRootNode(); 683 684 if (!ThisRoot) 685 return; 686 687 // Even in the case of multiple exits that form the post dominator root 688 // nodes, do not iterate over all exits, but start from the virtual root 689 // node. Otherwise bbs, that are not post dominated by any exit but by the 690 // virtual root node, will never be assigned a DFS number. 691 WorkStack.push_back(std::make_pair(ThisRoot, ThisRoot->begin())); 692 ThisRoot->DFSNumIn = DFSNum++; 693 694 while (!WorkStack.empty()) { 695 const DomTreeNodeBase<NodeT> *Node = WorkStack.back().first; 696 typename DomTreeNodeBase<NodeT>::const_iterator ChildIt = 697 WorkStack.back().second; 698 699 // If we visited all of the children of this node, "recurse" back up the 700 // stack setting the DFOutNum. 701 if (ChildIt == Node->end()) { 702 Node->DFSNumOut = DFSNum++; 703 WorkStack.pop_back(); 704 } else { 705 // Otherwise, recursively visit this child. 706 const DomTreeNodeBase<NodeT> *Child = *ChildIt; 707 ++WorkStack.back().second; 708 709 WorkStack.push_back(std::make_pair(Child, Child->begin())); 710 Child->DFSNumIn = DFSNum++; 711 } 712 } 713 714 SlowQueries = 0; 715 DFSInfoValid = true; 716 } 717 718 /// recalculate - compute a dominator tree for the given function 719 template <class FT> void recalculate(FT &F) { 720 typedef GraphTraits<FT *> TraitsTy; 721 reset(); 722 this->Vertex.push_back(nullptr); 723 724 if (!this->IsPostDominators) { 725 // Initialize root 726 NodeT *entry = TraitsTy::getEntryNode(&F); 727 this->Roots.push_back(entry); 728 this->IDoms[entry] = nullptr; 729 this->DomTreeNodes[entry] = nullptr; 730 731 Calculate<FT, NodeT *>(*this, F); 732 } else { 733 // Initialize the roots list 734 for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F), 735 E = TraitsTy::nodes_end(&F); 736 I != E; ++I) { 737 if (TraitsTy::child_begin(&*I) == TraitsTy::child_end(&*I)) 738 addRoot(&*I); 739 740 // Prepopulate maps so that we don't get iterator invalidation issues 741 // later. 742 this->IDoms[&*I] = nullptr; 743 this->DomTreeNodes[&*I] = nullptr; 744 } 745 746 Calculate<FT, Inverse<NodeT *>>(*this, F); 747 } 748 } 749 }; 750 751 // These two functions are declared out of line as a workaround for building 752 // with old (< r147295) versions of clang because of pr11642. 753 template <class NodeT> 754 bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) const { 755 if (A == B) 756 return true; 757 758 // Cast away the const qualifiers here. This is ok since 759 // this function doesn't actually return the values returned 760 // from getNode. 761 return dominates(getNode(const_cast<NodeT *>(A)), 762 getNode(const_cast<NodeT *>(B))); 763 } 764 template <class NodeT> 765 bool DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, 766 const NodeT *B) const { 767 if (A == B) 768 return false; 769 770 // Cast away the const qualifiers here. This is ok since 771 // this function doesn't actually return the values returned 772 // from getNode. 773 return dominates(getNode(const_cast<NodeT *>(A)), 774 getNode(const_cast<NodeT *>(B))); 775 } 776 777 } 778 779 #endif 780