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