LLVM 22.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>
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
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,
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
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
315 root_iterator root_begin() { return Roots.begin(); }
316 const_root_iterator root_begin() const { return Roots.begin(); }
317 root_iterator root_end() { return Roots.end(); }
318 const_root_iterator root_end() const { return Roots.end(); }
319
320 size_t root_size() const { return Roots.size(); }
321
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())
391 DomTreeNodes.resize(Idx + 1);
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 template <typename IteratorTy>
563 assert(!Nodes.empty() && "Nodes list is empty!");
564
565 NodeT *NCD = *Nodes.begin();
566 for (NodeT *Node : llvm::drop_begin(Nodes)) {
568
569 // Stop when the root is reached.
570 if (isVirtualRoot(getNode(NCD)))
571 return nullptr;
572 }
573
574 return NCD;
575 }
576
577 //===--------------------------------------------------------------------===//
578 // API to update (Post)DominatorTree information based on modifications to
579 // the CFG...
580
581 /// Inform the dominator tree about a sequence of CFG edge insertions and
582 /// deletions and perform a batch update on the tree.
583 ///
584 /// This function should be used when there were multiple CFG updates after
585 /// the last dominator tree update. It takes care of performing the updates
586 /// in sync with the CFG and optimizes away the redundant operations that
587 /// cancel each other.
588 /// The functions expects the sequence of updates to be balanced. Eg.:
589 /// - {{Insert, A, B}, {Delete, A, B}, {Insert, A, B}} is fine, because
590 /// logically it results in a single insertions.
591 /// - {{Insert, A, B}, {Insert, A, B}} is invalid, because it doesn't make
592 /// sense to insert the same edge twice.
593 ///
594 /// What's more, the functions assumes that it's safe to ask every node in the
595 /// CFG about its children and inverse children. This implies that deletions
596 /// of CFG edges must not delete the CFG nodes before calling this function.
597 ///
598 /// The applyUpdates function can reorder the updates and remove redundant
599 /// ones internally (as long as it is done in a deterministic fashion). The
600 /// batch updater is also able to detect sequences of zero and exactly one
601 /// update -- it's optimized to do less work in these cases.
602 ///
603 /// Note that for postdominators it automatically takes care of applying
604 /// updates on reverse edges internally (so there's no need to swap the
605 /// From and To pointers when constructing DominatorTree::UpdateType).
606 /// The type of updates is the same for DomTreeBase<T> and PostDomTreeBase<T>
607 /// with the same template parameter T.
608 ///
609 /// \param Updates An ordered sequence of updates to perform. The current CFG
610 /// and the reverse of these updates provides the pre-view of the CFG.
611 ///
614 Updates, /*ReverseApplyUpdates=*/true);
615 DomTreeBuilder::ApplyUpdates(*this, PreViewCFG, nullptr);
616 }
617
618 /// \param Updates An ordered sequence of updates to perform. The current CFG
619 /// and the reverse of these updates provides the pre-view of the CFG.
620 /// \param PostViewUpdates An ordered sequence of update to perform in order
621 /// to obtain a post-view of the CFG. The DT will be updated assuming the
622 /// obtained PostViewCFG is the desired end state.
624 ArrayRef<UpdateType> PostViewUpdates) {
625 if (Updates.empty()) {
626 GraphDiff<NodePtr, IsPostDom> PostViewCFG(PostViewUpdates);
627 DomTreeBuilder::ApplyUpdates(*this, PostViewCFG, &PostViewCFG);
628 } else {
629 // PreViewCFG needs to merge Updates and PostViewCFG. The updates in
630 // Updates need to be reversed, and match the direction in PostViewCFG.
631 // The PostViewCFG is created with updates reversed (equivalent to changes
632 // made to the CFG), so the PreViewCFG needs all the updates reverse
633 // applied.
634 SmallVector<UpdateType> AllUpdates(Updates);
635 append_range(AllUpdates, PostViewUpdates);
636 GraphDiff<NodePtr, IsPostDom> PreViewCFG(AllUpdates,
637 /*ReverseApplyUpdates=*/true);
638 GraphDiff<NodePtr, IsPostDom> PostViewCFG(PostViewUpdates);
639 DomTreeBuilder::ApplyUpdates(*this, PreViewCFG, &PostViewCFG);
640 }
641 }
642
643 /// Inform the dominator tree about a CFG edge insertion and update the tree.
644 ///
645 /// This function has to be called just before or just after making the update
646 /// on the actual CFG. There cannot be any other updates that the dominator
647 /// tree doesn't know about.
648 ///
649 /// Note that for postdominators it automatically takes care of inserting
650 /// a reverse edge internally (so there's no need to swap the parameters).
651 ///
652 void insertEdge(NodeT *From, NodeT *To) {
653 assert(From);
654 assert(To);
657 DomTreeBuilder::InsertEdge(*this, From, To);
658 }
659
660 /// Inform the dominator tree about a CFG edge deletion and update the tree.
661 ///
662 /// This function has to be called just after making the update on the actual
663 /// CFG. An internal functions checks if the edge doesn't exist in the CFG in
664 /// DEBUG mode. There cannot be any other updates that the
665 /// dominator tree doesn't know about.
666 ///
667 /// Note that for postdominators it automatically takes care of deleting
668 /// a reverse edge internally (so there's no need to swap the parameters).
669 ///
670 void deleteEdge(NodeT *From, NodeT *To) {
671 assert(From);
672 assert(To);
675 DomTreeBuilder::DeleteEdge(*this, From, To);
676 }
677
678 /// Add a new node to the dominator tree information.
679 ///
680 /// This creates a new node as a child of DomBB dominator node, linking it
681 /// into the children list of the immediate dominator.
682 ///
683 /// \param BB New node in CFG.
684 /// \param DomBB CFG node that is dominator for BB.
685 /// \returns New dominator tree node that represents new CFG node.
686 ///
687 DomTreeNodeBase<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) {
688 assert(getNode(BB) == nullptr && "Block already in dominator tree!");
689 DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
690 assert(IDomNode && "Not immediate dominator specified for block!");
691 DFSInfoValid = false;
692 return createNode(BB, IDomNode);
693 }
694
695 /// Add a new node to the forward dominator tree and make it a new root.
696 ///
697 /// \param BB New node in CFG.
698 /// \returns New dominator tree node that represents new CFG node.
699 ///
701 assert(getNode(BB) == nullptr && "Block already in dominator tree!");
702 assert(!this->isPostDominator() &&
703 "Cannot change root of post-dominator tree");
704 DFSInfoValid = false;
705 DomTreeNodeBase<NodeT> *NewNode = createNode(BB);
706 if (Roots.empty()) {
707 addRoot(BB);
708 } else {
709 assert(Roots.size() == 1);
710 NodeT *OldRoot = Roots.front();
711 DomTreeNodeBase<NodeT> *OldNode = getNode(OldRoot);
712 NewNode->addChild(OldNode);
713 OldNode->IDom = NewNode;
714 OldNode->UpdateLevel();
715 Roots[0] = BB;
716 }
717 return RootNode = NewNode;
718 }
719
720 /// changeImmediateDominator - This method is used to update the dominator
721 /// tree information when a node's immediate dominator changes.
722 ///
724 DomTreeNodeBase<NodeT> *NewIDom) {
725 assert(N && NewIDom && "Cannot change null node pointers!");
726 DFSInfoValid = false;
727 N->setIDom(NewIDom);
728 }
729
730 void changeImmediateDominator(NodeT *BB, NodeT *NewBB) {
732 }
733
734 /// eraseNode - Removes a node from the dominator tree. Block must not
735 /// dominate any other blocks. Removes node from its immediate dominator's
736 /// children list. Deletes dominator node associated with basic block BB.
737 void eraseNode(NodeT *BB) {
738 std::optional<unsigned> IdxOpt = getNodeIndex(BB);
739 assert(IdxOpt && DomTreeNodes[*IdxOpt] &&
740 "Removing node that isn't in dominator tree.");
741 DomTreeNodeBase<NodeT> *Node = DomTreeNodes[*IdxOpt].get();
742 assert(Node->isLeaf() && "Node is not a leaf node.");
743
744 DFSInfoValid = false;
745
746 // Remove node from immediate dominator's children list.
747 DomTreeNodeBase<NodeT> *IDom = Node->getIDom();
748 if (IDom) {
749 const auto I = find(IDom->Children, Node);
750 assert(I != IDom->Children.end() &&
751 "Not in immediate dominator children set!");
752 // I am no longer your child...
753 std::swap(*I, IDom->Children.back());
754 IDom->Children.pop_back();
755 }
756
757 DomTreeNodes[*IdxOpt] = nullptr;
758 if constexpr (!GraphHasNodeNumbers<NodeT *>)
759 NodeNumberMap.erase(BB);
760
761 if (!IsPostDom) return;
762
763 // Remember to update PostDominatorTree roots.
764 auto RIt = llvm::find(Roots, BB);
765 if (RIt != Roots.end()) {
766 std::swap(*RIt, Roots.back());
767 Roots.pop_back();
768 }
769 }
770
771 /// splitBlock - BB is split and now it has one successor. Update dominator
772 /// tree to reflect this change.
773 void splitBlock(NodeT *NewBB) {
774 if (IsPostDominator)
776 else
777 Split<NodeT *>(NewBB);
778 }
779
780 /// print - Convert to human readable form
781 ///
782 void print(raw_ostream &O) const {
783 O << "=============================--------------------------------\n";
784 if (IsPostDominator)
785 O << "Inorder PostDominator Tree: ";
786 else
787 O << "Inorder Dominator Tree: ";
788 if (!DFSInfoValid)
789 O << "DFSNumbers invalid: " << SlowQueries << " slow queries.";
790 O << "\n";
791
792 // The postdom tree can have a null root if there are no returns.
794 O << "Roots: ";
795 for (const NodePtr Block : Roots) {
796 Block->printAsOperand(O, false);
797 O << " ";
798 }
799 O << "\n";
800 }
801
802public:
803 /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
804 /// dominator tree in dfs order.
805 void updateDFSNumbers() const {
806 if (DFSInfoValid) {
807 SlowQueries = 0;
808 return;
809 }
810
813 32> WorkStack;
814
815 const DomTreeNodeBase<NodeT> *ThisRoot = getRootNode();
816 assert((!Parent || ThisRoot) && "Empty constructed DomTree");
817 if (!ThisRoot)
818 return;
819
820 // Both dominators and postdominators have a single root node. In the case
821 // case of PostDominatorTree, this node is a virtual root.
822 WorkStack.push_back({ThisRoot, ThisRoot->begin()});
823
824 unsigned DFSNum = 0;
825 ThisRoot->DFSNumIn = DFSNum++;
826
827 while (!WorkStack.empty()) {
828 const DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
829 const auto ChildIt = WorkStack.back().second;
830
831 // If we visited all of the children of this node, "recurse" back up the
832 // stack setting the DFOutNum.
833 if (ChildIt == Node->end()) {
834 Node->DFSNumOut = DFSNum++;
835 WorkStack.pop_back();
836 } else {
837 // Otherwise, recursively visit this child.
838 const DomTreeNodeBase<NodeT> *Child = *ChildIt;
839 ++WorkStack.back().second;
840
841 WorkStack.push_back({Child, Child->begin()});
842 Child->DFSNumIn = DFSNum++;
843 }
844 }
845
846 SlowQueries = 0;
847 DFSInfoValid = true;
848 }
849
850private:
851 void updateBlockNumberEpoch() {
852 // Nothing to do for graphs that don't number their blocks.
853 if constexpr (GraphHasNodeNumbers<NodeT *>)
855 }
856
857public:
858 /// recalculate - compute a dominator tree for the given function
860 Parent = &Func;
861 updateBlockNumberEpoch();
863 }
864
866 Parent = &Func;
867 updateBlockNumberEpoch();
869 }
870
871 /// Update dominator tree after renumbering blocks.
872 template <typename T = NodeT>
873 std::enable_if_t<GraphHasNodeNumbers<T *>, void> updateBlockNumbers() {
874 updateBlockNumberEpoch();
875
876 unsigned MaxNumber = GraphTraits<ParentPtr>::getMaxNumber(Parent);
877 DomTreeNodeStorageTy NewVector;
878 NewVector.resize(MaxNumber + 1); // +1, because index 0 is for nullptr
879 for (auto &Node : DomTreeNodes) {
880 if (!Node)
881 continue;
882 unsigned Idx = *getNodeIndex(Node->getBlock());
883 // getMaxNumber is not necessarily supported
884 if (Idx >= NewVector.size())
885 NewVector.resize(Idx + 1);
886 NewVector[Idx] = std::move(Node);
887 }
888 DomTreeNodes = std::move(NewVector);
889 }
890
891 /// verify - checks if the tree is correct. There are 3 level of verification:
892 /// - Full -- verifies if the tree is correct by making sure all the
893 /// properties (including the parent and the sibling property)
894 /// hold.
895 /// Takes O(N^3) time.
896 ///
897 /// - Basic -- checks if the tree is correct, but compares it to a freshly
898 /// constructed tree instead of checking the sibling property.
899 /// Takes O(N^2) time.
900 ///
901 /// - Fast -- checks basic tree structure and compares it with a freshly
902 /// constructed tree.
903 /// Takes O(N^2) time worst case, but is faster in practise (same
904 /// as tree construction).
906 return DomTreeBuilder::Verify(*this, VL);
907 }
908
909 void reset() {
910 DomTreeNodes.clear();
911 if constexpr (!GraphHasNodeNumbers<NodeT *>)
912 NodeNumberMap.clear();
913 Roots.clear();
914 RootNode = nullptr;
915 Parent = nullptr;
916 DFSInfoValid = false;
917 SlowQueries = 0;
918 }
919
920protected:
921 inline void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
922
924 DomTreeNodeBase<NodeT> *IDom = nullptr) {
925 auto Node = std::make_unique<DomTreeNodeBase<NodeT>>(BB, IDom);
926 auto *NodePtr = Node.get();
927 unsigned NodeIdx = getNodeIndexForInsert(BB);
928 DomTreeNodes[NodeIdx] = std::move(Node);
929 if (IDom)
930 IDom->addChild(NodePtr);
931 return NodePtr;
932 }
933
934 // NewBB is split and now it has one successor. Update dominator tree to
935 // reflect this change.
936 template <class N>
937 void Split(typename GraphTraits<N>::NodeRef NewBB) {
938 using GraphT = GraphTraits<N>;
939 using NodeRef = typename GraphT::NodeRef;
941 "NewBB should have a single successor!");
942 NodeRef NewBBSucc = *GraphT::child_begin(NewBB);
943
945
946 assert(!PredBlocks.empty() && "No predblocks?");
947
948 bool NewBBDominatesNewBBSucc = true;
949 for (auto *Pred : inverse_children<N>(NewBBSucc)) {
950 if (Pred != NewBB && !dominates(NewBBSucc, Pred) &&
951 isReachableFromEntry(Pred)) {
952 NewBBDominatesNewBBSucc = false;
953 break;
954 }
955 }
956
957 // Find NewBB's immediate dominator and create new dominator tree node for
958 // NewBB.
959 NodeT *NewBBIDom = nullptr;
960 unsigned i = 0;
961 for (i = 0; i < PredBlocks.size(); ++i)
962 if (isReachableFromEntry(PredBlocks[i])) {
963 NewBBIDom = PredBlocks[i];
964 break;
965 }
966
967 // It's possible that none of the predecessors of NewBB are reachable;
968 // in that case, NewBB itself is unreachable, so nothing needs to be
969 // changed.
970 if (!NewBBIDom) return;
971
972 for (i = i + 1; i < PredBlocks.size(); ++i) {
973 if (isReachableFromEntry(PredBlocks[i]))
974 NewBBIDom = findNearestCommonDominator(NewBBIDom, PredBlocks[i]);
975 }
976
977 // Create the new dominator tree node... and set the idom of NewBB.
978 DomTreeNodeBase<NodeT> *NewBBNode = addNewBlock(NewBB, NewBBIDom);
979
980 // If NewBB strictly dominates other blocks, then it is now the immediate
981 // dominator of NewBBSucc. Update the dominator tree as appropriate.
982 if (NewBBDominatesNewBBSucc) {
983 DomTreeNodeBase<NodeT> *NewBBSuccNode = getNode(NewBBSucc);
984 changeImmediateDominator(NewBBSuccNode, NewBBNode);
985 }
986 }
987
988 private:
989 bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
990 const DomTreeNodeBase<NodeT> *B) const {
991 assert(A != B);
994
995 const unsigned ALevel = A->getLevel();
996 const DomTreeNodeBase<NodeT> *IDom;
997
998 // Don't walk nodes above A's subtree. When we reach A's level, we must
999 // either find A or be in some other subtree not dominated by A.
1000 while ((IDom = B->getIDom()) != nullptr && IDom->getLevel() >= ALevel)
1001 B = IDom; // Walk up the tree
1002
1003 return B == A;
1004 }
1005
1006 /// Wipe this tree's state without releasing any resources.
1007 ///
1008 /// This is essentially a post-move helper only. It leaves the object in an
1009 /// assignable and destroyable state, but otherwise invalid.
1010 void wipe() {
1012 if constexpr (!GraphHasNodeNumbers<NodeT *>)
1013 NodeNumberMap.clear();
1014 RootNode = nullptr;
1015 Parent = nullptr;
1016 }
1017};
1018
1019template <typename T>
1021
1022template <typename T>
1024
1025// These two functions are declared out of line as a workaround for building
1026// with old (< r147295) versions of clang because of pr11642.
1027template <typename NodeT, bool IsPostDom>
1029 const NodeT *B) const {
1030 if (A == B)
1031 return true;
1032
1033 return dominates(getNode(A), getNode(B));
1034}
1035template <typename NodeT, bool IsPostDom>
1037 const NodeT *A, const NodeT *B) const {
1038 if (A == B)
1039 return false;
1040
1041 return dominates(getNode(A), getNode(B));
1042}
1043
1044} // end namespace llvm
1045
1046#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)
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:58
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:41
bool empty() const
empty - Check if the array is empty.
Definition ArrayRef.h:142
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
typename SmallVector< DomTreeNodeBase *, 4 >::const_iterator const_iterator
unsigned getDFSNumOut() const
const_iterator begin() const
void addChild(DomTreeNodeBase *C)
Core dominator tree base class.
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
DominatorTreeBase(DominatorTreeBase &&Arg)
NodeT * findNearestCommonDominator(iterator_range< IteratorTy > Nodes) const
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.
DominatorTreeBase & operator=(DominatorTreeBase &&RHS)
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.
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
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
SmallVector< std::unique_ptr< DomTreeNodeBase< BlockT > > > DomTreeNodeStorageTy
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.
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.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:318
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:1731
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:2116
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:302
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 >
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:1847
iterator_range< typename GraphTraits< GraphType >::ChildIteratorType > children(const typename GraphTraits< GraphType >::NodeRef &G)
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:851
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:853
#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