LLVM 24.0.0git
GenericDomTree.h
Go to the documentation of this file.
1//===- GenericDomTree.h - Generic dominator trees for graphs ----*- 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/// \file
9///
10/// This file defines a set of templates that efficiently compute a dominator
11/// tree over a generic graph. This is used typically in LLVM for fast
12/// dominance queries on the CFG, but is fully generic w.r.t. the underlying
13/// graph types.
14///
15/// Unlike ADT/* graph algorithms, generic dominator tree has more requirements
16/// on the graph's NodeRef. The NodeRef should be a pointer and,
17/// either NodeRef->getParent() must return the parent node that is also a
18/// pointer or DomTreeNodeTraits needs to be specialized.
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/STLExtras.h"
36#include <algorithm>
37#include <cassert>
38#include <cstddef>
39#include <memory>
40#include <new>
41#include <type_traits>
42#include <utility>
43
44namespace llvm {
45
46template <typename NodeT, bool IsPostDom>
48
49template <class BlockT, class LoopT> class LoopInfoBase;
50
51namespace DomTreeBuilder {
52template <typename DomTreeT>
53struct SemiNCAInfo;
54} // namespace DomTreeBuilder
55
56/// Base class for the actual dominator tree node.
57template <class NodeT> class DomTreeNodeBase {
58 friend class PostDominatorTree;
59 friend class DominatorTreeBase<NodeT, false>;
60 friend class DominatorTreeBase<NodeT, true>;
63
64 NodeT *TheBB;
65 DomTreeNodeBase *IDom;
66 unsigned Level;
67 DomTreeNodeBase *FirstChild = nullptr;
68 DomTreeNodeBase *Sibling = nullptr;
69 DomTreeNodeBase **AppendPtr = &FirstChild;
70 mutable unsigned DFSNumIn = ~0;
71 mutable unsigned DFSNumOut = ~0;
72
73 public:
75 : TheBB(BB), IDom(iDom), Level(IDom ? IDom->Level + 1 : 0) {}
76
79
81 : public iterator_facade_base<const_iterator, std::forward_iterator_tag,
82 DomTreeNodeBase *> {
83 DomTreeNodeBase *Node;
84
85 public:
86 const_iterator(DomTreeNodeBase *Node = nullptr) : Node(Node) {}
87 bool operator==(const const_iterator &Other) const {
88 return Other.Node == Node;
89 }
90 DomTreeNodeBase *operator*() const { return Node; }
92 Node = Node->Sibling;
93 return *this;
94 }
96 const_iterator cp = *this;
97 ++*this;
98 return cp;
99 }
100 };
101 // We don't permit modifications through the iterator.
102 using iterator = const_iterator;
103
104 iterator begin() const { return iterator{FirstChild}; }
105 iterator end() const { return iterator{}; }
106
109 return make_range(begin(), end());
110 }
111
112 NodeT *getBlock() const { return TheBB; }
113 DomTreeNodeBase *getIDom() const { return IDom; }
114 unsigned getLevel() const { return Level; }
115
116 // TODO: make these private once NewGVN doesn't require these anymore.
118 assert(!C->Sibling && "cannot add child that already has siblings");
119 assert(!*AppendPtr && "sibling of last child must be nullptr");
120 *AppendPtr = C;
121 AppendPtr = &C->Sibling;
122 }
123
124 // TODO: make these private once NewGVN doesn't require these anymore.
126 DomTreeNodeBase **It = &FirstChild;
127 while (*It != C) {
128 assert(*It != nullptr && "Not in immediate dominator children list!");
129 It = &(*It)->Sibling;
130 }
131 assert(!*AppendPtr && "sibling of last child must be nullptr");
132 assert(C->Sibling || AppendPtr == &C->Sibling);
133 *It = C->Sibling;
134 if (C->Sibling)
135 C->Sibling = nullptr;
136 else
137 AppendPtr = It;
138 }
139
140 bool isLeaf() const { return FirstChild == nullptr; }
141
142 bool compare(const DomTreeNodeBase *Other) const {
143 if (Level != Other->Level) return true;
144
145 SmallPtrSet<const NodeT *, 4> OtherChildren;
146 for (const DomTreeNodeBase *I : *Other) {
147 const NodeT *Nd = I->getBlock();
148 OtherChildren.insert(Nd);
149 }
150
151 size_t OwnCount = 0;
152 for (const DomTreeNodeBase *I : *this) {
153 const NodeT *N = I->getBlock();
154 if (OtherChildren.count(N) == 0)
155 return true;
156 ++OwnCount;
157 }
158 return OwnCount != OtherChildren.size();
159 }
160
161 void setIDom(DomTreeNodeBase *NewIDom) {
162 assert(IDom && "No immediate dominator?");
163 if (IDom == NewIDom) return;
164 IDom->removeChild(this);
165
166 // Switch to new dominator
167 IDom = NewIDom;
168 IDom->addChild(this);
169
170 UpdateLevel();
171 }
172
173 /// getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes
174 /// in the dominator tree. They are only guaranteed valid if
175 /// updateDFSNumbers() has been called.
176 unsigned getDFSNumIn() const { return DFSNumIn; }
177 unsigned getDFSNumOut() const { return DFSNumOut; }
178
179private:
180 // Return true if this node is dominated by other. Use this only if DFS info
181 // is valid.
182 bool DominatedBy(const DomTreeNodeBase *other) const {
183 return this->DFSNumIn >= other->DFSNumIn &&
184 this->DFSNumOut <= other->DFSNumOut;
185 }
186
187 void UpdateLevel() {
188 assert(IDom);
189 if (Level == IDom->Level + 1) return;
190
191 SmallVector<DomTreeNodeBase *, 64> WorkStack = {this};
192
193 while (!WorkStack.empty()) {
194 DomTreeNodeBase *Current = WorkStack.pop_back_val();
195 Current->Level = Current->IDom->Level + 1;
196
197 for (DomTreeNodeBase *C : *Current) {
198 assert(C->IDom);
199 if (C->Level != C->IDom->Level + 1) WorkStack.push_back(C);
200 }
201 }
202 }
203};
204
205template <class NodeT>
207 if (Node->getBlock())
208 Node->getBlock()->printAsOperand(O, false);
209 else
210 O << " <<exit node>>";
211
212 O << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "} ["
213 << Node->getLevel() << "]\n";
214
215 return O;
216}
217
218template <class NodeT>
220 unsigned Lev) {
221 O.indent(2 * Lev) << "[" << Lev << "] " << N;
222 for (const auto &I : *N)
223 PrintDomTree<NodeT>(I, O, Lev + 1);
224}
225
226namespace DomTreeBuilder {
227// The routines below are provided in a separate header but referenced here.
228template <typename DomTreeT>
229void Calculate(DomTreeT &DT);
230
231template <typename DomTreeT>
232void CalculateWithUpdates(DomTreeT &DT,
234
235template <typename DomTreeT>
236void InsertEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
237 typename DomTreeT::NodePtr To);
238
239template <typename DomTreeT>
240void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
241 typename DomTreeT::NodePtr To);
242
243template <typename DomTreeT>
244void ApplyUpdates(DomTreeT &DT,
245 GraphDiff<typename DomTreeT::NodePtr,
246 DomTreeT::IsPostDominator> &PreViewCFG,
247 GraphDiff<typename DomTreeT::NodePtr,
248 DomTreeT::IsPostDominator> *PostViewCFG);
249
250template <typename DomTreeT>
251bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL);
252} // namespace DomTreeBuilder
253
254/// Default DomTreeNode traits for NodeT. The default implementation assume a
255/// Function-like NodeT. Can be specialized to support different node types.
256template <typename NodeT> struct DomTreeNodeTraits {
257 using NodeType = NodeT;
258 using NodePtr = NodeT *;
259 using ParentPtr = decltype(std::declval<NodePtr>()->getParent());
260 static_assert(std::is_pointer_v<ParentPtr>,
261 "Currently NodeT's parent must be a pointer type");
262 using ParentType = std::remove_pointer_t<ParentPtr>;
263
264 static NodeT *getEntryNode(ParentPtr Parent) { return &Parent->front(); }
265 static ParentPtr getParent(NodePtr BB) { return BB->getParent(); }
266};
267
268/// Core dominator tree base class.
269///
270/// This class is a generic template over graph nodes. It is instantiated for
271/// various graphs in the LLVM IR or in the code generator.
272template <typename NodeT, bool IsPostDom> class DominatorTreeBase {
273public:
274 static_assert(GraphHasNodeNumbers<NodeT *>,
275 "DominatorTreeBase requires graphs with numbered nodes");
276 static_assert(std::is_pointer_v<typename GraphTraits<NodeT *>::NodeRef>,
277 "Currently DominatorTreeBase supports only pointer nodes");
280 using NodePtr = typename NodeTrait::NodePtr;
282 static_assert(std::is_pointer_v<ParentPtr>,
283 "Currently NodeT's parent must be a pointer type");
284 using ParentType = std::remove_pointer_t<ParentPtr>;
285 static constexpr bool IsPostDominator = IsPostDom;
286
289 static constexpr UpdateKind Insert = UpdateKind::Insert;
290 static constexpr UpdateKind Delete = UpdateKind::Delete;
291
293
294protected:
295 // Dominators always have a single root, postdominators can have more.
297
301 ParentPtr Parent = nullptr;
302
303 // Use small slab size to reduce memory waste for modules with many small
304 // functions. Compensate with a short GrowthDelay. This is relevant for
305 // ThinLTO on modules with many functions (not uncommon in C++), where all
306 // dominator trees are live at the same time.
307 static constexpr size_t SlabSize = 8 * sizeof(DomTreeNodeBase<NodeT>);
309 /*GrowthDelay=*/2>
311
312 mutable bool DFSInfoValid = false;
313 mutable unsigned int SlowQueries = 0;
314 unsigned BlockNumberEpoch = 0;
315
317 template <class BlockT, class LoopT> friend class LoopInfoBase;
318
319public:
320 DominatorTreeBase() = default;
321
324
327
328 /// Iteration over roots.
329 ///
330 /// This may include multiple blocks if we are computing post dominators.
331 /// For forward dominators, this will always be a single block (the entry
332 /// block).
335
336 root_iterator root_begin() { return Roots.begin(); }
337 const_root_iterator root_begin() const { return Roots.begin(); }
338 root_iterator root_end() { return Roots.end(); }
339 const_root_iterator root_end() const { return Roots.end(); }
340
341 size_t root_size() const { return Roots.size(); }
342
349
350 /// isPostDominator - Returns true if analysis based of postdoms
351 ///
352 bool isPostDominator() const { return IsPostDominator; }
353
354 /// compare - Return false if the other dominator tree base matches this
355 /// dominator tree base. Otherwise return true.
356 bool compare(const DominatorTreeBase &Other) const {
357 if (Parent != Other.Parent) return true;
358
359 if (Roots.size() != Other.Roots.size())
360 return true;
361
362 if (!std::is_permutation(Roots.begin(), Roots.end(), Other.Roots.begin()))
363 return true;
364
365 size_t NumNodes = 0;
366 // All nodes we have must exist and be equal in the other tree.
367 for (const auto &Node : DomTreeNodes) {
368 if (!Node)
369 continue;
370 if (Node->compare(Other.getNode(Node->getBlock())))
371 return true;
372 NumNodes++;
373 }
374
375 // If the other tree has more nodes than we have, they're not equal.
376 size_t NumOtherNodes = 0;
377 for (const auto &OtherNode : Other.DomTreeNodes)
378 if (OtherNode)
379 NumOtherNodes++;
380 return NumNodes != NumOtherNodes;
381 }
382
383private:
384 // For LoopInfoBase's use in deriving a reverse-preorder traversal.
385 auto nodes() const {
387 return N != nullptr;
388 });
389 }
390
391 unsigned getNodeIndex(const NodeT *BB) const {
392 assert(BlockNumberEpoch == GraphTraits<ParentPtr>::getNumberEpoch(Parent) &&
393 "dominator tree used with outdated block numbers");
394 if constexpr (IsPostDom) {
395 if (!BB)
396 return 0; // BB may be nullptr for post-dominator tree, map to 0.
397 } else
398 assert(BB && "dominator tree block must be non-null");
399 return GraphTraits<const NodeT *>::getNumber(BB) + IsPostDom;
400 }
401
402public:
403 /// getNode - return the (Post)DominatorTree node for the specified basic
404 /// block. This is the same as using operator[] on this class. The result
405 /// may (but is not required to) be null for a forward (backwards)
406 /// statically unreachable block.
407 DomTreeNodeBase<NodeT> *getNode(const NodeT *BB) const {
408 assert((!BB || Parent == NodeTrait::getParent(const_cast<NodeT *>(BB))) &&
409 "cannot get DomTreeNode of block with different parent");
410 if (unsigned Idx = getNodeIndex(BB); Idx < DomTreeNodes.size())
411 return DomTreeNodes[Idx];
412 return nullptr;
413 }
414
415 /// See getNode.
416 DomTreeNodeBase<NodeT> *operator[](const NodeT *BB) const {
417 return getNode(BB);
418 }
419
420 /// getRootNode - This returns the entry node for the CFG of the function. If
421 /// this tree represents the post-dominance relations for a function, however,
422 /// this root may be a node with the block == NULL. This is the case when
423 /// there are multiple exit nodes from a particular function. Consumers of
424 /// post-dominance information must be capable of dealing with this
425 /// possibility.
426 ///
428 const DomTreeNodeBase<NodeT> *getRootNode() const { return RootNode; }
429
430 /// Get all nodes dominated by R, including R itself.
431 void getDescendants(NodeT *R, SmallVectorImpl<NodeT *> &Result) const {
432 Result.clear();
433 const DomTreeNodeBase<NodeT> *RN = getNode(R);
434 if (!RN)
435 return; // If R is unreachable, it will not be present in the DOM tree.
437 WL.push_back(RN);
438
439 while (!WL.empty()) {
441 Result.push_back(N->getBlock());
442 WL.append(N->begin(), N->end());
443 }
444 }
445
446 /// properlyDominates - Returns true iff A dominates B and A != B.
447 /// Note that this is not a constant time operation!
448 ///
450 const DomTreeNodeBase<NodeT> *B) const {
451 if (!A || !B)
452 return false;
453 if (A == B)
454 return false;
455 return dominates(A, B);
456 }
457
458 bool properlyDominates(const NodeT *A, const NodeT *B) const;
459
460 /// isReachableFromEntry - Return true if A is dominated by the entry
461 /// block of the function containing it.
462 bool isReachableFromEntry(const NodeT *A) const {
463 assert(!this->isPostDominator() &&
464 "This is not implemented for post dominators");
465 return getNode(A) != nullptr;
466 }
467
468 /// dominates - Returns true iff A dominates B. Note that this is not a
469 /// constant time operation!
470 ///
472 const DomTreeNodeBase<NodeT> *B) const {
473 // A node trivially dominates itself.
474 if (B == A)
475 return true;
476
477 // An unreachable node is dominated by anything.
478 if (!B)
479 return true;
480
481 // And dominates nothing.
482 if (!A)
483 return false;
484
485 if (B->getIDom() == A) return true;
486
487 if (A->getIDom() == B) return false;
488
489 // A can only dominate B if it is higher in the tree.
490 if (A->getLevel() >= B->getLevel()) return false;
491
492 // Compare the result of the tree walk and the dfs numbers, if expensive
493 // checks are enabled.
494#ifdef EXPENSIVE_CHECKS
496 (dominatedBySlowTreeWalk(A, B) == B->DominatedBy(A))) &&
497 "Tree walk disagrees with dfs numbers!");
498#endif
499
500 if (DFSInfoValid)
501 return B->DominatedBy(A);
502
503 // If we end up with too many slow queries, just update the
504 // DFS numbers on the theory that we are going to keep querying.
505 SlowQueries++;
506 if (SlowQueries > 32) {
508 return B->DominatedBy(A);
509 }
510
511 return dominatedBySlowTreeWalk(A, B);
512 }
513
514 bool dominates(const NodeT *A, const NodeT *B) const;
515
516 NodeT *getRoot() const {
517 assert(this->Roots.size() == 1 && "Should always have entry node!");
518 return this->Roots[0];
519 }
520
521 /// Find nearest common dominator basic block for basic block A and B. A and B
522 /// must have tree nodes.
523 NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) const {
524 assert(A && B && "Pointers are not valid");
526 "Two blocks are not in same function");
527
528 // If either A or B is a entry block then it is nearest common dominator
529 // (for forward-dominators).
530 if (!isPostDominator()) {
531 NodeT &Entry =
533 if (A == &Entry || B == &Entry)
534 return &Entry;
535 }
536
539 assert(NodeA && "A must be in the tree");
540 assert(NodeB && "B must be in the tree");
541
542 // Use level information to go up the tree until the levels match. Then
543 // continue going up til we arrive at the same node.
544 while (NodeA != NodeB) {
545 if (NodeA->getLevel() < NodeB->getLevel()) std::swap(NodeA, NodeB);
546
547 NodeA = NodeA->IDom;
548 }
549
550 return NodeA->getBlock();
551 }
552
553 const NodeT *findNearestCommonDominator(const NodeT *A,
554 const NodeT *B) const {
555 // Cast away the const qualifiers here. This is ok since
556 // const is re-introduced on the return type.
557 return findNearestCommonDominator(const_cast<NodeT *>(A),
558 const_cast<NodeT *>(B));
559 }
560
562 return isPostDominator() && !A->getBlock();
563 }
564
565 template <typename IteratorTy>
567 assert(!Nodes.empty() && "Nodes list is empty!");
568
569 NodeT *NCD = *Nodes.begin();
570 for (NodeT *Node : llvm::drop_begin(Nodes)) {
572
573 // Stop when the root is reached.
574 if (isVirtualRoot(getNode(NCD)))
575 return nullptr;
576 }
577
578 return NCD;
579 }
580
581 //===--------------------------------------------------------------------===//
582 // API to update (Post)DominatorTree information based on modifications to
583 // the CFG...
584
585 /// Inform the dominator tree about a sequence of CFG edge insertions and
586 /// deletions and perform a batch update on the tree.
587 ///
588 /// This function should be used when there were multiple CFG updates after
589 /// the last dominator tree update. It takes care of performing the updates
590 /// in sync with the CFG and optimizes away the redundant operations that
591 /// cancel each other.
592 /// The functions expects the sequence of updates to be balanced. Eg.:
593 /// - {{Insert, A, B}, {Delete, A, B}, {Insert, A, B}} is fine, because
594 /// logically it results in a single insertions.
595 /// - {{Insert, A, B}, {Insert, A, B}} is invalid, because it doesn't make
596 /// sense to insert the same edge twice.
597 ///
598 /// What's more, the functions assumes that it's safe to ask every node in the
599 /// CFG about its children and inverse children. This implies that deletions
600 /// of CFG edges must not delete the CFG nodes before calling this function.
601 ///
602 /// The applyUpdates function can reorder the updates and remove redundant
603 /// ones internally (as long as it is done in a deterministic fashion). The
604 /// batch updater is also able to detect sequences of zero and exactly one
605 /// update -- it's optimized to do less work in these cases.
606 ///
607 /// Note that for postdominators it automatically takes care of applying
608 /// updates on reverse edges internally (so there's no need to swap the
609 /// From and To pointers when constructing DominatorTree::UpdateType).
610 /// The type of updates is the same for DomTreeBase<T> and PostDomTreeBase<T>
611 /// with the same template parameter T.
612 ///
613 /// \param Updates An ordered sequence of updates to perform. The current CFG
614 /// and the reverse of these updates provides the pre-view of the CFG.
615 ///
617
618 /// \param Updates An ordered sequence of updates to perform. The current CFG
619 /// and the reverse of these updates provides the pre-view of the CFG.
620 /// \param PostViewUpdates An ordered sequence of update to perform in order
621 /// to obtain a post-view of the CFG. The DT will be updated assuming the
622 /// obtained PostViewCFG is the desired end state.
624 ArrayRef<UpdateType> PostViewUpdates);
625
626 /// Inform the dominator tree about a CFG edge insertion and update the tree.
627 ///
628 /// This function has to be called just before or just after making the update
629 /// on the actual CFG. There cannot be any other updates that the dominator
630 /// tree doesn't know about.
631 ///
632 /// Note that for postdominators it automatically takes care of inserting
633 /// a reverse edge internally (so there's no need to swap the parameters).
634 ///
635 void insertEdge(NodeT *From, NodeT *To);
636
637 /// Inform the dominator tree about a CFG edge deletion and update the tree.
638 ///
639 /// This function has to be called just after making the update on the actual
640 /// CFG. An internal functions checks if the edge doesn't exist in the CFG in
641 /// DEBUG mode. There cannot be any other updates that the
642 /// dominator tree doesn't know about.
643 ///
644 /// Note that for postdominators it automatically takes care of deleting
645 /// a reverse edge internally (so there's no need to swap the parameters).
646 ///
647 void deleteEdge(NodeT *From, NodeT *To);
648
649 /// Add a new node to the dominator tree information.
650 ///
651 /// This creates a new node as a child of DomBB dominator node, linking it
652 /// into the children list of the immediate dominator.
653 ///
654 /// \param BB New node in CFG.
655 /// \param DomBB CFG node that is dominator for BB.
656 /// \returns New dominator tree node that represents new CFG node.
657 ///
658 DomTreeNodeBase<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) {
659 assert(getNode(BB) == nullptr && "Block already in dominator tree!");
660 DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
661 assert(IDomNode && "Not immediate dominator specified for block!");
662 DFSInfoValid = false;
663 return createNode(BB, IDomNode);
664 }
665
666 /// Add a new node to the forward dominator tree and make it a new root.
667 ///
668 /// \param BB New node in CFG.
669 /// \returns New dominator tree node that represents new CFG node.
670 ///
672 assert(getNode(BB) == nullptr && "Block already in dominator tree!");
673 assert(!this->isPostDominator() &&
674 "Cannot change root of post-dominator tree");
675 DFSInfoValid = false;
676 DomTreeNodeBase<NodeT> *NewNode = createNode(BB);
677 if (Roots.empty()) {
678 addRoot(BB);
679 } else {
680 assert(Roots.size() == 1);
681 NodeT *OldRoot = Roots.front();
682 DomTreeNodeBase<NodeT> *OldNode = getNode(OldRoot);
683 NewNode->addChild(OldNode);
684 OldNode->IDom = NewNode;
685 OldNode->UpdateLevel();
686 Roots[0] = BB;
687 }
688 return RootNode = NewNode;
689 }
690
691 /// changeImmediateDominator - This method is used to update the dominator
692 /// tree information when a node's immediate dominator changes.
693 ///
695 DomTreeNodeBase<NodeT> *NewIDom) {
696 assert(N && NewIDom && "Cannot change null node pointers!");
697 DFSInfoValid = false;
698 N->setIDom(NewIDom);
699 }
700
701 void changeImmediateDominator(NodeT *BB, NodeT *NewBB) {
703 }
704
705 /// eraseNode - Removes a node from the dominator tree. Block must not
706 /// dominate any other blocks. Removes node from its immediate dominator's
707 /// children list. Deletes dominator node associated with basic block BB.
708 void eraseNode(NodeT *BB) {
709 unsigned Idx = getNodeIndex(BB);
711 assert(Node && "Removing node that isn't in dominator tree.");
712 assert(Node->isLeaf() && "Node is not a leaf node.");
713
714 DFSInfoValid = false;
715
716 // Remove node from immediate dominator's children list.
717 if (DomTreeNodeBase<NodeT> *IDom = Node->getIDom())
718 IDom->removeChild(Node);
719
720 DomTreeNodes[Idx] = nullptr;
721
722 if (!IsPostDom) return;
723
724 // Remember to update PostDominatorTree roots.
725 auto RIt = llvm::find(Roots, BB);
726 if (RIt != Roots.end()) {
727 std::swap(*RIt, Roots.back());
728 Roots.pop_back();
729 }
730 }
731
732 /// splitBlock - BB is split and now it has one successor. Update dominator
733 /// tree to reflect this change.
734 void splitBlock(NodeT *NewBB) {
735 if (IsPostDominator)
737 else
738 Split<NodeT *>(NewBB);
739 }
740
741 /// print - Convert to human readable form
742 ///
743 void print(raw_ostream &O) const {
744 O << "=============================--------------------------------\n";
745 if (IsPostDominator)
746 O << "Inorder PostDominator Tree: ";
747 else
748 O << "Inorder Dominator Tree: ";
749 if (!DFSInfoValid)
750 O << "DFSNumbers invalid: " << SlowQueries << " slow queries.";
751 O << "\n";
752
753 // The postdom tree can have a null root if there are no returns.
755 O << "Roots: ";
756 for (const NodePtr Block : Roots) {
757 Block->printAsOperand(O, false);
758 O << " ";
759 }
760 O << "\n";
761 }
762
763public:
764 /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
765 /// dominator tree in dfs order.
766 void updateDFSNumbers() const {
767 if (DFSInfoValid) {
768 SlowQueries = 0;
769 return;
770 }
771
774 32> WorkStack;
775
776 const DomTreeNodeBase<NodeT> *ThisRoot = getRootNode();
777 assert((!Parent || ThisRoot) && "Empty constructed DomTree");
778 if (!ThisRoot)
779 return;
780
781 // Both dominators and postdominators have a single root node. In the case
782 // case of PostDominatorTree, this node is a virtual root.
783 WorkStack.push_back({ThisRoot, ThisRoot->begin()});
784
785 unsigned DFSNum = 0;
786 ThisRoot->DFSNumIn = DFSNum++;
787
788 while (!WorkStack.empty()) {
789 const DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
790 const auto ChildIt = WorkStack.back().second;
791
792 // If we visited all of the children of this node, "recurse" back up the
793 // stack setting the DFOutNum.
794 if (ChildIt == Node->end()) {
795 Node->DFSNumOut = DFSNum;
796 WorkStack.pop_back();
797 } else {
798 // Otherwise, recursively visit this child.
799 const DomTreeNodeBase<NodeT> *Child = *ChildIt;
800 ++WorkStack.back().second;
801
802 WorkStack.push_back({Child, Child->begin()});
803 Child->DFSNumIn = DFSNum++;
804 }
805 }
806
807 SlowQueries = 0;
808 DFSInfoValid = true;
809 }
810
811private:
812 void updateBlockNumberEpoch() {
814 }
815
816public:
817 /// recalculate - compute a dominator tree for the given function
819
821
822 /// Update dominator tree after renumbering blocks.
824 updateBlockNumberEpoch();
825
826 unsigned MaxNumber = GraphTraits<ParentPtr>::getMaxNumber(Parent);
827 DomTreeNodeStorageTy NewVector;
828 NewVector.resize(MaxNumber + IsPostDom); // index 0 is for nullptr
830 if (Node)
831 NewVector[getNodeIndex(Node->getBlock())] = Node;
832 }
833 DomTreeNodes = std::move(NewVector);
834 }
835
836 /// verify - checks if the tree is correct. There are 3 level of verification:
837 /// - Full -- verifies if the tree is correct by making sure all the
838 /// properties (including the parent and the sibling property)
839 /// hold.
840 /// Takes O(N^3) time.
841 ///
842 /// - Basic -- checks if the tree is correct, but compares it to a freshly
843 /// constructed tree instead of checking the sibling property.
844 /// Takes O(N^2) time.
845 ///
846 /// - Fast -- checks basic tree structure and compares it with a freshly
847 /// constructed tree.
848 /// Takes O(N^2) time worst case, but is faster in practise (same
849 /// as tree construction).
851
852 void reset() {
853 DomTreeNodes.clear();
854 Roots.clear();
855 RootNode = nullptr;
856 Parent = nullptr;
857 DFSInfoValid = false;
858 NodeAllocator.Reset();
859 SlowQueries = 0;
860 }
861
862protected:
863 inline void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
864
866 DomTreeNodeBase<NodeT> *IDom = nullptr) {
867 static_assert(std::is_trivially_destructible_v<DomTreeNodeBase<NodeT>>);
868 auto *Node = new (NodeAllocator) DomTreeNodeBase<NodeT>(BB, IDom);
869 unsigned Idx = getNodeIndex(BB);
870 if (Idx >= DomTreeNodes.size()) {
871 // Add 1 for post-dominator trees, 0 is nullptr block.
872 unsigned Max = GraphTraits<ParentPtr>::getMaxNumber(Parent) + IsPostDom;
873 assert(Idx < Max && "getMaxNumber returned too small value");
874 DomTreeNodes.resize(Max);
875 }
876 DomTreeNodes[Idx] = Node;
877 if (IDom)
878 IDom->addChild(Node);
879 return Node;
880 }
881
882 // NewBB is split and now it has one successor. Update dominator tree to
883 // reflect this change.
884 template <class N>
885 void Split(typename GraphTraits<N>::NodeRef NewBB) {
886 using GraphT = GraphTraits<N>;
887 using NodeRef = typename GraphT::NodeRef;
889 "NewBB should have a single successor!");
890 NodeRef NewBBSucc = *GraphT::child_begin(NewBB);
891
893
894 assert(!PredBlocks.empty() && "No predblocks?");
895
896 bool NewBBDominatesNewBBSucc = true;
897 for (auto *Pred : inverse_children<N>(NewBBSucc)) {
898 if (Pred != NewBB && !dominates(NewBBSucc, Pred) &&
899 isReachableFromEntry(Pred)) {
900 NewBBDominatesNewBBSucc = false;
901 break;
902 }
903 }
904
905 // Find NewBB's immediate dominator and create new dominator tree node for
906 // NewBB.
907 NodeT *NewBBIDom = nullptr;
908 unsigned i = 0;
909 for (i = 0; i < PredBlocks.size(); ++i)
910 if (isReachableFromEntry(PredBlocks[i])) {
911 NewBBIDom = PredBlocks[i];
912 break;
913 }
914
915 // It's possible that none of the predecessors of NewBB are reachable;
916 // in that case, NewBB itself is unreachable, so nothing needs to be
917 // changed.
918 if (!NewBBIDom) return;
919
920 for (i = i + 1; i < PredBlocks.size(); ++i) {
921 if (isReachableFromEntry(PredBlocks[i]))
922 NewBBIDom = findNearestCommonDominator(NewBBIDom, PredBlocks[i]);
923 }
924
925 // Create the new dominator tree node... and set the idom of NewBB.
926 DomTreeNodeBase<NodeT> *NewBBNode = addNewBlock(NewBB, NewBBIDom);
927
928 // If NewBB strictly dominates other blocks, then it is now the immediate
929 // dominator of NewBBSucc. Update the dominator tree as appropriate.
930 if (NewBBDominatesNewBBSucc) {
931 DomTreeNodeBase<NodeT> *NewBBSuccNode = getNode(NewBBSucc);
932 changeImmediateDominator(NewBBSuccNode, NewBBNode);
933 }
934 }
935
936 private:
937 bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
938 const DomTreeNodeBase<NodeT> *B) const {
939 assert(A != B);
940 assert(A && B);
941
942 const unsigned ALevel = A->getLevel();
943 const DomTreeNodeBase<NodeT> *IDom;
944
945 // Don't walk nodes above A's subtree. When we reach A's level, we must
946 // either find A or be in some other subtree not dominated by A.
947 while ((IDom = B->getIDom()) != nullptr && IDom->getLevel() >= ALevel)
948 B = IDom; // Walk up the tree
949
950 return B == A;
951 }
952};
953
954template <typename T>
956
957template <typename T>
959
960// These two functions are declared out of line as a workaround for building
961// with old (< r147295) versions of clang because of pr11642.
962template <typename NodeT, bool IsPostDom>
964 const NodeT *B) const {
965 if (A == B)
966 return true;
967
968 return dominates(getNode(A), getNode(B));
969}
970template <typename NodeT, bool IsPostDom>
972 const NodeT *A, const NodeT *B) const {
973 if (A == B)
974 return false;
975
976 return dominates(getNode(A), getNode(B));
977}
978
979} // end namespace llvm
980
981#endif // LLVM_SUPPORT_GENERICDOMTREE_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
Unify divergent function exit nodes
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseMap class.
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
#define I(x, y, z)
Definition MD5.cpp:57
ppc ctr loops PowerPC CTR Loops Verify
static bool dominates(InstrPosIndexes &PosIndexes, const MachineInstr &A, const MachineInstr &B)
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
Value * RHS
void printAsOperand(OutputBuffer &OB, Prec P=Prec::Default, bool StrictlyWorse=false) const
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition Allocator.h:71
bool operator==(const const_iterator &Other) const
DomTreeNodeBase * operator*() const
const_iterator(DomTreeNodeBase *Node=nullptr)
Base class for the actual dominator tree node.
iterator_range< iterator > children()
DomTreeNodeBase(const DomTreeNodeBase &)=delete
void setIDom(DomTreeNodeBase *NewIDom)
void removeChild(DomTreeNodeBase *C)
DomTreeNodeBase * getIDom() const
unsigned getDFSNumIn() const
getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes in the dominator tree.
iterator begin() const
DomTreeNodeBase & operator=(const DomTreeNodeBase &)=delete
DomTreeNodeBase(NodeT *BB, DomTreeNodeBase *iDom)
bool compare(const DomTreeNodeBase *Other) const
NodeT * getBlock() const
unsigned getLevel() const
iterator end() const
iterator_range< const_iterator > children() const
unsigned getDFSNumOut() const
void addChild(DomTreeNodeBase *C)
Core dominator tree base class.
DominatorTreeBase(DominatorTreeBase &&Arg)=default
DomTreeNodeTraits< BlockT > NodeTrait
void print(raw_ostream &O) const
print - Convert to human readable form
typename NodeTrait::NodeType NodeType
DomTreeNodeBase< NodeT > * operator[](const NodeT *BB) const
See getNode.
typename SmallVectorImpl< BlockT * >::iterator root_iterator
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
void changeImmediateDominator(NodeT *BB, NodeT *NewBB)
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
Find nearest common dominator basic block for basic block A and B.
void Split(typename GraphTraits< N >::NodeRef NewBB)
iterator_range< root_iterator > roots()
void changeImmediateDominator(DomTreeNodeBase< NodeT > *N, DomTreeNodeBase< NodeT > *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
std::remove_pointer_t< ParentPtr > ParentType
NodeT * findNearestCommonDominator(iterator_range< IteratorTy > Nodes) const
BumpPtrAllocatorImpl< MallocAllocator, SlabSize, SlabSize, 2 > NodeAllocator
bool isPostDominator() const
isPostDominator - Returns true if analysis based of postdoms
bool dominates(const NodeT *A, const NodeT *B) const
const NodeT * findNearestCommonDominator(const NodeT *A, const NodeT *B) const
void getDescendants(NodeT *R, SmallVectorImpl< NodeT * > &Result) const
Get all nodes dominated by R, including R itself.
DomTreeNodeBase< NodeT > * addNewBlock(NodeT *BB, NodeT *DomBB)
Add a new node to the dominator tree information.
DomTreeNodeBase< NodeT > * createNode(NodeT *BB, DomTreeNodeBase< NodeT > *IDom=nullptr)
void applyUpdates(ArrayRef< UpdateType > Updates)
Inform the dominator tree about a sequence of CFG edge insertions and deletions and perform a batch u...
void insertEdge(NodeT *From, NodeT *To)
Inform the dominator tree about a CFG edge insertion and update the tree.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
void updateBlockNumbers()
Update dominator tree after renumbering blocks.
iterator_range< const_root_iterator > roots() const
const_root_iterator root_end() const
void splitBlock(NodeT *NewBB)
splitBlock - BB is split and now it has one successor.
void recalculate(ParentType &Func, ArrayRef< UpdateType > Updates)
void updateDFSNumbers() const
updateDFSNumbers - Assign In and Out numbers to the nodes while walking dominator tree in dfs order.
typename SmallVectorImpl< BlockT * >::const_iterator const_root_iterator
bool compare(const DominatorTreeBase &Other) const
compare - Return false if the other dominator tree base matches this dominator tree base.
DominatorTreeBase & operator=(DominatorTreeBase &&RHS)=default
DomTreeNodeBase< NodeT > * setNewRoot(NodeT *BB)
Add a new node to the forward dominator tree and make it a new root.
SmallVector< DomTreeNodeBase< BlockT > * > DomTreeNodeStorageTy
root_iterator root_begin()
DominatorTreeBase(const DominatorTreeBase &)=delete
const_root_iterator root_begin() const
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
SmallVector< BlockT *, IsPostDom ? 4 :1 > Roots
void eraseNode(NodeT *BB)
eraseNode - Removes a node from the dominator tree.
void deleteEdge(NodeT *From, NodeT *To)
Inform the dominator tree about a CFG edge deletion and update the tree.
const DomTreeNodeBase< NodeT > * getRootNode() const
DomTreeNodeBase< BlockT > * RootNode
typename NodeTrait::NodePtr NodePtr
bool isReachableFromEntry(const NodeT *A) const
isReachableFromEntry - Return true if A is dominated by the entry block of the function containing it...
void applyUpdates(ArrayRef< UpdateType > Updates, ArrayRef< UpdateType > PostViewUpdates)
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
bool properlyDominates(const NodeT *A, const NodeT *B) const
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
bool isVirtualRoot(const DomTreeNodeBase< NodeT > *A) const
typename NodeTrait::ParentPtr ParentPtr
DominatorTreeBase & operator=(const DominatorTreeBase &)=delete
This class builds and contains all of the top-level loop structures in the specified function.
size_type size() const
Definition SmallPtrSet.h:99
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
typename SuperClass::const_iterator const_iterator
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
typename SuperClass::iterator iterator
void resize(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition iterator.h:80
A range adaptor for a pair of iterators.
IteratorT begin() const
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
void CalculateWithUpdates(DomTreeT &DT, ArrayRef< typename DomTreeT::UpdateType > Updates)
void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From, typename DomTreeT::NodePtr To)
void ApplyUpdates(DomTreeT &DT, GraphDiff< typename DomTreeT::NodePtr, DomTreeT::IsPostDominator > &PreViewCFG, GraphDiff< typename DomTreeT::NodePtr, DomTreeT::IsPostDominator > *PostViewCFG)
void InsertEdge(DomTreeT &DT, typename DomTreeT::NodePtr From, typename DomTreeT::NodePtr To)
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1765
void PrintDomTree(const DomTreeNodeBase< NodeT > *N, raw_ostream &O, unsigned Lev)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
constexpr bool GraphHasNodeNumbers
Indicate whether a GraphTraits<NodeT>::getNumber() is supported.
DominatorTreeBase< T, true > PostDomTreeBase
DominatorTreeBase< T, false > DomTreeBase
bool hasSingleElement(ContainerTy &&C)
Returns true if the given container only contains a single element.
Definition STLExtras.h:299
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
Definition STLExtras.h:551
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ Other
Any other memory.
Definition ModRef.h:68
iterator_range< typename GraphTraits< Inverse< GraphType > >::ChildIteratorType > inverse_children(const typename GraphTraits< GraphType >::NodeRef &G)
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
ArrayRef(const T &OneElt) -> ArrayRef< T >
iterator_range< typename GraphTraits< GraphType >::ChildIteratorType > children(const typename GraphTraits< GraphType >::NodeRef &G)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
Default DomTreeNode traits for NodeT.
static NodeT * getEntryNode(ParentPtr Parent)
std::remove_pointer_t< ParentPtr > ParentType
static ParentPtr getParent(NodePtr BB)
decltype(std::declval< NodePtr >() ->getParent()) ParentPtr
typename GraphType::UnknownGraphTypeError NodeRef
Definition GraphTraits.h:95