LLVM 23.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
49namespace DomTreeBuilder {
50template <typename DomTreeT>
51struct SemiNCAInfo;
52} // namespace DomTreeBuilder
53
54/// Base class for the actual dominator tree node.
55template <class NodeT> class DomTreeNodeBase {
56 friend class PostDominatorTree;
57 friend class DominatorTreeBase<NodeT, false>;
58 friend class DominatorTreeBase<NodeT, true>;
61
62 NodeT *TheBB;
63 DomTreeNodeBase *IDom;
64 unsigned Level;
65 DomTreeNodeBase *FirstChild = nullptr;
66 DomTreeNodeBase *Sibling = nullptr;
67 DomTreeNodeBase **AppendPtr = &FirstChild;
68 mutable unsigned DFSNumIn = ~0;
69 mutable unsigned DFSNumOut = ~0;
70
71 public:
73 : TheBB(BB), IDom(iDom), Level(IDom ? IDom->Level + 1 : 0) {}
74
77
79 : public iterator_facade_base<const_iterator, std::forward_iterator_tag,
80 DomTreeNodeBase *> {
81 DomTreeNodeBase *Node;
82
83 public:
84 const_iterator(DomTreeNodeBase *Node = nullptr) : Node(Node) {}
85 bool operator==(const const_iterator &Other) const {
86 return Other.Node == Node;
87 }
88 DomTreeNodeBase *operator*() const { return Node; }
90 Node = Node->Sibling;
91 return *this;
92 }
94 const_iterator cp = *this;
95 ++*this;
96 return cp;
97 }
98 };
99 // We don't permit modifications through the iterator.
100 using iterator = const_iterator;
101
102 iterator begin() const { return iterator{FirstChild}; }
103 iterator end() const { return iterator{}; }
104
107 return make_range(begin(), end());
108 }
109
110 NodeT *getBlock() const { return TheBB; }
111 DomTreeNodeBase *getIDom() const { return IDom; }
112 unsigned getLevel() const { return Level; }
113
114 // TODO: make these private once NewGVN doesn't require these anymore.
116 assert(!C->Sibling && "cannot add child that already has siblings");
117 assert(!*AppendPtr && "sibling of last child must be nullptr");
118 *AppendPtr = C;
119 AppendPtr = &C->Sibling;
120 }
121
122 // TODO: make these private once NewGVN doesn't require these anymore.
124 DomTreeNodeBase **It = &FirstChild;
125 while (*It != C) {
126 assert(*It != nullptr && "Not in immediate dominator children list!");
127 It = &(*It)->Sibling;
128 }
129 assert(!*AppendPtr && "sibling of last child must be nullptr");
130 assert(C->Sibling || AppendPtr == &C->Sibling);
131 *It = C->Sibling;
132 if (C->Sibling)
133 C->Sibling = nullptr;
134 else
135 AppendPtr = It;
136 }
137
138 bool isLeaf() const { return FirstChild == nullptr; }
139
140 bool compare(const DomTreeNodeBase *Other) const {
141 if (Level != Other->Level) return true;
142
143 SmallPtrSet<const NodeT *, 4> OtherChildren;
144 for (const DomTreeNodeBase *I : *Other) {
145 const NodeT *Nd = I->getBlock();
146 OtherChildren.insert(Nd);
147 }
148
149 size_t OwnCount = 0;
150 for (const DomTreeNodeBase *I : *this) {
151 const NodeT *N = I->getBlock();
152 if (OtherChildren.count(N) == 0)
153 return true;
154 ++OwnCount;
155 }
156 return OwnCount != OtherChildren.size();
157 }
158
159 void setIDom(DomTreeNodeBase *NewIDom) {
160 assert(IDom && "No immediate dominator?");
161 if (IDom == NewIDom) return;
162 IDom->removeChild(this);
163
164 // Switch to new dominator
165 IDom = NewIDom;
166 IDom->addChild(this);
167
168 UpdateLevel();
169 }
170
171 /// getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes
172 /// in the dominator tree. They are only guaranteed valid if
173 /// updateDFSNumbers() has been called.
174 unsigned getDFSNumIn() const { return DFSNumIn; }
175 unsigned getDFSNumOut() const { return DFSNumOut; }
176
177private:
178 // Return true if this node is dominated by other. Use this only if DFS info
179 // is valid.
180 bool DominatedBy(const DomTreeNodeBase *other) const {
181 return this->DFSNumIn >= other->DFSNumIn &&
182 this->DFSNumOut <= other->DFSNumOut;
183 }
184
185 void UpdateLevel() {
186 assert(IDom);
187 if (Level == IDom->Level + 1) return;
188
189 SmallVector<DomTreeNodeBase *, 64> WorkStack = {this};
190
191 while (!WorkStack.empty()) {
192 DomTreeNodeBase *Current = WorkStack.pop_back_val();
193 Current->Level = Current->IDom->Level + 1;
194
195 for (DomTreeNodeBase *C : *Current) {
196 assert(C->IDom);
197 if (C->Level != C->IDom->Level + 1) WorkStack.push_back(C);
198 }
199 }
200 }
201};
202
203template <class NodeT>
205 if (Node->getBlock())
206 Node->getBlock()->printAsOperand(O, false);
207 else
208 O << " <<exit node>>";
209
210 O << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "} ["
211 << Node->getLevel() << "]\n";
212
213 return O;
214}
215
216template <class NodeT>
218 unsigned Lev) {
219 O.indent(2 * Lev) << "[" << Lev << "] " << N;
220 for (const auto &I : *N)
221 PrintDomTree<NodeT>(I, O, Lev + 1);
222}
223
224namespace DomTreeBuilder {
225// The routines below are provided in a separate header but referenced here.
226template <typename DomTreeT>
227void Calculate(DomTreeT &DT);
228
229template <typename DomTreeT>
230void CalculateWithUpdates(DomTreeT &DT,
232
233template <typename DomTreeT>
234void InsertEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
235 typename DomTreeT::NodePtr To);
236
237template <typename DomTreeT>
238void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
239 typename DomTreeT::NodePtr To);
240
241template <typename DomTreeT>
242void ApplyUpdates(DomTreeT &DT,
243 GraphDiff<typename DomTreeT::NodePtr,
244 DomTreeT::IsPostDominator> &PreViewCFG,
245 GraphDiff<typename DomTreeT::NodePtr,
246 DomTreeT::IsPostDominator> *PostViewCFG);
247
248template <typename DomTreeT>
249bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL);
250} // namespace DomTreeBuilder
251
252/// Default DomTreeNode traits for NodeT. The default implementation assume a
253/// Function-like NodeT. Can be specialized to support different node types.
254template <typename NodeT> struct DomTreeNodeTraits {
255 using NodeType = NodeT;
256 using NodePtr = NodeT *;
257 using ParentPtr = decltype(std::declval<NodePtr>()->getParent());
258 static_assert(std::is_pointer_v<ParentPtr>,
259 "Currently NodeT's parent must be a pointer type");
260 using ParentType = std::remove_pointer_t<ParentPtr>;
261
262 static NodeT *getEntryNode(ParentPtr Parent) { return &Parent->front(); }
263 static ParentPtr getParent(NodePtr BB) { return BB->getParent(); }
264};
265
266/// Core dominator tree base class.
267///
268/// This class is a generic template over graph nodes. It is instantiated for
269/// various graphs in the LLVM IR or in the code generator.
270template <typename NodeT, bool IsPostDom>
272 public:
273 static_assert(std::is_pointer_v<typename GraphTraits<NodeT *>::NodeRef>,
274 "Currently DominatorTreeBase supports only pointer nodes");
277 using NodePtr = typename NodeTrait::NodePtr;
279 static_assert(std::is_pointer_v<ParentPtr>,
280 "Currently NodeT's parent must be a pointer type");
281 using ParentType = std::remove_pointer_t<ParentPtr>;
282 static constexpr bool IsPostDominator = IsPostDom;
283
286 static constexpr UpdateKind Insert = UpdateKind::Insert;
287 static constexpr UpdateKind Delete = UpdateKind::Delete;
288
290
291protected:
292 // Dominators always have a single root, postdominators can have more.
294
297 // For graphs where blocks don't have numbers, create a numbering here.
298 // TODO: use an empty struct with [[no_unique_address]] in C++20.
299 std::conditional_t<!GraphHasNodeNumbers<NodeT *>,
303 ParentPtr Parent = nullptr;
304
305 // Use small slab size to reduce memory waste for modules with many small
306 // functions. Compensate with a short GrowthDelay. This is relevant for
307 // ThinLTO on modules with many functions (not uncommon in C++), where all
308 // dominator trees are live at the same time.
309 static constexpr size_t SlabSize = 8 * sizeof(DomTreeNodeBase<NodeT>);
311 /*GrowthDelay=*/2>
313
314 mutable bool DFSInfoValid = false;
315 mutable unsigned int SlowQueries = 0;
316 unsigned BlockNumberEpoch = 0;
317
319
320 public:
321 DominatorTreeBase() = default;
322
325
328
329 /// Iteration over roots.
330 ///
331 /// This may include multiple blocks if we are computing post dominators.
332 /// For forward dominators, this will always be a single block (the entry
333 /// block).
336
337 root_iterator root_begin() { return Roots.begin(); }
338 const_root_iterator root_begin() const { return Roots.begin(); }
339 root_iterator root_end() { return Roots.end(); }
340 const_root_iterator root_end() const { return Roots.end(); }
341
342 size_t root_size() const { return Roots.size(); }
343
350
351 /// isPostDominator - Returns true if analysis based of postdoms
352 ///
353 bool isPostDominator() const { return IsPostDominator; }
354
355 /// compare - Return false if the other dominator tree base matches this
356 /// dominator tree base. Otherwise return true.
357 bool compare(const DominatorTreeBase &Other) const {
358 if (Parent != Other.Parent) return true;
359
360 if (Roots.size() != Other.Roots.size())
361 return true;
362
363 if (!std::is_permutation(Roots.begin(), Roots.end(), Other.Roots.begin()))
364 return true;
365
366 size_t NumNodes = 0;
367 // All nodes we have must exist and be equal in the other tree.
368 for (const auto &Node : DomTreeNodes) {
369 if (!Node)
370 continue;
371 if (Node->compare(Other.getNode(Node->getBlock())))
372 return true;
373 NumNodes++;
374 }
375
376 // If the other tree has more nodes than we have, they're not equal.
377 size_t NumOtherNodes = 0;
378 for (const auto &OtherNode : Other.DomTreeNodes)
379 if (OtherNode)
380 NumOtherNodes++;
381 return NumNodes != NumOtherNodes;
382 }
383
384private:
385 std::optional<unsigned> getNodeIndex(const NodeT *BB) const {
386 if constexpr (GraphHasNodeNumbers<NodeT *>) {
389 "dominator tree used with outdated block numbers");
390 if constexpr (IsPostDom) {
391 if (!BB)
392 return 0; // BB may be nullptr for post-dominator tree, map to 0.
393 } else
394 assert(BB && "dominator tree block must be non-null");
395 return GraphTraits<const NodeT *>::getNumber(BB) + 1;
396 } else {
397 if (auto It = NodeNumberMap.find(BB); It != NodeNumberMap.end())
398 return It->second;
399 return std::nullopt;
400 }
401 }
402
403 unsigned getNodeIndexForInsert(const NodeT *BB) {
404 if constexpr (GraphHasNodeNumbers<NodeT *>) {
405 // getNodeIndex will never fail if nodes have getNumber().
406 unsigned Idx = *getNodeIndex(BB);
407 if (Idx >= DomTreeNodes.size()) {
408 unsigned Max = GraphTraits<ParentPtr>::getMaxNumber(Parent);
409 DomTreeNodes.resize(Max > Idx + 1 ? Max : Idx + 1);
410 }
411 return Idx;
412 } else {
413 // We might already have a number stored for BB.
414 unsigned Idx =
415 NodeNumberMap.try_emplace(BB, DomTreeNodes.size()).first->second;
416 if (Idx >= DomTreeNodes.size())
417 DomTreeNodes.resize(Idx + 1);
418 return Idx;
419 }
420 }
421
422public:
423 /// getNode - return the (Post)DominatorTree node for the specified basic
424 /// block. This is the same as using operator[] on this class. The result
425 /// may (but is not required to) be null for a forward (backwards)
426 /// statically unreachable block.
427 DomTreeNodeBase<NodeT> *getNode(const NodeT *BB) const {
428 assert((!BB || Parent == NodeTrait::getParent(const_cast<NodeT *>(BB))) &&
429 "cannot get DomTreeNode of block with different parent");
430 if (auto Idx = getNodeIndex(BB); Idx && *Idx < DomTreeNodes.size())
431 return DomTreeNodes[*Idx];
432 return nullptr;
433 }
434
435 /// See getNode.
436 DomTreeNodeBase<NodeT> *operator[](const NodeT *BB) const {
437 return getNode(BB);
438 }
439
440 /// getRootNode - This returns the entry node for the CFG of the function. If
441 /// this tree represents the post-dominance relations for a function, however,
442 /// this root may be a node with the block == NULL. This is the case when
443 /// there are multiple exit nodes from a particular function. Consumers of
444 /// post-dominance information must be capable of dealing with this
445 /// possibility.
446 ///
448 const DomTreeNodeBase<NodeT> *getRootNode() const { return RootNode; }
449
450 /// Get all nodes dominated by R, including R itself.
451 void getDescendants(NodeT *R, SmallVectorImpl<NodeT *> &Result) const {
452 Result.clear();
453 const DomTreeNodeBase<NodeT> *RN = getNode(R);
454 if (!RN)
455 return; // If R is unreachable, it will not be present in the DOM tree.
457 WL.push_back(RN);
458
459 while (!WL.empty()) {
461 Result.push_back(N->getBlock());
462 WL.append(N->begin(), N->end());
463 }
464 }
465
466 /// properlyDominates - Returns true iff A dominates B and A != B.
467 /// Note that this is not a constant time operation!
468 ///
470 const DomTreeNodeBase<NodeT> *B) const {
471 if (!A || !B)
472 return false;
473 if (A == B)
474 return false;
475 return dominates(A, B);
476 }
477
478 bool properlyDominates(const NodeT *A, const NodeT *B) const;
479
480 /// isReachableFromEntry - Return true if A is dominated by the entry
481 /// block of the function containing it.
482 bool isReachableFromEntry(const NodeT *A) const {
483 assert(!this->isPostDominator() &&
484 "This is not implemented for post dominators");
485 return isReachableFromEntry(getNode(A));
486 }
487
488 bool isReachableFromEntry(const DomTreeNodeBase<NodeT> *A) const { return A; }
489
490 /// dominates - Returns true iff A dominates B. Note that this is not a
491 /// constant time operation!
492 ///
494 const DomTreeNodeBase<NodeT> *B) const {
495 // A node trivially dominates itself.
496 if (B == A)
497 return true;
498
499 // An unreachable node is dominated by anything.
501 return true;
502
503 // And dominates nothing.
505 return false;
506
507 if (B->getIDom() == A) return true;
508
509 if (A->getIDom() == B) return false;
510
511 // A can only dominate B if it is higher in the tree.
512 if (A->getLevel() >= B->getLevel()) return false;
513
514 // Compare the result of the tree walk and the dfs numbers, if expensive
515 // checks are enabled.
516#ifdef EXPENSIVE_CHECKS
518 (dominatedBySlowTreeWalk(A, B) == B->DominatedBy(A))) &&
519 "Tree walk disagrees with dfs numbers!");
520#endif
521
522 if (DFSInfoValid)
523 return B->DominatedBy(A);
524
525 // If we end up with too many slow queries, just update the
526 // DFS numbers on the theory that we are going to keep querying.
527 SlowQueries++;
528 if (SlowQueries > 32) {
530 return B->DominatedBy(A);
531 }
532
533 return dominatedBySlowTreeWalk(A, B);
534 }
535
536 bool dominates(const NodeT *A, const NodeT *B) const;
537
538 NodeT *getRoot() const {
539 assert(this->Roots.size() == 1 && "Should always have entry node!");
540 return this->Roots[0];
541 }
542
543 /// Find nearest common dominator basic block for basic block A and B. A and B
544 /// must have tree nodes.
545 NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) const {
546 assert(A && B && "Pointers are not valid");
548 "Two blocks are not in same function");
549
550 // If either A or B is a entry block then it is nearest common dominator
551 // (for forward-dominators).
552 if (!isPostDominator()) {
553 NodeT &Entry =
555 if (A == &Entry || B == &Entry)
556 return &Entry;
557 }
558
561 assert(NodeA && "A must be in the tree");
562 assert(NodeB && "B must be in the tree");
563
564 // Use level information to go up the tree until the levels match. Then
565 // continue going up til we arrive at the same node.
566 while (NodeA != NodeB) {
567 if (NodeA->getLevel() < NodeB->getLevel()) std::swap(NodeA, NodeB);
568
569 NodeA = NodeA->IDom;
570 }
571
572 return NodeA->getBlock();
573 }
574
575 const NodeT *findNearestCommonDominator(const NodeT *A,
576 const NodeT *B) const {
577 // Cast away the const qualifiers here. This is ok since
578 // const is re-introduced on the return type.
579 return findNearestCommonDominator(const_cast<NodeT *>(A),
580 const_cast<NodeT *>(B));
581 }
582
584 return isPostDominator() && !A->getBlock();
585 }
586
587 template <typename IteratorTy>
589 assert(!Nodes.empty() && "Nodes list is empty!");
590
591 NodeT *NCD = *Nodes.begin();
592 for (NodeT *Node : llvm::drop_begin(Nodes)) {
594
595 // Stop when the root is reached.
596 if (isVirtualRoot(getNode(NCD)))
597 return nullptr;
598 }
599
600 return NCD;
601 }
602
603 //===--------------------------------------------------------------------===//
604 // API to update (Post)DominatorTree information based on modifications to
605 // the CFG...
606
607 /// Inform the dominator tree about a sequence of CFG edge insertions and
608 /// deletions and perform a batch update on the tree.
609 ///
610 /// This function should be used when there were multiple CFG updates after
611 /// the last dominator tree update. It takes care of performing the updates
612 /// in sync with the CFG and optimizes away the redundant operations that
613 /// cancel each other.
614 /// The functions expects the sequence of updates to be balanced. Eg.:
615 /// - {{Insert, A, B}, {Delete, A, B}, {Insert, A, B}} is fine, because
616 /// logically it results in a single insertions.
617 /// - {{Insert, A, B}, {Insert, A, B}} is invalid, because it doesn't make
618 /// sense to insert the same edge twice.
619 ///
620 /// What's more, the functions assumes that it's safe to ask every node in the
621 /// CFG about its children and inverse children. This implies that deletions
622 /// of CFG edges must not delete the CFG nodes before calling this function.
623 ///
624 /// The applyUpdates function can reorder the updates and remove redundant
625 /// ones internally (as long as it is done in a deterministic fashion). The
626 /// batch updater is also able to detect sequences of zero and exactly one
627 /// update -- it's optimized to do less work in these cases.
628 ///
629 /// Note that for postdominators it automatically takes care of applying
630 /// updates on reverse edges internally (so there's no need to swap the
631 /// From and To pointers when constructing DominatorTree::UpdateType).
632 /// The type of updates is the same for DomTreeBase<T> and PostDomTreeBase<T>
633 /// with the same template parameter T.
634 ///
635 /// \param Updates An ordered sequence of updates to perform. The current CFG
636 /// and the reverse of these updates provides the pre-view of the CFG.
637 ///
640 Updates, /*ReverseApplyUpdates=*/true);
641 DomTreeBuilder::ApplyUpdates(*this, PreViewCFG, nullptr);
642 }
643
644 /// \param Updates An ordered sequence of updates to perform. The current CFG
645 /// and the reverse of these updates provides the pre-view of the CFG.
646 /// \param PostViewUpdates An ordered sequence of update to perform in order
647 /// to obtain a post-view of the CFG. The DT will be updated assuming the
648 /// obtained PostViewCFG is the desired end state.
650 ArrayRef<UpdateType> PostViewUpdates) {
651 if (Updates.empty()) {
652 GraphDiff<NodePtr, IsPostDom> PostViewCFG(PostViewUpdates);
653 DomTreeBuilder::ApplyUpdates(*this, PostViewCFG, &PostViewCFG);
654 } else {
655 // PreViewCFG needs to merge Updates and PostViewCFG. The updates in
656 // Updates need to be reversed, and match the direction in PostViewCFG.
657 // The PostViewCFG is created with updates reversed (equivalent to changes
658 // made to the CFG), so the PreViewCFG needs all the updates reverse
659 // applied.
660 SmallVector<UpdateType> AllUpdates(Updates);
661 append_range(AllUpdates, PostViewUpdates);
662 GraphDiff<NodePtr, IsPostDom> PreViewCFG(AllUpdates,
663 /*ReverseApplyUpdates=*/true);
664 GraphDiff<NodePtr, IsPostDom> PostViewCFG(PostViewUpdates);
665 DomTreeBuilder::ApplyUpdates(*this, PreViewCFG, &PostViewCFG);
666 }
667 }
668
669 /// Inform the dominator tree about a CFG edge insertion and update the tree.
670 ///
671 /// This function has to be called just before or just after making the update
672 /// on the actual CFG. There cannot be any other updates that the dominator
673 /// tree doesn't know about.
674 ///
675 /// Note that for postdominators it automatically takes care of inserting
676 /// a reverse edge internally (so there's no need to swap the parameters).
677 ///
678 void insertEdge(NodeT *From, NodeT *To) {
679 assert(From);
680 assert(To);
683 DomTreeBuilder::InsertEdge(*this, From, To);
684 }
685
686 /// Inform the dominator tree about a CFG edge deletion and update the tree.
687 ///
688 /// This function has to be called just after making the update on the actual
689 /// CFG. An internal functions checks if the edge doesn't exist in the CFG in
690 /// DEBUG mode. There cannot be any other updates that the
691 /// dominator tree doesn't know about.
692 ///
693 /// Note that for postdominators it automatically takes care of deleting
694 /// a reverse edge internally (so there's no need to swap the parameters).
695 ///
696 void deleteEdge(NodeT *From, NodeT *To) {
697 assert(From);
698 assert(To);
701 DomTreeBuilder::DeleteEdge(*this, From, To);
702 }
703
704 /// Add a new node to the dominator tree information.
705 ///
706 /// This creates a new node as a child of DomBB dominator node, linking it
707 /// into the children list of the immediate dominator.
708 ///
709 /// \param BB New node in CFG.
710 /// \param DomBB CFG node that is dominator for BB.
711 /// \returns New dominator tree node that represents new CFG node.
712 ///
713 DomTreeNodeBase<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) {
714 assert(getNode(BB) == nullptr && "Block already in dominator tree!");
715 DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
716 assert(IDomNode && "Not immediate dominator specified for block!");
717 DFSInfoValid = false;
718 return createNode(BB, IDomNode);
719 }
720
721 /// Add a new node to the forward dominator tree and make it a new root.
722 ///
723 /// \param BB New node in CFG.
724 /// \returns New dominator tree node that represents new CFG node.
725 ///
727 assert(getNode(BB) == nullptr && "Block already in dominator tree!");
728 assert(!this->isPostDominator() &&
729 "Cannot change root of post-dominator tree");
730 DFSInfoValid = false;
731 DomTreeNodeBase<NodeT> *NewNode = createNode(BB);
732 if (Roots.empty()) {
733 addRoot(BB);
734 } else {
735 assert(Roots.size() == 1);
736 NodeT *OldRoot = Roots.front();
737 DomTreeNodeBase<NodeT> *OldNode = getNode(OldRoot);
738 NewNode->addChild(OldNode);
739 OldNode->IDom = NewNode;
740 OldNode->UpdateLevel();
741 Roots[0] = BB;
742 }
743 return RootNode = NewNode;
744 }
745
746 /// changeImmediateDominator - This method is used to update the dominator
747 /// tree information when a node's immediate dominator changes.
748 ///
750 DomTreeNodeBase<NodeT> *NewIDom) {
751 assert(N && NewIDom && "Cannot change null node pointers!");
752 DFSInfoValid = false;
753 N->setIDom(NewIDom);
754 }
755
756 void changeImmediateDominator(NodeT *BB, NodeT *NewBB) {
758 }
759
760 /// eraseNode - Removes a node from the dominator tree. Block must not
761 /// dominate any other blocks. Removes node from its immediate dominator's
762 /// children list. Deletes dominator node associated with basic block BB.
763 void eraseNode(NodeT *BB) {
764 std::optional<unsigned> IdxOpt = getNodeIndex(BB);
765 assert(IdxOpt && DomTreeNodes[*IdxOpt] &&
766 "Removing node that isn't in dominator tree.");
768 assert(Node->isLeaf() && "Node is not a leaf node.");
769
770 DFSInfoValid = false;
771
772 // Remove node from immediate dominator's children list.
773 if (DomTreeNodeBase<NodeT> *IDom = Node->getIDom())
774 IDom->removeChild(Node);
775
776 DomTreeNodes[*IdxOpt] = nullptr;
777 if constexpr (!GraphHasNodeNumbers<NodeT *>)
778 NodeNumberMap.erase(BB);
779
780 if (!IsPostDom) return;
781
782 // Remember to update PostDominatorTree roots.
783 auto RIt = llvm::find(Roots, BB);
784 if (RIt != Roots.end()) {
785 std::swap(*RIt, Roots.back());
786 Roots.pop_back();
787 }
788 }
789
790 /// splitBlock - BB is split and now it has one successor. Update dominator
791 /// tree to reflect this change.
792 void splitBlock(NodeT *NewBB) {
793 if (IsPostDominator)
795 else
796 Split<NodeT *>(NewBB);
797 }
798
799 /// print - Convert to human readable form
800 ///
801 void print(raw_ostream &O) const {
802 O << "=============================--------------------------------\n";
803 if (IsPostDominator)
804 O << "Inorder PostDominator Tree: ";
805 else
806 O << "Inorder Dominator Tree: ";
807 if (!DFSInfoValid)
808 O << "DFSNumbers invalid: " << SlowQueries << " slow queries.";
809 O << "\n";
810
811 // The postdom tree can have a null root if there are no returns.
813 O << "Roots: ";
814 for (const NodePtr Block : Roots) {
815 Block->printAsOperand(O, false);
816 O << " ";
817 }
818 O << "\n";
819 }
820
821public:
822 /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
823 /// dominator tree in dfs order.
824 void updateDFSNumbers() const {
825 if (DFSInfoValid) {
826 SlowQueries = 0;
827 return;
828 }
829
832 32> WorkStack;
833
834 const DomTreeNodeBase<NodeT> *ThisRoot = getRootNode();
835 assert((!Parent || ThisRoot) && "Empty constructed DomTree");
836 if (!ThisRoot)
837 return;
838
839 // Both dominators and postdominators have a single root node. In the case
840 // case of PostDominatorTree, this node is a virtual root.
841 WorkStack.push_back({ThisRoot, ThisRoot->begin()});
842
843 unsigned DFSNum = 0;
844 ThisRoot->DFSNumIn = DFSNum++;
845
846 while (!WorkStack.empty()) {
847 const DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
848 const auto ChildIt = WorkStack.back().second;
849
850 // If we visited all of the children of this node, "recurse" back up the
851 // stack setting the DFOutNum.
852 if (ChildIt == Node->end()) {
853 Node->DFSNumOut = DFSNum++;
854 WorkStack.pop_back();
855 } else {
856 // Otherwise, recursively visit this child.
857 const DomTreeNodeBase<NodeT> *Child = *ChildIt;
858 ++WorkStack.back().second;
859
860 WorkStack.push_back({Child, Child->begin()});
861 Child->DFSNumIn = DFSNum++;
862 }
863 }
864
865 SlowQueries = 0;
866 DFSInfoValid = true;
867 }
868
869private:
870 void updateBlockNumberEpoch() {
871 // Nothing to do for graphs that don't number their blocks.
872 if constexpr (GraphHasNodeNumbers<NodeT *>)
874 }
875
876public:
877 /// recalculate - compute a dominator tree for the given function
879 Parent = &Func;
880 updateBlockNumberEpoch();
882 }
883
885 Parent = &Func;
886 updateBlockNumberEpoch();
888 }
889
890 /// Update dominator tree after renumbering blocks.
891 template <typename T = NodeT>
892 std::enable_if_t<GraphHasNodeNumbers<T *>, void> updateBlockNumbers() {
893 updateBlockNumberEpoch();
894
895 unsigned MaxNumber = GraphTraits<ParentPtr>::getMaxNumber(Parent);
896 DomTreeNodeStorageTy NewVector;
897 NewVector.resize(MaxNumber + 1); // +1, because index 0 is for nullptr
898 for (auto &Node : DomTreeNodes) {
899 if (!Node)
900 continue;
901 unsigned Idx = *getNodeIndex(Node->getBlock());
902 // getMaxNumber is not necessarily supported
903 if (Idx >= NewVector.size())
904 NewVector.resize(Idx + 1);
905 NewVector[Idx] = std::move(Node);
906 }
907 DomTreeNodes = std::move(NewVector);
908 }
909
910 /// verify - checks if the tree is correct. There are 3 level of verification:
911 /// - Full -- verifies if the tree is correct by making sure all the
912 /// properties (including the parent and the sibling property)
913 /// hold.
914 /// Takes O(N^3) time.
915 ///
916 /// - Basic -- checks if the tree is correct, but compares it to a freshly
917 /// constructed tree instead of checking the sibling property.
918 /// Takes O(N^2) time.
919 ///
920 /// - Fast -- checks basic tree structure and compares it with a freshly
921 /// constructed tree.
922 /// Takes O(N^2) time worst case, but is faster in practise (same
923 /// as tree construction).
925 return DomTreeBuilder::Verify(*this, VL);
926 }
927
928 void reset() {
929 DomTreeNodes.clear();
930 if constexpr (!GraphHasNodeNumbers<NodeT *>)
931 NodeNumberMap.clear();
932 Roots.clear();
933 RootNode = nullptr;
934 Parent = nullptr;
935 DFSInfoValid = false;
936 NodeAllocator.Reset();
937 SlowQueries = 0;
938 }
939
940protected:
941 inline void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
942
944 DomTreeNodeBase<NodeT> *IDom = nullptr) {
945 static_assert(std::is_trivially_destructible_v<DomTreeNodeBase<NodeT>>);
946 auto *Node = new (NodeAllocator) DomTreeNodeBase<NodeT>(BB, IDom);
947 unsigned NodeIdx = getNodeIndexForInsert(BB);
948 DomTreeNodes[NodeIdx] = Node;
949 if (IDom)
950 IDom->addChild(Node);
951 return Node;
952 }
953
954 // NewBB is split and now it has one successor. Update dominator tree to
955 // reflect this change.
956 template <class N>
957 void Split(typename GraphTraits<N>::NodeRef NewBB) {
958 using GraphT = GraphTraits<N>;
959 using NodeRef = typename GraphT::NodeRef;
961 "NewBB should have a single successor!");
962 NodeRef NewBBSucc = *GraphT::child_begin(NewBB);
963
965
966 assert(!PredBlocks.empty() && "No predblocks?");
967
968 bool NewBBDominatesNewBBSucc = true;
969 for (auto *Pred : inverse_children<N>(NewBBSucc)) {
970 if (Pred != NewBB && !dominates(NewBBSucc, Pred) &&
971 isReachableFromEntry(Pred)) {
972 NewBBDominatesNewBBSucc = false;
973 break;
974 }
975 }
976
977 // Find NewBB's immediate dominator and create new dominator tree node for
978 // NewBB.
979 NodeT *NewBBIDom = nullptr;
980 unsigned i = 0;
981 for (i = 0; i < PredBlocks.size(); ++i)
982 if (isReachableFromEntry(PredBlocks[i])) {
983 NewBBIDom = PredBlocks[i];
984 break;
985 }
986
987 // It's possible that none of the predecessors of NewBB are reachable;
988 // in that case, NewBB itself is unreachable, so nothing needs to be
989 // changed.
990 if (!NewBBIDom) return;
991
992 for (i = i + 1; i < PredBlocks.size(); ++i) {
993 if (isReachableFromEntry(PredBlocks[i]))
994 NewBBIDom = findNearestCommonDominator(NewBBIDom, PredBlocks[i]);
995 }
996
997 // Create the new dominator tree node... and set the idom of NewBB.
998 DomTreeNodeBase<NodeT> *NewBBNode = addNewBlock(NewBB, NewBBIDom);
999
1000 // If NewBB strictly dominates other blocks, then it is now the immediate
1001 // dominator of NewBBSucc. Update the dominator tree as appropriate.
1002 if (NewBBDominatesNewBBSucc) {
1003 DomTreeNodeBase<NodeT> *NewBBSuccNode = getNode(NewBBSucc);
1004 changeImmediateDominator(NewBBSuccNode, NewBBNode);
1005 }
1006 }
1007
1008 private:
1009 bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
1010 const DomTreeNodeBase<NodeT> *B) const {
1011 assert(A != B);
1014
1015 const unsigned ALevel = A->getLevel();
1016 const DomTreeNodeBase<NodeT> *IDom;
1017
1018 // Don't walk nodes above A's subtree. When we reach A's level, we must
1019 // either find A or be in some other subtree not dominated by A.
1020 while ((IDom = B->getIDom()) != nullptr && IDom->getLevel() >= ALevel)
1021 B = IDom; // Walk up the tree
1022
1023 return B == A;
1024 }
1025};
1026
1027template <typename T>
1029
1030template <typename T>
1032
1033// These two functions are declared out of line as a workaround for building
1034// with old (< r147295) versions of clang because of pr11642.
1035template <typename NodeT, bool IsPostDom>
1037 const NodeT *B) const {
1038 if (A == B)
1039 return true;
1040
1041 return dominates(getNode(A), getNode(B));
1042}
1043template <typename NodeT, bool IsPostDom>
1045 const NodeT *A, const NodeT *B) const {
1046 if (A == B)
1047 return false;
1048
1049 return dominates(getNode(A), getNode(B));
1050}
1051
1052} // end namespace llvm
1053
1054#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)
This file defines the BumpPtrAllocator interface.
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
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
bool empty() const
empty - Check if the array is empty.
Definition ArrayRef.h:137
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition Allocator.h:67
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
bool isReachableFromEntry(const DomTreeNodeBase< NodeT > *A) const
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.
std::enable_if_t< GraphHasNodeNumbers< T * >, void > updateBlockNumbers()
Update dominator tree after renumbering blocks.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
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
std::conditional_t<!GraphHasNodeNumbers< BlockT * >, DenseMap< const BlockT *, unsigned >, std::tuple<> > NodeNumberMap
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
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
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL)
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.
Definition Types.h:26
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
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.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2208
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:300
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:872
#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