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 if (this == &RHS)
291 return *this;
292 Roots = std::move(RHS.Roots);
293 DomTreeNodes = std::move(RHS.DomTreeNodes);
294 NodeNumberMap = std::move(RHS.NodeNumberMap);
295 RootNode = RHS.RootNode;
296 Parent = RHS.Parent;
297 DFSInfoValid = RHS.DFSInfoValid;
298 SlowQueries = RHS.SlowQueries;
299 BlockNumberEpoch = RHS.BlockNumberEpoch;
300 RHS.wipe();
301 return *this;
302 }
303
306
307 /// Iteration over roots.
308 ///
309 /// This may include multiple blocks if we are computing post dominators.
310 /// For forward dominators, this will always be a single block (the entry
311 /// block).
314
318 const_root_iterator root_end() const { return Roots.end(); }
319
320 size_t root_size() const { return Roots.size(); }
321
323 return make_range(root_begin(), root_end());
324 }
326 return make_range(root_begin(), root_end());
327 }
328
329 /// isPostDominator - Returns true if analysis based of postdoms
330 ///
331 bool isPostDominator() const { return IsPostDominator; }
332
333 /// compare - Return false if the other dominator tree base matches this
334 /// dominator tree base. Otherwise return true.
335 bool compare(const DominatorTreeBase &Other) const {
336 if (Parent != Other.Parent) return true;
337
338 if (Roots.size() != Other.Roots.size())
339 return true;
340
341 if (!std::is_permutation(Roots.begin(), Roots.end(), Other.Roots.begin()))
342 return true;
343
344 size_t NumNodes = 0;
345 // All nodes we have must exist and be equal in the other tree.
346 for (const auto &Node : DomTreeNodes) {
347 if (!Node)
348 continue;
349 if (Node->compare(Other.getNode(Node->getBlock())))
350 return true;
351 NumNodes++;
352 }
353
354 // If the other tree has more nodes than we have, they're not equal.
355 size_t NumOtherNodes = 0;
356 for (const auto &OtherNode : Other.DomTreeNodes)
357 if (OtherNode)
358 NumOtherNodes++;
359 return NumNodes != NumOtherNodes;
360 }
361
362private:
363 std::optional<unsigned> getNodeIndex(const NodeT *BB) const {
364 if constexpr (GraphHasNodeNumbers<NodeT *>) {
365 // BB can be nullptr, map nullptr to index 0.
368 "dominator tree used with outdated block numbers");
369 return BB ? GraphTraits<const NodeT *>::getNumber(BB) + 1 : 0;
370 } else {
371 if (auto It = NodeNumberMap.find(BB); It != NodeNumberMap.end())
372 return It->second;
373 return std::nullopt;
374 }
375 }
376
377 unsigned getNodeIndexForInsert(const NodeT *BB) {
378 if constexpr (GraphHasNodeNumbers<NodeT *>) {
379 // getNodeIndex will never fail if nodes have getNumber().
380 unsigned Idx = *getNodeIndex(BB);
381 if (Idx >= DomTreeNodes.size()) {
382 unsigned Max = GraphTraits<ParentPtr>::getMaxNumber(Parent);
383 DomTreeNodes.resize(Max > Idx + 1 ? Max : Idx + 1);
384 }
385 return Idx;
386 } else {
387 // We might already have a number stored for BB.
388 unsigned Idx =
389 NodeNumberMap.try_emplace(BB, DomTreeNodes.size()).first->second;
390 if (Idx >= DomTreeNodes.size())
392 return Idx;
393 }
394 }
395
396public:
397 /// getNode - return the (Post)DominatorTree node for the specified basic
398 /// block. This is the same as using operator[] on this class. The result
399 /// may (but is not required to) be null for a forward (backwards)
400 /// statically unreachable block.
401 DomTreeNodeBase<NodeT> *getNode(const NodeT *BB) const {
402 assert((!BB || Parent == NodeTrait::getParent(const_cast<NodeT *>(BB))) &&
403 "cannot get DomTreeNode of block with different parent");
404 if (auto Idx = getNodeIndex(BB); Idx && *Idx < DomTreeNodes.size())
405 return DomTreeNodes[*Idx].get();
406 return nullptr;
407 }
408
409 /// See getNode.
410 DomTreeNodeBase<NodeT> *operator[](const NodeT *BB) const {
411 return getNode(BB);
412 }
413
414 /// getRootNode - This returns the entry node for the CFG of the function. If
415 /// this tree represents the post-dominance relations for a function, however,
416 /// this root may be a node with the block == NULL. This is the case when
417 /// there are multiple exit nodes from a particular function. Consumers of
418 /// post-dominance information must be capable of dealing with this
419 /// possibility.
420 ///
422 const DomTreeNodeBase<NodeT> *getRootNode() const { return RootNode; }
423
424 /// Get all nodes dominated by R, including R itself.
425 void getDescendants(NodeT *R, SmallVectorImpl<NodeT *> &Result) const {
426 Result.clear();
427 const DomTreeNodeBase<NodeT> *RN = getNode(R);
428 if (!RN)
429 return; // If R is unreachable, it will not be present in the DOM tree.
431 WL.push_back(RN);
432
433 while (!WL.empty()) {
435 Result.push_back(N->getBlock());
436 WL.append(N->begin(), N->end());
437 }
438 }
439
440 /// properlyDominates - Returns true iff A dominates B and A != B.
441 /// Note that this is not a constant time operation!
442 ///
444 const DomTreeNodeBase<NodeT> *B) const {
445 if (!A || !B)
446 return false;
447 if (A == B)
448 return false;
449 return dominates(A, B);
450 }
451
452 bool properlyDominates(const NodeT *A, const NodeT *B) const;
453
454 /// isReachableFromEntry - Return true if A is dominated by the entry
455 /// block of the function containing it.
456 bool isReachableFromEntry(const NodeT *A) const {
457 assert(!this->isPostDominator() &&
458 "This is not implemented for post dominators");
459 return isReachableFromEntry(getNode(A));
460 }
461
462 bool isReachableFromEntry(const DomTreeNodeBase<NodeT> *A) const { return A; }
463
464 /// dominates - Returns true iff A dominates B. Note that this is not a
465 /// constant time operation!
466 ///
468 const DomTreeNodeBase<NodeT> *B) const {
469 // A node trivially dominates itself.
470 if (B == A)
471 return true;
472
473 // An unreachable node is dominated by anything.
475 return true;
476
477 // And dominates nothing.
479 return false;
480
481 if (B->getIDom() == A) return true;
482
483 if (A->getIDom() == B) return false;
484
485 // A can only dominate B if it is higher in the tree.
486 if (A->getLevel() >= B->getLevel()) return false;
487
488 // Compare the result of the tree walk and the dfs numbers, if expensive
489 // checks are enabled.
490#ifdef EXPENSIVE_CHECKS
492 (dominatedBySlowTreeWalk(A, B) == B->DominatedBy(A))) &&
493 "Tree walk disagrees with dfs numbers!");
494#endif
495
496 if (DFSInfoValid)
497 return B->DominatedBy(A);
498
499 // If we end up with too many slow queries, just update the
500 // DFS numbers on the theory that we are going to keep querying.
501 SlowQueries++;
502 if (SlowQueries > 32) {
504 return B->DominatedBy(A);
505 }
506
507 return dominatedBySlowTreeWalk(A, B);
508 }
509
510 bool dominates(const NodeT *A, const NodeT *B) const;
511
512 NodeT *getRoot() const {
513 assert(this->Roots.size() == 1 && "Should always have entry node!");
514 return this->Roots[0];
515 }
516
517 /// Find nearest common dominator basic block for basic block A and B. A and B
518 /// must have tree nodes.
519 NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) const {
520 assert(A && B && "Pointers are not valid");
522 "Two blocks are not in same function");
523
524 // If either A or B is a entry block then it is nearest common dominator
525 // (for forward-dominators).
526 if (!isPostDominator()) {
527 NodeT &Entry =
529 if (A == &Entry || B == &Entry)
530 return &Entry;
531 }
532
535 assert(NodeA && "A must be in the tree");
536 assert(NodeB && "B must be in the tree");
537
538 // Use level information to go up the tree until the levels match. Then
539 // continue going up til we arrive at the same node.
540 while (NodeA != NodeB) {
541 if (NodeA->getLevel() < NodeB->getLevel()) std::swap(NodeA, NodeB);
542
543 NodeA = NodeA->IDom;
544 }
545
546 return NodeA->getBlock();
547 }
548
549 const NodeT *findNearestCommonDominator(const NodeT *A,
550 const NodeT *B) const {
551 // Cast away the const qualifiers here. This is ok since
552 // const is re-introduced on the return type.
553 return findNearestCommonDominator(const_cast<NodeT *>(A),
554 const_cast<NodeT *>(B));
555 }
556
558 return isPostDominator() && !A->getBlock();
559 }
560
561 //===--------------------------------------------------------------------===//
562 // API to update (Post)DominatorTree information based on modifications to
563 // the CFG...
564
565 /// Inform the dominator tree about a sequence of CFG edge insertions and
566 /// deletions and perform a batch update on the tree.
567 ///
568 /// This function should be used when there were multiple CFG updates after
569 /// the last dominator tree update. It takes care of performing the updates
570 /// in sync with the CFG and optimizes away the redundant operations that
571 /// cancel each other.
572 /// The functions expects the sequence of updates to be balanced. Eg.:
573 /// - {{Insert, A, B}, {Delete, A, B}, {Insert, A, B}} is fine, because
574 /// logically it results in a single insertions.
575 /// - {{Insert, A, B}, {Insert, A, B}} is invalid, because it doesn't make
576 /// sense to insert the same edge twice.
577 ///
578 /// What's more, the functions assumes that it's safe to ask every node in the
579 /// CFG about its children and inverse children. This implies that deletions
580 /// of CFG edges must not delete the CFG nodes before calling this function.
581 ///
582 /// The applyUpdates function can reorder the updates and remove redundant
583 /// ones internally (as long as it is done in a deterministic fashion). The
584 /// batch updater is also able to detect sequences of zero and exactly one
585 /// update -- it's optimized to do less work in these cases.
586 ///
587 /// Note that for postdominators it automatically takes care of applying
588 /// updates on reverse edges internally (so there's no need to swap the
589 /// From and To pointers when constructing DominatorTree::UpdateType).
590 /// The type of updates is the same for DomTreeBase<T> and PostDomTreeBase<T>
591 /// with the same template parameter T.
592 ///
593 /// \param Updates An ordered sequence of updates to perform. The current CFG
594 /// and the reverse of these updates provides the pre-view of the CFG.
595 ///
598 Updates, /*ReverseApplyUpdates=*/true);
599 DomTreeBuilder::ApplyUpdates(*this, PreViewCFG, nullptr);
600 }
601
602 /// \param Updates An ordered sequence of updates to perform. The current CFG
603 /// and the reverse of these updates provides the pre-view of the CFG.
604 /// \param PostViewUpdates An ordered sequence of update to perform in order
605 /// to obtain a post-view of the CFG. The DT will be updated assuming the
606 /// obtained PostViewCFG is the desired end state.
608 ArrayRef<UpdateType> PostViewUpdates) {
609 if (Updates.empty()) {
610 GraphDiff<NodePtr, IsPostDom> PostViewCFG(PostViewUpdates);
611 DomTreeBuilder::ApplyUpdates(*this, PostViewCFG, &PostViewCFG);
612 } else {
613 // PreViewCFG needs to merge Updates and PostViewCFG. The updates in
614 // Updates need to be reversed, and match the direction in PostViewCFG.
615 // The PostViewCFG is created with updates reversed (equivalent to changes
616 // made to the CFG), so the PreViewCFG needs all the updates reverse
617 // applied.
618 SmallVector<UpdateType> AllUpdates(Updates);
619 append_range(AllUpdates, PostViewUpdates);
620 GraphDiff<NodePtr, IsPostDom> PreViewCFG(AllUpdates,
621 /*ReverseApplyUpdates=*/true);
622 GraphDiff<NodePtr, IsPostDom> PostViewCFG(PostViewUpdates);
623 DomTreeBuilder::ApplyUpdates(*this, PreViewCFG, &PostViewCFG);
624 }
625 }
626
627 /// Inform the dominator tree about a CFG edge insertion and update the tree.
628 ///
629 /// This function has to be called just before or just after making the update
630 /// on the actual CFG. There cannot be any other updates that the dominator
631 /// tree doesn't know about.
632 ///
633 /// Note that for postdominators it automatically takes care of inserting
634 /// a reverse edge internally (so there's no need to swap the parameters).
635 ///
636 void insertEdge(NodeT *From, NodeT *To) {
637 assert(From);
638 assert(To);
642 }
643
644 /// Inform the dominator tree about a CFG edge deletion and update the tree.
645 ///
646 /// This function has to be called just after making the update on the actual
647 /// CFG. An internal functions checks if the edge doesn't exist in the CFG in
648 /// DEBUG mode. There cannot be any other updates that the
649 /// dominator tree doesn't know about.
650 ///
651 /// Note that for postdominators it automatically takes care of deleting
652 /// a reverse edge internally (so there's no need to swap the parameters).
653 ///
654 void deleteEdge(NodeT *From, NodeT *To) {
655 assert(From);
656 assert(To);
660 }
661
662 /// Add a new node to the dominator tree information.
663 ///
664 /// This creates a new node as a child of DomBB dominator node, linking it
665 /// into the children list of the immediate dominator.
666 ///
667 /// \param BB New node in CFG.
668 /// \param DomBB CFG node that is dominator for BB.
669 /// \returns New dominator tree node that represents new CFG node.
670 ///
671 DomTreeNodeBase<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) {
672 assert(getNode(BB) == nullptr && "Block already in dominator tree!");
673 DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
674 assert(IDomNode && "Not immediate dominator specified for block!");
675 DFSInfoValid = false;
676 return createNode(BB, IDomNode);
677 }
678
679 /// Add a new node to the forward dominator tree and make it a new root.
680 ///
681 /// \param BB New node in CFG.
682 /// \returns New dominator tree node that represents new CFG node.
683 ///
685 assert(getNode(BB) == nullptr && "Block already in dominator tree!");
686 assert(!this->isPostDominator() &&
687 "Cannot change root of post-dominator tree");
688 DFSInfoValid = false;
689 DomTreeNodeBase<NodeT> *NewNode = createNode(BB);
690 if (Roots.empty()) {
691 addRoot(BB);
692 } else {
693 assert(Roots.size() == 1);
694 NodeT *OldRoot = Roots.front();
695 DomTreeNodeBase<NodeT> *OldNode = getNode(OldRoot);
696 NewNode->addChild(OldNode);
697 OldNode->IDom = NewNode;
698 OldNode->UpdateLevel();
699 Roots[0] = BB;
700 }
701 return RootNode = NewNode;
702 }
703
704 /// changeImmediateDominator - This method is used to update the dominator
705 /// tree information when a node's immediate dominator changes.
706 ///
708 DomTreeNodeBase<NodeT> *NewIDom) {
709 assert(N && NewIDom && "Cannot change null node pointers!");
710 DFSInfoValid = false;
711 N->setIDom(NewIDom);
712 }
713
714 void changeImmediateDominator(NodeT *BB, NodeT *NewBB) {
716 }
717
718 /// eraseNode - Removes a node from the dominator tree. Block must not
719 /// dominate any other blocks. Removes node from its immediate dominator's
720 /// children list. Deletes dominator node associated with basic block BB.
721 void eraseNode(NodeT *BB) {
722 std::optional<unsigned> IdxOpt = getNodeIndex(BB);
723 assert(IdxOpt && DomTreeNodes[*IdxOpt] &&
724 "Removing node that isn't in dominator tree.");
725 DomTreeNodeBase<NodeT> *Node = DomTreeNodes[*IdxOpt].get();
726 assert(Node->isLeaf() && "Node is not a leaf node.");
727
728 DFSInfoValid = false;
729
730 // Remove node from immediate dominator's children list.
731 DomTreeNodeBase<NodeT> *IDom = Node->getIDom();
732 if (IDom) {
733 const auto I = find(IDom->Children, Node);
734 assert(I != IDom->Children.end() &&
735 "Not in immediate dominator children set!");
736 // I am no longer your child...
737 std::swap(*I, IDom->Children.back());
738 IDom->Children.pop_back();
739 }
740
741 DomTreeNodes[*IdxOpt] = nullptr;
742 if constexpr (!GraphHasNodeNumbers<NodeT *>)
743 NodeNumberMap.erase(BB);
744
745 if (!IsPostDom) return;
746
747 // Remember to update PostDominatorTree roots.
748 auto RIt = llvm::find(Roots, BB);
749 if (RIt != Roots.end()) {
750 std::swap(*RIt, Roots.back());
751 Roots.pop_back();
752 }
753 }
754
755 /// splitBlock - BB is split and now it has one successor. Update dominator
756 /// tree to reflect this change.
757 void splitBlock(NodeT *NewBB) {
758 if (IsPostDominator)
759 Split<Inverse<NodeT *>>(NewBB);
760 else
761 Split<NodeT *>(NewBB);
762 }
763
764 /// print - Convert to human readable form
765 ///
766 void print(raw_ostream &O) const {
767 O << "=============================--------------------------------\n";
768 if (IsPostDominator)
769 O << "Inorder PostDominator Tree: ";
770 else
771 O << "Inorder Dominator Tree: ";
772 if (!DFSInfoValid)
773 O << "DFSNumbers invalid: " << SlowQueries << " slow queries.";
774 O << "\n";
775
776 // The postdom tree can have a null root if there are no returns.
777 if (getRootNode()) PrintDomTree<NodeT>(getRootNode(), O, 1);
778 O << "Roots: ";
779 for (const NodePtr Block : Roots) {
780 Block->printAsOperand(O, false);
781 O << " ";
782 }
783 O << "\n";
784 }
785
786public:
787 /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
788 /// dominator tree in dfs order.
789 void updateDFSNumbers() const {
790 if (DFSInfoValid) {
791 SlowQueries = 0;
792 return;
793 }
794
797 32> WorkStack;
798
799 const DomTreeNodeBase<NodeT> *ThisRoot = getRootNode();
800 assert((!Parent || ThisRoot) && "Empty constructed DomTree");
801 if (!ThisRoot)
802 return;
803
804 // Both dominators and postdominators have a single root node. In the case
805 // case of PostDominatorTree, this node is a virtual root.
806 WorkStack.push_back({ThisRoot, ThisRoot->begin()});
807
808 unsigned DFSNum = 0;
809 ThisRoot->DFSNumIn = DFSNum++;
810
811 while (!WorkStack.empty()) {
812 const DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
813 const auto ChildIt = WorkStack.back().second;
814
815 // If we visited all of the children of this node, "recurse" back up the
816 // stack setting the DFOutNum.
817 if (ChildIt == Node->end()) {
818 Node->DFSNumOut = DFSNum++;
819 WorkStack.pop_back();
820 } else {
821 // Otherwise, recursively visit this child.
822 const DomTreeNodeBase<NodeT> *Child = *ChildIt;
823 ++WorkStack.back().second;
824
825 WorkStack.push_back({Child, Child->begin()});
826 Child->DFSNumIn = DFSNum++;
827 }
828 }
829
830 SlowQueries = 0;
831 DFSInfoValid = true;
832 }
833
834private:
835 void updateBlockNumberEpoch() {
836 // Nothing to do for graphs that don't number their blocks.
837 if constexpr (GraphHasNodeNumbers<NodeT *>)
839 }
840
841public:
842 /// recalculate - compute a dominator tree for the given function
844 Parent = &Func;
845 updateBlockNumberEpoch();
847 }
848
850 Parent = &Func;
851 updateBlockNumberEpoch();
853 }
854
855 /// Update dominator tree after renumbering blocks.
856 template <typename T = NodeT>
857 std::enable_if_t<GraphHasNodeNumbers<T *>, void> updateBlockNumbers() {
858 updateBlockNumberEpoch();
859
860 unsigned MaxNumber = GraphTraits<ParentPtr>::getMaxNumber(Parent);
861 DomTreeNodeStorageTy NewVector;
862 NewVector.resize(MaxNumber + 1); // +1, because index 0 is for nullptr
863 for (auto &Node : DomTreeNodes) {
864 if (!Node)
865 continue;
866 unsigned Idx = *getNodeIndex(Node->getBlock());
867 // getMaxNumber is not necessarily supported
868 if (Idx >= NewVector.size())
869 NewVector.resize(Idx + 1);
870 NewVector[Idx] = std::move(Node);
871 }
872 DomTreeNodes = std::move(NewVector);
873 }
874
875 /// verify - checks if the tree is correct. There are 3 level of verification:
876 /// - Full -- verifies if the tree is correct by making sure all the
877 /// properties (including the parent and the sibling property)
878 /// hold.
879 /// Takes O(N^3) time.
880 ///
881 /// - Basic -- checks if the tree is correct, but compares it to a freshly
882 /// constructed tree instead of checking the sibling property.
883 /// Takes O(N^2) time.
884 ///
885 /// - Fast -- checks basic tree structure and compares it with a freshly
886 /// constructed tree.
887 /// Takes O(N^2) time worst case, but is faster in practise (same
888 /// as tree construction).
890 return DomTreeBuilder::Verify(*this, VL);
891 }
892
893 void reset() {
895 if constexpr (!GraphHasNodeNumbers<NodeT *>)
896 NodeNumberMap.clear();
897 Roots.clear();
898 RootNode = nullptr;
899 Parent = nullptr;
900 DFSInfoValid = false;
901 SlowQueries = 0;
902 }
903
904protected:
905 void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
906
908 DomTreeNodeBase<NodeT> *IDom = nullptr) {
909 auto Node = std::make_unique<DomTreeNodeBase<NodeT>>(BB, IDom);
910 auto *NodePtr = Node.get();
911 unsigned NodeIdx = getNodeIndexForInsert(BB);
912 DomTreeNodes[NodeIdx] = std::move(Node);
913 if (IDom)
914 IDom->addChild(NodePtr);
915 return NodePtr;
916 }
917
918 // NewBB is split and now it has one successor. Update dominator tree to
919 // reflect this change.
920 template <class N>
921 void Split(typename GraphTraits<N>::NodeRef NewBB) {
922 using GraphT = GraphTraits<N>;
923 using NodeRef = typename GraphT::NodeRef;
924 assert(llvm::hasSingleElement(children<N>(NewBB)) &&
925 "NewBB should have a single successor!");
926 NodeRef NewBBSucc = *GraphT::child_begin(NewBB);
927
928 SmallVector<NodeRef, 4> PredBlocks(inverse_children<N>(NewBB));
929
930 assert(!PredBlocks.empty() && "No predblocks?");
931
932 bool NewBBDominatesNewBBSucc = true;
933 for (auto *Pred : inverse_children<N>(NewBBSucc)) {
934 if (Pred != NewBB && !dominates(NewBBSucc, Pred) &&
935 isReachableFromEntry(Pred)) {
936 NewBBDominatesNewBBSucc = false;
937 break;
938 }
939 }
940
941 // Find NewBB's immediate dominator and create new dominator tree node for
942 // NewBB.
943 NodeT *NewBBIDom = nullptr;
944 unsigned i = 0;
945 for (i = 0; i < PredBlocks.size(); ++i)
946 if (isReachableFromEntry(PredBlocks[i])) {
947 NewBBIDom = PredBlocks[i];
948 break;
949 }
950
951 // It's possible that none of the predecessors of NewBB are reachable;
952 // in that case, NewBB itself is unreachable, so nothing needs to be
953 // changed.
954 if (!NewBBIDom) return;
955
956 for (i = i + 1; i < PredBlocks.size(); ++i) {
957 if (isReachableFromEntry(PredBlocks[i]))
958 NewBBIDom = findNearestCommonDominator(NewBBIDom, PredBlocks[i]);
959 }
960
961 // Create the new dominator tree node... and set the idom of NewBB.
962 DomTreeNodeBase<NodeT> *NewBBNode = addNewBlock(NewBB, NewBBIDom);
963
964 // If NewBB strictly dominates other blocks, then it is now the immediate
965 // dominator of NewBBSucc. Update the dominator tree as appropriate.
966 if (NewBBDominatesNewBBSucc) {
967 DomTreeNodeBase<NodeT> *NewBBSuccNode = getNode(NewBBSucc);
968 changeImmediateDominator(NewBBSuccNode, NewBBNode);
969 }
970 }
971
972 private:
973 bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
974 const DomTreeNodeBase<NodeT> *B) const {
975 assert(A != B);
978
979 const unsigned ALevel = A->getLevel();
980 const DomTreeNodeBase<NodeT> *IDom;
981
982 // Don't walk nodes above A's subtree. When we reach A's level, we must
983 // either find A or be in some other subtree not dominated by A.
984 while ((IDom = B->getIDom()) != nullptr && IDom->getLevel() >= ALevel)
985 B = IDom; // Walk up the tree
986
987 return B == A;
988 }
989
990 /// Wipe this tree's state without releasing any resources.
991 ///
992 /// This is essentially a post-move helper only. It leaves the object in an
993 /// assignable and destroyable state, but otherwise invalid.
994 void wipe() {
996 if constexpr (!GraphHasNodeNumbers<NodeT *>)
997 NodeNumberMap.clear();
998 RootNode = nullptr;
999 Parent = nullptr;
1000 }
1001};
1002
1003template <typename T>
1005
1006template <typename T>
1008
1009// These two functions are declared out of line as a workaround for building
1010// with old (< r147295) versions of clang because of pr11642.
1011template <typename NodeT, bool IsPostDom>
1013 const NodeT *B) const {
1014 if (A == B)
1015 return true;
1016
1017 return dominates(getNode(A), getNode(B));
1018}
1019template <typename NodeT, bool IsPostDom>
1021 const NodeT *A, const NodeT *B) const {
1022 if (A == B)
1023 return false;
1024
1025 return dominates(getNode(A), getNode(B));
1026}
1027
1028} // end namespace llvm
1029
1030#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
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.
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:41
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:163
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:452
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:384
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:519
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
typename SuperClass::const_iterator const_iterator
Definition: SmallVector.h:578
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:683
typename SuperClass::iterator iterator
Definition: SmallVector.h:577
void resize(size_type N)
Definition: SmallVector.h:638
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
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:1759
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:2115
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:303
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:1873
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