18 #ifndef LLVM_SUPPORT_GENERICDOMTREE_H
19 #define LLVM_SUPPORT_GENERICDOMTREE_H
47 Roots = std::move(RHS.Roots);
65 template <
class NodeT>
class DominatorTreeBase;
66 struct PostDominatorTree;
69 template <
class NodeT>
class DomTreeNodeBase {
71 DomTreeNodeBase<NodeT> *IDom;
72 std::vector<DomTreeNodeBase<NodeT> *> Children;
73 mutable int DFSNumIn, DFSNumOut;
90 const std::vector<DomTreeNodeBase<NodeT> *> &
getChildren()
const {
95 : TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) {}
97 std::unique_ptr<DomTreeNodeBase<NodeT>>
99 Children.push_back(
C.get());
113 const NodeT *Nd = (*I)->getBlock();
118 const NodeT *
N = (*I)->getBlock();
119 if (OtherChildren.
count(N) == 0)
126 assert(IDom &&
"No immediate dominator?");
127 if (IDom != NewIDom) {
128 typename std::vector<DomTreeNodeBase<NodeT> *>
::iterator I =
129 std::find(IDom->Children.begin(), IDom->Children.end(),
this);
130 assert(I != IDom->Children.end() &&
131 "Not in immediate dominator children set!");
133 IDom->Children.erase(I);
137 IDom->Children.push_back(
this);
150 return this->DFSNumIn >= other->DFSNumIn &&
151 this->DFSNumOut <= other->DFSNumOut;
155 template <
class NodeT>
156 raw_ostream &operator<<(raw_ostream &o, const DomTreeNodeBase<NodeT> *Node) {
157 if (Node->getBlock())
158 Node->getBlock()->printAsOperand(o,
false);
160 o <<
" <<exit node>>";
162 o <<
" {" << Node->getDFSNumIn() <<
"," << Node->getDFSNumOut() <<
"}";
167 template <
class NodeT>
170 o.
indent(2 * Lev) <<
"[" << Lev <<
"] " <<
N;
174 PrintDomTree<NodeT>(*
I, o, Lev + 1);
178 template <
class FuncT,
class N>
186 template <
class NodeT>
class DominatorTreeBase :
public DominatorBase<NodeT> {
187 DominatorTreeBase(
const DominatorTreeBase &) =
delete;
188 DominatorTreeBase &operator=(
const DominatorTreeBase &) =
delete;
190 bool dominatedBySlowTreeWalk(
const DomTreeNodeBase<NodeT> *
A,
191 const DomTreeNodeBase<NodeT> *B)
const {
196 const DomTreeNodeBase<NodeT> *IDom;
197 while ((IDom = B->getIDom()) !=
nullptr && IDom != A && IDom != B)
199 return IDom !=
nullptr;
215 typedef DenseMap<NodeT *, std::unique_ptr<DomTreeNodeBase<NodeT>>>
252 template <
class N,
class GraphT>
255 assert(std::distance(GraphT::child_begin(NewBB),
256 GraphT::child_end(NewBB)) == 1 &&
257 "NewBB should have a single successor!");
260 std::vector<typename GraphT::NodeType *> PredBlocks;
262 for (
typename InvTraits::ChildIteratorType
263 PI = InvTraits::child_begin(NewBB),
264 PE = InvTraits::child_end(NewBB);
266 PredBlocks.push_back(*PI);
268 assert(!PredBlocks.empty() &&
"No predblocks?");
270 bool NewBBDominatesNewBBSucc =
true;
271 for (
typename InvTraits::ChildIteratorType
272 PI = InvTraits::child_begin(NewBBSucc),
273 E = InvTraits::child_end(NewBBSucc);
276 if (ND != NewBB && !DT.dominates(NewBBSucc, ND) &&
277 DT.isReachableFromEntry(ND)) {
278 NewBBDominatesNewBBSucc =
false;
285 NodeT *NewBBIDom =
nullptr;
287 for (i = 0; i < PredBlocks.size(); ++i)
288 if (DT.isReachableFromEntry(PredBlocks[i])) {
289 NewBBIDom = PredBlocks[i];
299 for (i = i + 1; i < PredBlocks.size(); ++i) {
300 if (DT.isReachableFromEntry(PredBlocks[i]))
301 NewBBIDom = DT.findNearestCommonDominator(NewBBIDom, PredBlocks[i]);
309 if (NewBBDominatesNewBBSucc) {
311 DT.changeImmediateDominator(NewBBSuccNode, NewBBNode);
336 IDoms = std::move(RHS.IDoms);
337 Vertex = std::move(RHS.Vertex);
338 Info = std::move(RHS.Info);
355 NodeT *BB =
I->first;
357 OtherDomTreeNodes.
find(BB);
358 if (OI == OtherDomTreeNodes.
end())
379 return I->second.get();
404 while (!WL.
empty()) {
429 "This is not implemented for post dominators");
456 (dominatedBySlowTreeWalk(A, B) == B->DominatedBy(A))) &&
457 "Tree walk disagrees with dfs numbers!");
461 return B->DominatedBy(A);
468 return B->DominatedBy(A);
471 return dominatedBySlowTreeWalk(A, B);
474 bool dominates(
const NodeT *A,
const NodeT *B)
const;
477 assert(this->
Roots.size() == 1 &&
"Should always have entry node!");
478 return this->
Roots[0];
484 assert(A->getParent() == B->getParent() &&
485 "Two blocks are not in same function");
490 NodeT &Entry = A->getParent()->front();
491 if (A == &Entry || B == &Entry)
514 if (NodeB->DominatedBy(IDomA))
533 if (NodeADoms.
count(IDomB) != 0)
546 const_cast<NodeT *>(B));
557 assert(
getNode(BB) ==
nullptr &&
"Block already in dominator tree!");
559 assert(IDomNode &&
"Not immediate dominator specified for block!");
570 assert(N && NewIDom &&
"Cannot change null node pointers!");
584 assert(Node &&
"Removing node that isn't in dominator tree.");
585 assert(Node->
getChildren().empty() &&
"Node is not a leaf node.");
590 typename std::vector<DomTreeNodeBase<NodeT> *>::iterator
I =
591 std::find(IDom->Children.begin(), IDom->Children.end(), Node);
592 assert(I != IDom->Children.end() &&
593 "Not in immediate dominator children set!");
595 IDom->Children.erase(I);
608 this->Split<NodeT *, GraphTraits<NodeT *>>(*
this, NewBB);
614 o <<
"=============================--------------------------------\n";
616 o <<
"Inorder PostDominator Tree: ";
618 o <<
"Inorder Dominator Tree: ";
620 o <<
"DFSNumbers invalid: " <<
SlowQueries <<
" slow queries.";
629 template <
class GraphT>
634 template <
class GraphT>
638 template <
class FuncT,
class N>
690 ThisRoot->DFSNumIn = DFSNum++;
692 while (!WorkStack.
empty()) {
694 typename DomTreeNodeBase<NodeT>::const_iterator ChildIt =
695 WorkStack.
back().second;
699 if (ChildIt == Node->
end()) {
700 Node->DFSNumOut = DFSNum++;
705 ++WorkStack.
back().second;
708 Child->DFSNumIn = DFSNum++;
720 this->
Vertex.push_back(
nullptr);
724 NodeT *entry = TraitsTy::getEntryNode(&F);
725 this->
Roots.push_back(entry);
726 this->
IDoms[entry] =
nullptr;
729 Calculate<FT, NodeT *>(*
this,
F);
732 for (
typename TraitsTy::nodes_iterator
I = TraitsTy::nodes_begin(&F),
733 E = TraitsTy::nodes_end(&F);
735 if (TraitsTy::child_begin(
I) == TraitsTy::child_end(
I))
744 Calculate<FT, Inverse<NodeT *>>(*
this,
F);
751 template <
class NodeT>
759 return dominates(getNode(const_cast<NodeT *>(A)),
760 getNode(const_cast<NodeT *>(B)));
762 template <
class NodeT>
764 const NodeT *B)
const {
771 return dominates(getNode(const_cast<NodeT *>(A)),
772 getNode(const_cast<NodeT *>(B)));
std::vector< NodeT * > Roots
DomTreeNodeBase< NodeT > * addNewBlock(NodeT *BB, NodeT *DomBB)
addNewBlock - 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
void Split(DominatorTreeBase< typename GraphT::NodeType > &DT, typename GraphT::NodeType *NewBB)
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
void getDescendants(NodeT *R, SmallVectorImpl< NodeT * > &Result) const
Get all nodes dominated by R, including R itself.
bool compare(const DomTreeNodeBase< NodeT > *Other) const
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.
DominatorTreeBase(bool isPostDom)
bool isPostDominator() const
isPostDominator - Returns true if analysis based of postdoms
friend GraphT::NodeType * Eval(DominatorTreeBase< typename GraphT::NodeType > &DT, typename GraphT::NodeType *V, unsigned LastLinked)
DominatorTreeBase(DominatorTreeBase &&Arg)
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
NodeT * getIDom(NodeT *BB) const
DomTreeNodeMapType DomTreeNodes
void setIDom(DomTreeNodeBase< NodeT > *NewIDom)
std::vector< DomTreeNodeBase< NodeT > * >::iterator iterator
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
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.
unsigned getDFSNumIn() const
getDFSNumIn/getDFSNumOut - These are an internal implementation detail, do not call them...
DominatorBase(bool isPostDom)
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
friend void Calculate(DominatorTreeBase< typename GraphTraits< N >::NodeType > &DT, FuncT &F)
DominatorBase & operator=(DominatorBase &&RHS)
DominatorTreeBase & operator=(DominatorTreeBase &&RHS)
DenseMap< NodeT *, NodeT * > IDoms
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.
const_iterator begin() const
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 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.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
DomTreeNodeBase< NodeT > * operator[](NodeT *BB) const
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B)
findNearestCommonDominator - Find nearest common dominator basic block for basic block A and B...
const std::vector< DomTreeNodeBase< NodeT > * > & getChildren() const
std::vector< NodeT * > Vertex
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
std::unique_ptr< DomTreeNodeBase< NodeT > > addChild(std::unique_ptr< DomTreeNodeBase< NodeT >> C)
void changeImmediateDominator(NodeT *BB, NodeT *NewBB)
DenseMap< NodeT *, InfoRec > Info
bool isReachableFromEntry(const DomTreeNodeBase< NodeT > *A) const
void Calculate(DominatorTreeBase< typename GraphTraits< N >::NodeType > &DT, FuncT &F)
void PrintDomTree(const DomTreeNodeBase< NodeT > *N, raw_ostream &o, unsigned Lev)
DomTreeNodeBase< NodeT > * getIDom() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
GraphType::UnknownGraphTypeError NodeType
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...
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...
std::vector< DomTreeNodeBase< NodeT > * >::const_iterator const_iterator
size_t getNumChildren() const
unsigned getDFSNumOut() const
void print(raw_ostream &o) const
print - Convert to human readable form
iterator find(const KeyT &Val)
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.
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...
DomTreeNodeBase(NodeT *BB, DomTreeNodeBase< NodeT > *iDom)
void recalculate(FT &F)
recalculate - compute a dominator tree for the given function
const_iterator end() const
DomTreeNodeBase< NodeT > * getNode(NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
const DomTreeNodeBase< NodeT > * getRootNode() const
friend unsigned DFSPass(DominatorTreeBase< typename GraphT::NodeType > &DT, typename GraphT::NodeType *V, unsigned N)
void splitBlock(NodeT *NewBB)
splitBlock - BB is split and now it has one successor.