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