1//===- GenericDomTree.h - Generic dominator trees for graphs ----*- C++ -*-===// 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 7//===----------------------------------------------------------------------===// 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 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. 20/// FIXME: Maybe GenericDomTree needs a TreeTraits, instead of GraphTraits. 22//===----------------------------------------------------------------------===// 24#ifndef LLVM_SUPPORT_GENERICDOMTREE_H 25#define LLVM_SUPPORT_GENERICDOMTREE_H 45template <
typename NodeT,
bool IsPostDom>
46classDominatorTreeBase;
48namespaceDomTreeBuilder {
49template <
typename DomTreeT>
51}
// namespace DomTreeBuilder 53/// Base class for the actual dominator tree node. 65mutableunsigned DFSNumIn = ~0;
66mutableunsigned DFSNumOut = ~0;
70 : TheBB(BB), IDom(iDom), Level(IDom ? IDom->Level + 1 : 0) {}
95boolisLeaf()
const{
return Children.empty(); }
104if (Level !=
Other->Level)
returntrue;
108const NodeT *Nd =
I->getBlock();
113const NodeT *
N =
I->getBlock();
114if (OtherChildren.
count(
N) == 0)
121assert(IDom &&
"No immediate dominator?");
122if (IDom == NewIDom)
return;
124autoI =
find(IDom->Children,
this);
125assert(
I != IDom->Children.end() &&
126"Not in immediate dominator children set!");
127// I am no longer your child... 128 IDom->Children.erase(
I);
130// Switch to new dominator 132 IDom->Children.push_back(
this);
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. 144// Return true if this node is dominated by other. Use this only if DFS info 147return this->DFSNumIn >= other->DFSNumIn &&
148 this->DFSNumOut <= other->DFSNumOut;
153if (Level == IDom->Level + 1)
return;
155 SmallVector<DomTreeNodeBase *, 64> WorkStack = {
this};
157while (!WorkStack.empty()) {
159 Current->Level = Current->IDom->Level + 1;
161for (DomTreeNodeBase *
C : *Current) {
163if (
C->Level !=
C->IDom->Level + 1) WorkStack.push_back(
C);
169template <
class NodeT>
174 O <<
" <<exit node>>";
176 O <<
" {" <<
Node->getDFSNumIn() <<
"," <<
Node->getDFSNumOut() <<
"} [" 177 <<
Node->getLevel() <<
"]\n";
182template <
class NodeT>
185 O.indent(2 * Lev) <<
"[" << Lev <<
"] " <<
N;
186for (
constauto &
I : *
N)
187 PrintDomTree<NodeT>(
I, O, Lev + 1);
190namespaceDomTreeBuilder {
191// The routines below are provided in a separate header but referenced here. 192template <
typename DomTreeT>
195template <
typename DomTreeT>
197 ArrayRef<typename DomTreeT::UpdateType> Updates);
199template <
typename DomTreeT>
201typename DomTreeT::NodePtr To);
203template <
typename DomTreeT>
205typename DomTreeT::NodePtr To);
207template <
typename DomTreeT>
209 GraphDiff<
typename DomTreeT::NodePtr,
210 DomTreeT::IsPostDominator> &PreViewCFG,
211 GraphDiff<
typename DomTreeT::NodePtr,
212 DomTreeT::IsPostDominator> *PostViewCFG);
214template <
typename DomTreeT>
215boolVerify(
const DomTreeT &DT,
typename DomTreeT::VerificationLevel VL);
216}
// namespace DomTreeBuilder 218/// Default DomTreeNode traits for NodeT. The default implementation assume a 219/// Function-like NodeT. Can be specialized to support different node types. 223usingParentPtr =
decltype(std::declval<NodePtr>()->getParent());
224static_assert(std::is_pointer_v<ParentPtr>,
225"Currently NodeT's parent must be a pointer type");
232/// Core dominator tree base class. 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>
239static_assert(std::is_pointer_v<typename GraphTraits<NodeT *>::NodeRef>,
240"Currently DominatorTreeBase supports only pointer nodes");
245static_assert(std::is_pointer_v<ParentPtr>,
246"Currently NodeT's parent must be a pointer type");
258// Dominators always have a single root, postdominators can have more. 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 *>,
307 /// Iteration over roots. 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 329 /// isPostDominator - Returns true if analysis based of postdoms 333 /// compare - Return false if the other dominator tree base matches this 334 /// dominator tree base. Otherwise return true. 345// All nodes we have must exist and be equal in the other tree. 354// If the other tree has more nodes than we have, they're not equal. 355size_t NumOtherNodes = 0;
356for (
constauto &OtherNode :
Other.DomTreeNodes)
359return NumNodes != NumOtherNodes;
363 std::optional<unsigned> getNodeIndex(
const NodeT *BB)
const{
364ifconstexpr (GraphHasNodeNumbers<NodeT *>) {
365// BB can be nullptr, map nullptr to index 0. 368"dominator tree used with outdated block numbers");
377unsigned getNodeIndexForInsert(
const NodeT *BB) {
378ifconstexpr (GraphHasNodeNumbers<NodeT *>) {
379// getNodeIndex will never fail if nodes have getNumber(). 380unsignedIdx = *getNodeIndex(BB);
382unsignedMax = GraphTraits<ParentPtr>::getMaxNumber(
Parent);
387// We might already have a number stored for BB. 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. 403"cannot get DomTreeNode of block with different parent");
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 424 /// Get all nodes dominated by R, including R itself. 429return;
// If R is unreachable, it will not be present in the DOM tree. 435 Result.push_back(
N->getBlock());
440 /// properlyDominates - Returns true iff A dominates B and A != B. 441 /// Note that this is not a constant time operation! 454 /// isReachableFromEntry - Return true if A is dominated by the entry 455 /// block of the function containing it. 458"This is not implemented for post dominators");
464 /// dominates - Returns true iff A dominates B. Note that this is not a 465 /// constant time operation! 469// A node trivially dominates itself. 473// An unreachable node is dominated by anything. 477// And dominates nothing. 481if (
B->getIDom() ==
A)
returntrue;
483if (
A->getIDom() ==
B)
returnfalse;
485// A can only dominate B if it is higher in the tree. 486if (
A->getLevel() >=
B->getLevel())
returnfalse;
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!");
497returnB->DominatedBy(
A);
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. 504returnB->DominatedBy(
A);
507return dominatedBySlowTreeWalk(
A,
B);
513assert(this->Roots.
size() == 1 &&
"Should always have entry node!");
514return this->Roots[0];
517 /// Find nearest common dominator basic block for basic block A and B. A and B 518 /// must have tree nodes. 520assert(
A &&
B &&
"Pointers are not valid");
522"Two blocks are not in same function");
524// If either A or B is a entry block then it is nearest common dominator 525// (for forward-dominators). 529if (
A == &Entry ||
B == &Entry)
535assert(NodeA &&
"A must be in the tree");
536assert(NodeB &&
"B must be in the tree");
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. 540while (NodeA != NodeB) {
550const NodeT *
B)
const{
551// Cast away the const qualifiers here. This is ok since 552// const is re-introduced on the return type. 554const_cast<NodeT *
>(
B));
561template <
typename IteratorTy>
565 NodeT *NCD = *Nodes.
begin();
569// Stop when the root is reached. 577//===--------------------------------------------------------------------===// 578// API to update (Post)DominatorTree information based on modifications to 581 /// Inform the dominator tree about a sequence of CFG edge insertions and 582 /// deletions and perform a batch update on the tree. 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. 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. 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. 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. 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. 614 Updates,
/*ReverseApplyUpdates=*/true);
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. 625if (Updates.
empty()) {
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 637/*ReverseApplyUpdates=*/true);
643 /// Inform the dominator tree about a CFG edge insertion and update the tree. 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. 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). 660 /// Inform the dominator tree about a CFG edge deletion and update the tree. 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. 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). 678 /// Add a new node to the dominator tree information. 680 /// This creates a new node as a child of DomBB dominator node, linking it 681 /// into the children list of the immediate dominator. 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. 688assert(
getNode(BB) ==
nullptr &&
"Block already in dominator tree!");
690assert(IDomNode &&
"Not immediate dominator specified for block!");
695 /// Add a new node to the forward dominator tree and make it a new root. 697 /// \param BB New node in CFG. 698 /// \returns New dominator tree node that represents new CFG node. 701assert(
getNode(BB) ==
nullptr &&
"Block already in dominator tree!");
703"Cannot change root of post-dominator tree");
713 OldNode->IDom = NewNode;
714 OldNode->UpdateLevel();
720 /// changeImmediateDominator - This method is used to update the dominator 721 /// tree information when a node's immediate dominator changes. 725assert(
N && NewIDom &&
"Cannot change null node pointers!");
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. 738 std::optional<unsigned> IdxOpt = getNodeIndex(BB);
740"Removing node that isn't in dominator tree.");
742assert(
Node->isLeaf() &&
"Node is not a leaf node.");
746// Remove node from immediate dominator's children list. 750assert(
I != IDom->Children.end() &&
751"Not in immediate dominator children set!");
752// I am no longer your child... 754 IDom->Children.pop_back();
758ifconstexpr (!GraphHasNodeNumbers<NodeT *>)
761if (!IsPostDom)
return;
763// Remember to update PostDominatorTree roots. 771 /// splitBlock - BB is split and now it has one successor. Update dominator 772 /// tree to reflect this change. 775 Split<Inverse<NodeT *>>(NewBB);
777 Split<NodeT *>(NewBB);
780 /// print - Convert to human readable form 783 O <<
"=============================--------------------------------\n";
785 O <<
"Inorder PostDominator Tree: ";
787 O <<
"Inorder Dominator Tree: ";
789 O <<
"DFSNumbers invalid: " <<
SlowQueries <<
" slow queries.";
792// The postdom tree can have a null root if there are no returns. 796Block->printAsOperand(O,
false);
803 /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking 804 /// dominator tree in dfs order. 816assert((!
Parent || ThisRoot) &&
"Empty constructed DomTree");
820// Both dominators and postdominators have a single root node. In the case 821// case of PostDominatorTree, this node is a virtual root. 825 ThisRoot->DFSNumIn = DFSNum++;
827while (!WorkStack.
empty()) {
829constauto ChildIt = WorkStack.
back().second;
831// If we visited all of the children of this node, "recurse" back up the 832// stack setting the DFOutNum. 833if (ChildIt ==
Node->end()) {
834Node->DFSNumOut = DFSNum++;
837// Otherwise, recursively visit this child. 839 ++WorkStack.
back().second;
842 Child->DFSNumIn = DFSNum++;
851void updateBlockNumberEpoch() {
852// Nothing to do for graphs that don't number their blocks. 853ifconstexpr (GraphHasNodeNumbers<NodeT *>)
858 /// recalculate - compute a dominator tree for the given function 861 updateBlockNumberEpoch();
867 updateBlockNumberEpoch();
871 /// Update dominator tree after renumbering blocks. 872template <
typename T = NodeT>
874 updateBlockNumberEpoch();
878 NewVector.
resize(MaxNumber + 1);
// +1, because index 0 is for nullptr 882unsignedIdx = *getNodeIndex(
Node->getBlock());
883// getMaxNumber is not necessarily supported 886 NewVector[
Idx] = std::move(
Node);
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) 895 /// Takes O(N^3) time. 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. 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). 911ifconstexpr (!GraphHasNodeNumbers<NodeT *>)
925autoNode = std::make_unique<DomTreeNodeBase<NodeT>>(BB, IDom);
927unsigned NodeIdx = getNodeIndexForInsert(BB);
934// NewBB is split and now it has one successor. Update dominator tree to 935// reflect this change. 939usingNodeRef =
typename GraphT::NodeRef;
941"NewBB should have a single successor!");
942 NodeRef NewBBSucc = *GraphT::child_begin(NewBB);
948bool NewBBDominatesNewBBSucc =
true;
949for (
auto *Pred : inverse_children<N>(NewBBSucc)) {
950if (Pred != NewBB && !
dominates(NewBBSucc, Pred) &&
952 NewBBDominatesNewBBSucc =
false;
957// Find NewBB's immediate dominator and create new dominator tree node for 959 NodeT *NewBBIDom =
nullptr;
961for (i = 0; i < PredBlocks.
size(); ++i)
963 NewBBIDom = PredBlocks[i];
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 970if (!NewBBIDom)
return;
972for (i = i + 1; i < PredBlocks.
size(); ++i) {
977// Create the new dominator tree node... and set the idom of NewBB. 980// If NewBB strictly dominates other blocks, then it is now the immediate 981// dominator of NewBBSucc. Update the dominator tree as appropriate. 982if (NewBBDominatesNewBBSucc) {
995constunsigned ALevel =
A->getLevel();
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. 1000while ((IDom =
B->getIDom()) !=
nullptr && IDom->
getLevel() >= ALevel)
1001B = IDom;
// Walk up the tree 1006 /// Wipe this tree's state without releasing any resources. 1008 /// This is essentially a post-move helper only. It leaves the object in an 1009 /// assignable and destroyable state, but otherwise invalid. 1012ifconstexpr (!GraphHasNodeNumbers<NodeT *>)
1019template <
typename T>
1022template <
typename T>
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>
1029const NodeT *
B)
const{
1035template <
typename NodeT,
bool IsPostDom>
1037const NodeT *
A,
const NodeT *
B)
const{
1044}
// end namespace llvm 1046#endif// LLVM_SUPPORT_GENERICDOMTREE_H static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
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...
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.
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),...
bool empty() const
empty - Check if the array is empty.
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
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.
DominatorTreeBase()=default
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
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)
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
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)
unsigned BlockNumberEpoch
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.
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 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.
This class implements an extremely fast bulk output stream that can only output to a stream.
@ C
The default llvm calling convention, compatible with C.
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 Calculate(DomTreeT &DT)
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.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
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.
bool hasSingleElement(ContainerTy &&C)
Returns true if the given container only contains a single element.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
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