24 #ifndef LLVM_SUPPORT_GENERICDOMTREE_H
25 #define LLVM_SUPPORT_GENERICDOMTREE_H
39 template <
class NodeT>
class DominatorTreeBase;
44 static_assert(std::is_pointer<typename GT::NodeRef>::value,
45 "Currently NodeRef must be a pointer type.");
47 typename std::remove_pointer<typename GT::NodeRef>::type>;
52 template <
typename GT>
70 Roots = std::move(RHS.Roots);
88 struct PostDominatorTree;
94 std::vector<DomTreeNodeBase<NodeT> *> Children;
95 mutable int DFSNumIn, DFSNumOut;
112 const std::vector<DomTreeNodeBase<NodeT> *> &
getChildren()
const {
117 : TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) {}
119 std::unique_ptr<DomTreeNodeBase<NodeT>>
121 Children.push_back(
C.get());
135 const NodeT *Nd =
I->getBlock();
141 if (OtherChildren.
count(N) == 0)
148 assert(IDom &&
"No immediate dominator?");
149 if (IDom != NewIDom) {
150 typename std::vector<DomTreeNodeBase<NodeT> *>
::iterator I =
151 find(IDom->Children,
this);
152 assert(I != IDom->Children.end() &&
153 "Not in immediate dominator children set!");
155 IDom->Children.erase(I);
159 IDom->Children.push_back(
this);
173 return this->DFSNumIn >= other->DFSNumIn &&
174 this->DFSNumOut <= other->DFSNumOut;
178 template <
class NodeT>
179 raw_ostream &operator<<(raw_ostream &o, const DomTreeNodeBase<NodeT> *Node) {
180 if (Node->getBlock())
181 Node->getBlock()->printAsOperand(o,
false);
183 o <<
" <<exit node>>";
185 o <<
" {" << Node->getDFSNumIn() <<
"," << Node->getDFSNumOut() <<
"}";
190 template <
class NodeT>
193 o.
indent(2 * Lev) <<
"[" << Lev <<
"] " <<
N;
197 PrintDomTree<NodeT>(*
I, o, Lev + 1);
201 template <
class FuncT,
class N>
208 template <
class NodeT>
class DominatorTreeBase :
public DominatorBase<NodeT> {
209 DominatorTreeBase(
const DominatorTreeBase &) =
delete;
210 DominatorTreeBase &operator=(
const DominatorTreeBase &) =
delete;
212 bool dominatedBySlowTreeWalk(
const DomTreeNodeBase<NodeT> *
A,
213 const DomTreeNodeBase<NodeT> *
B)
const {
218 const DomTreeNodeBase<NodeT> *IDom;
219 while ((IDom = B->getIDom()) !=
nullptr && IDom != A && IDom != B)
221 return IDom !=
nullptr;
237 typedef DenseMap<NodeT *, std::unique_ptr<DomTreeNodeBase<NodeT>>>
274 template <
class N,
class GraphT>
276 typename GraphT::NodeRef NewBB) {
277 assert(std::distance(GraphT::child_begin(NewBB),
278 GraphT::child_end(NewBB)) == 1 &&
279 "NewBB should have a single successor!");
280 typename GraphT::NodeRef NewBBSucc = *GraphT::child_begin(NewBB);
282 std::vector<typename GraphT::NodeRef> PredBlocks;
284 for (
typename InvTraits::ChildIteratorType
285 PI = InvTraits::child_begin(NewBB),
286 PE = InvTraits::child_end(NewBB);
288 PredBlocks.push_back(*PI);
290 assert(!PredBlocks.empty() &&
"No predblocks?");
292 bool NewBBDominatesNewBBSucc =
true;
293 for (
typename InvTraits::ChildIteratorType
294 PI = InvTraits::child_begin(NewBBSucc),
295 E = InvTraits::child_end(NewBBSucc);
297 typename InvTraits::NodeRef ND = *PI;
298 if (ND != NewBB && !DT.dominates(NewBBSucc, ND) &&
299 DT.isReachableFromEntry(ND)) {
300 NewBBDominatesNewBBSucc =
false;
307 NodeT *NewBBIDom =
nullptr;
309 for (i = 0; i < PredBlocks.size(); ++
i)
310 if (DT.isReachableFromEntry(PredBlocks[i])) {
311 NewBBIDom = PredBlocks[
i];
321 for (i = i + 1; i < PredBlocks.size(); ++
i) {
322 if (DT.isReachableFromEntry(PredBlocks[i]))
323 NewBBIDom = DT.findNearestCommonDominator(NewBBIDom, PredBlocks[i]);
331 if (NewBBDominatesNewBBSucc) {
333 DT.changeImmediateDominator(NewBBSuccNode, NewBBNode);
358 IDoms = std::move(RHS.IDoms);
359 Vertex = std::move(RHS.Vertex);
360 Info = std::move(RHS.Info);
376 OtherDomTreeNodes.
find(BB);
377 if (OI == OtherDomTreeNodes.
end())
399 return I->second.get();
425 while (!WL.
empty()) {
450 "This is not implemented for post dominators");
475 #ifdef EXPENSIVE_CHECKS
477 (dominatedBySlowTreeWalk(A, B) == B->DominatedBy(A))) &&
478 "Tree walk disagrees with dfs numbers!");
482 return B->DominatedBy(A);
489 return B->DominatedBy(A);
492 return dominatedBySlowTreeWalk(A, B);
495 bool dominates(
const NodeT *A,
const NodeT *B)
const;
498 assert(this->
Roots.size() == 1 &&
"Should always have entry node!");
499 return this->
Roots[0];
505 assert(A->getParent() == B->getParent() &&
506 "Two blocks are not in same function");
511 NodeT &Entry = A->getParent()->front();
512 if (A == &Entry || B == &Entry)
535 if (NodeB->DominatedBy(IDomA))
554 if (NodeADoms.
count(IDomB) != 0)
567 const_cast<NodeT *>(B));
584 assert(
getNode(BB) ==
nullptr &&
"Block already in dominator tree!");
586 assert(IDomNode &&
"Not immediate dominator specified for block!");
598 assert(
getNode(BB) ==
nullptr &&
"Block already in dominator tree!");
600 "Cannot change root of post-dominator tree");
604 llvm::make_unique<DomTreeNodeBase<NodeT>>(BB,
nullptr)).get();
609 NodeT *OldRoot =
Roots.front();
622 assert(N && NewIDom &&
"Cannot change null node pointers!");
636 assert(Node &&
"Removing node that isn't in dominator tree.");
642 typename std::vector<DomTreeNodeBase<NodeT> *>::iterator
I =
643 find(IDom->Children, Node);
644 assert(I != IDom->Children.end() &&
645 "Not in immediate dominator children set!");
647 IDom->Children.erase(I);
660 this->Split<NodeT *, GraphTraits<NodeT *>>(*
this, NewBB);
666 o <<
"=============================--------------------------------\n";
668 o <<
"Inorder PostDominator Tree: ";
670 o <<
"Inorder Dominator Tree: ";
672 o <<
"DFSNumbers invalid: " <<
SlowQueries <<
" slow queries.";
681 template <
class GraphT>
682 friend typename GraphT::NodeRef
684 unsigned LastLinked);
686 template <
class GraphT>
688 typename GraphT::NodeRef V,
unsigned N);
690 template <
class FuncT,
class N>
741 ThisRoot->DFSNumIn = DFSNum++;
743 while (!WorkStack.
empty()) {
745 typename DomTreeNodeBase<NodeT>::const_iterator ChildIt =
746 WorkStack.
back().second;
750 if (ChildIt == Node->
end()) {
751 Node->DFSNumOut = DFSNum++;
756 ++WorkStack.
back().second;
759 Child->DFSNumIn = DFSNum++;
771 this->
Vertex.push_back(
nullptr);
775 NodeT *entry = TraitsTy::getEntryNode(&F);
778 Calculate<FT, NodeT *>(*
this,
F);
781 for (
typename TraitsTy::nodes_iterator
I = TraitsTy::nodes_begin(&F),
782 E = TraitsTy::nodes_end(&F);
784 if (TraitsTy::child_begin(*
I) == TraitsTy::child_end(*
I))
787 Calculate<FT, Inverse<NodeT *>>(*
this,
F);
794 template <
class NodeT>
802 return dominates(getNode(const_cast<NodeT *>(A)),
803 getNode(const_cast<NodeT *>(B)));
805 template <
class NodeT>
807 const NodeT *B)
const {
814 return dominates(getNode(const_cast<NodeT *>(A)),
815 getNode(const_cast<NodeT *>(B)));
std::vector< NodeT * > Roots
DomTreeNodeBase< NodeT > * addNewBlock(NodeT *BB, NodeT *DomBB)
Add a new node to the dominator tree information.
void push_back(const T &Elt)
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
DenseMap< NodeT *, std::unique_ptr< DomTreeNodeBase< NodeT > > > DomTreeNodeMapType
const std::vector< DomTreeNodeBase< NodeT > * > & getChildren() const
std::unique_ptr< DomTreeNodeBase< NodeT > > addChild(std::unique_ptr< DomTreeNodeBase< NodeT >> C)
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
const_iterator end() const
void getDescendants(NodeT *R, SmallVectorImpl< NodeT * > &Result) const
Get all nodes dominated by R, including R itself.
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
const_iterator begin() const
void Calculate(DominatorTreeBaseByGraphTraits< GraphTraits< N >> &DT, FuncT &F)
DominatorTreeBase(bool isPostDom)
bool isPostDominator() const
isPostDominator - Returns true if analysis based of postdoms
DominatorTreeBase(DominatorTreeBase &&Arg)
NodeT * getIDom(NodeT *BB) const
DomTreeNodeMapType DomTreeNodes
DomTreeNodeBase< NodeT > * getIDom() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
DomTreeNodeBase< NodeT > * RootNode
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
LLVM_NODISCARD bool empty() const
DominatorBase(bool isPostDom)
Function Alias Analysis false
void Split(DominatorTreeBaseByGraphTraits< GraphT > &DT, typename GraphT::NodeRef NewBB)
Base class for the actual dominator tree node.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
DominatorBase & operator=(DominatorBase &&RHS)
DominatorTreeBase & operator=(DominatorTreeBase &&RHS)
DenseMap< NodeT *, NodeT * > IDoms
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
Core dominator tree base class.
bool erase(const KeyT &Val)
bool isReachableFromEntry(const NodeT *A) const
isReachableFromEntry - Return true if A is dominated by the entry block of the function containing it...
const std::vector< NodeT * > & getRoots() const
getRoots - Return the root blocks of the current CFG.
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&...args)
Constructs a new T() with the given args and returns a unique_ptr<T> which owns the object...
bool compare(const DomTreeNodeBase< NodeT > *Other) const
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
void eraseNode(NodeT *BB)
eraseNode - Removes a node from the dominator tree.
DomTreeNodeBase< NodeT > * setNewRoot(NodeT *BB)
Add a new node to the forward dominator tree and make it a new root.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
friend unsigned DFSPass(DominatorTreeBaseByGraphTraits< GraphT > &DT, typename GraphT::NodeRef V, unsigned N)
unsigned getDFSNumIn() const
getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes in the dominator tree...
DomTreeNodeBase< NodeT > * operator[](NodeT *BB) const
See getNode.
friend GraphT::NodeRef Eval(DominatorTreeBaseByGraphTraits< GraphT > &DT, typename GraphT::NodeRef V, unsigned LastLinked)
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B)
findNearestCommonDominator - Find nearest common dominator basic block for basic block A and B...
std::vector< NodeT * > Vertex
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
friend void Calculate(DominatorTreeBaseByGraphTraits< GraphTraits< N >> &DT, FuncT &F)
void changeImmediateDominator(NodeT *BB, NodeT *NewBB)
DenseMap< NodeT *, InfoRec > Info
bool isReachableFromEntry(const DomTreeNodeBase< NodeT > *A) const
void PrintDomTree(const DomTreeNodeBase< NodeT > *N, raw_ostream &o, unsigned Lev)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
void setIDom(DomTreeNodeBase< NodeT > *NewIDom)
auto find(R &&Range, const T &Val) -> decltype(std::begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
const NodeT * findNearestCommonDominator(const NodeT *A, const NodeT *B)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
LLVM_NODISCARD T pop_back_val()
std::vector< DomTreeNodeBase< NodeT > * >::const_iterator const_iterator
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
DomTreeNodeBase< NodeT > * getNodeForBlock(NodeT *BB)
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
void updateDFSNumbers() const
updateDFSNumbers - Assign In and Out numbers to the nodes while walking dominator tree in dfs order...
unsigned getDFSNumOut() const
void print(raw_ostream &o) const
print - Convert to human readable form
typename detail::DominatorTreeBaseTraits< GT >::type DominatorTreeBaseByGraphTraits
iterator find(const KeyT &Val)
DomTreeNodeBase(NodeT *BB, DomTreeNodeBase< NodeT > *iDom)
void changeImmediateDominator(DomTreeNodeBase< NodeT > *N, DomTreeNodeBase< NodeT > *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
Base class that other, more interesting dominator analyses inherit from.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::vector< DomTreeNodeBase< NodeT > * >::iterator iterator
DominatorBase(DominatorBase &&Arg)
bool compare(const DominatorTreeBase &Other) const
compare - Return false if the other dominator tree base matches this dominator tree base...
This class implements an extremely fast bulk output stream that can only output to a stream...
void recalculate(FT &F)
recalculate - compute a dominator tree for the given function
DomTreeNodeBase< NodeT > * getNode(NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
const DomTreeNodeBase< NodeT > * getRootNode() const
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
size_t getNumChildren() const
void splitBlock(NodeT *NewBB)
splitBlock - BB is split and now it has one successor.