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