15 #ifndef LLVM_ANALYSIS_DOMINATORS_H
16 #define LLVM_ANALYSIS_DOMINATORS_H
36 template <
class NodeT>
63 template <
class NodeT>
67 std::vector<DomTreeNodeBase<NodeT> *> Children;
68 int DFSNumIn, DFSNumOut;
84 const std::vector<DomTreeNodeBase<NodeT>*> &
getChildren()
const {
89 : TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) { }
92 Children.push_back(C);
97 return Children.size();
110 const NodeT *Nd = (*I)->getBlock();
115 const NodeT *
N = (*I)->getBlock();
116 if (OtherChildren.
count(N) == 0)
123 assert(IDom &&
"No immediate dominator?");
124 if (IDom != NewIDom) {
125 typename std::vector<DomTreeNodeBase<NodeT>*>
::iterator I =
126 std::find(IDom->Children.begin(), IDom->Children.end(),
this);
127 assert(I != IDom->Children.end() &&
128 "Not in immediate dominator children set!");
130 IDom->Children.erase(I);
134 IDom->Children.push_back(
this);
146 return this->DFSNumIn >= other->DFSNumIn &&
147 this->DFSNumOut <= other->DFSNumOut;
154 template<
class NodeT>
160 o <<
" <<exit node>>";
167 template<
class NodeT>
170 o.
indent(2*Lev) <<
"[" << Lev <<
"] " <<
N;
172 E = N->end();
I != E; ++
I)
173 PrintDomTree<NodeT>(*
I, o, Lev+1);
182 template<
class FuncT,
class N>
186 template<
class NodeT>
195 while ((IDom = B->
getIDom()) != 0 && IDom != A && IDom != B)
238 template<
class N,
class GraphT>
241 assert(std::distance(GraphT::child_begin(NewBB),
242 GraphT::child_end(NewBB)) == 1 &&
243 "NewBB should have a single successor!");
246 std::vector<typename GraphT::NodeType*> PredBlocks;
248 for (
typename InvTraits::ChildIteratorType PI =
249 InvTraits::child_begin(NewBB),
250 PE = InvTraits::child_end(NewBB); PI != PE; ++PI)
251 PredBlocks.push_back(*PI);
253 assert(!PredBlocks.empty() &&
"No predblocks?");
255 bool NewBBDominatesNewBBSucc =
true;
256 for (
typename InvTraits::ChildIteratorType PI =
257 InvTraits::child_begin(NewBBSucc),
258 E = InvTraits::child_end(NewBBSucc); PI != E; ++PI) {
260 if (ND != NewBB && !DT.
dominates(NewBBSucc, ND) &&
262 NewBBDominatesNewBBSucc =
false;
269 NodeT *NewBBIDom = 0;
271 for (i = 0; i < PredBlocks.size(); ++i)
273 NewBBIDom = PredBlocks[i];
283 for (i = i + 1; i < PredBlocks.size(); ++i) {
293 if (NewBBDominatesNewBBSucc) {
315 NodeT *BB =
I->first;
317 if (OI == OtherDomTreeNodes.
end())
356 while (!WL.
empty()) {
368 if (A == 0 || B == 0)
381 "This is not implemented for post dominators");
410 (dominatedBySlowTreeWalk(A, B) == B->DominatedBy(A))) &&
411 "Tree walk disagrees with dfs numbers!");
415 return B->DominatedBy(A);
422 return B->DominatedBy(A);
425 return dominatedBySlowTreeWalk(A, B);
428 bool dominates(
const NodeT *A,
const NodeT *B);
431 assert(this->
Roots.size() == 1 &&
"Should always have entry node!");
432 return this->
Roots[0];
438 assert(A->getParent() == B->getParent() &&
439 "Two blocks are not in same function");
445 if (A == &Entry || B == &Entry)
472 if (NodeADoms.
count(IDomB) != 0)
485 const_cast<NodeT *>(B));
496 assert(
getNode(BB) == 0 &&
"Block already in dominator tree!");
498 assert(IDomNode &&
"Not immediate dominator specified for block!");
509 assert(N && NewIDom &&
"Cannot change null node pointers!");
523 assert(Node &&
"Removing node that isn't in dominator tree.");
524 assert(Node->
getChildren().empty() &&
"Node is not a leaf node.");
529 typename std::vector<DomTreeNodeBase<NodeT>*>::iterator
I =
530 std::find(IDom->Children.begin(), IDom->Children.end(), Node);
531 assert(I != IDom->Children.end() &&
532 "Not in immediate dominator children set!");
534 IDom->Children.erase(I);
545 assert(
getNode(BB) &&
"Removing node that isn't in dominator tree.");
555 this->Split<NodeT*, GraphTraits<NodeT*> >(*
this, NewBB);
561 o <<
"=============================--------------------------------\n";
563 o <<
"Inorder PostDominator Tree: ";
565 o <<
"Inorder Dominator Tree: ";
567 o <<
"DFSNumbers invalid: " <<
SlowQueries <<
" slow queries.";
576 template<
class GraphT>
580 unsigned LastLinked);
582 template<
class GraphT>
587 template<
class FuncT,
class N>
609 ThisRoot->DFSNumIn = DFSNum++;
611 while (!WorkStack.
empty()) {
613 typename DomTreeNodeBase<NodeT>::iterator ChildIt =
614 WorkStack.
back().second;
618 if (ChildIt == Node->
end()) {
619 Node->DFSNumOut = DFSNum++;
624 ++WorkStack.
back().second;
627 Child->DFSNumIn = DFSNum++;
657 this->
Roots.push_back(BB);
666 this->
Vertex.push_back(0);
670 NodeT *entry = TraitsTy::getEntryNode(&F);
671 this->
Roots.push_back(entry);
672 this->
IDoms[entry] = 0;
675 Calculate<FT, NodeT*>(*
this,
F);
678 for (
typename TraitsTy::nodes_iterator
I = TraitsTy::nodes_begin(&F),
679 E = TraitsTy::nodes_end(&F);
I != E; ++
I) {
680 if (TraitsTy::child_begin(
I) == TraitsTy::child_end(
I))
688 Calculate<FT, Inverse<NodeT*> >(*
this,
F);
695 template<
class NodeT>
703 return dominates(getNode(const_cast<NodeT *>(A)),
704 getNode(const_cast<NodeT *>(B)));
706 template<
class NodeT>
715 return dominates(getNode(const_cast<NodeT *>(A)),
716 getNode(const_cast<NodeT *>(B)));
726 Start(Start_), End(End_) { }
760 inline const std::vector<BasicBlock*> &
getRoots()
const {
761 return DT->getRoots();
765 return DT->getRoot();
769 return DT->getRootNode();
775 DT->getDescendants(R, Result);
802 return DT->dominates(A, B);
806 return DT->dominates(A, B);
819 return DT->properlyDominates(A, B);
823 return DT->properlyDominates(A, B);
829 return DT->findNearestCommonDominator(A, B);
834 return DT->findNearestCommonDominator(A, B);
838 return DT->getNode(BB);
845 return DT->getNode(BB);
852 return DT->addNewBlock(BB, DomBB);
859 DT->changeImmediateDominator(N, NewIDom);
863 DT->changeImmediateDominator(N, NewIDom);
876 DT->splitBlock(NewBB);
880 return DT->isReachableFromEntry(A);
918 return df_end(getEntryNode(N));
933 return df_end(getEntryNode(N));
void push_back(const T &Elt)
DenseMap< NodeT *, InfoRec > Info
DomTreeNode * getNode(BasicBlock *BB) const
const MachineFunction * getParent() const
virtual ~DominatorTreeBase()
static PassRegistry * getPassRegistry()
DominatorTreeBase< BasicBlock > * DT
std::vector< NodeT * > Roots
const BasicBlock * findNearestCommonDominator(const BasicBlock *A, const BasicBlock *B)
const_iterator end() const
The main container class for the LLVM Intermediate Representation.
bool isReachableFromEntry(const BasicBlock *A) const
const BasicBlock * getStart() const
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase< BasicBlock >)
void splitBlock(BasicBlock *NewBB)
const_iterator begin() const
bool properlyDominates(const DomTreeNode *A, const DomTreeNode *B) const
DomTreeNodeMapType DomTreeNodes
DomTreeNodeBase< NodeT > * getRootNode()
bool isPostDominator() const
void initializeDominatorTreePass(PassRegistry &)
NodeType::iterator ChildIteratorType
friend GraphT::NodeType * Eval(DominatorTreeBase< typename GraphT::NodeType > &DT, typename GraphT::NodeType *V, unsigned LastLinked)
virtual void releaseMemory()
std::vector< NodeT * > Vertex
static nodes_iterator nodes_begin(DominatorTree *N)
DomTreeNodeBase< NodeT > * getIDom() const
void WriteAsOperand(raw_ostream &, const Value *, bool PrintTy=true, const Module *Context=0)
virtual void getAnalysisUsage(AnalysisUsage &AU) const
void Split(DominatorTreeBase< typename GraphT::NodeType > &DT, typename GraphT::NodeType *NewBB)
void changeImmediateDominator(NodeT *BB, NodeT *NewBB)
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
bool isReachableFromEntry(const DomTreeNodeBase< NodeT > *A) const
void changeImmediateDominator(BasicBlock *N, BasicBlock *NewIDom)
DominatorTreeBase< BasicBlock > & getBase()
static ChildIteratorType child_begin(NodeType *N)
const bool IsPostDominators
const MachineBasicBlock & front() const
DominatorBase(bool isPostDom)
bool count(PtrType Ptr) const
count - Return true if the specified pointer is in the set.
void eraseNode(BasicBlock *BB)
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
static nodes_iterator nodes_end(DominatorTree *N)
void print(raw_ostream &o) const
friend void Calculate(DominatorTreeBase< typename GraphTraits< N >::NodeType > &DT, FuncT &F)
DominatorTreeBase(bool isPostDom)
DenseMap< NodeT *, DomTreeNodeBase< NodeT > * > DomTreeNodeMapType
bool compare(const DomTreeNodeBase< NodeT > *Other) const
LLVM Basic Block Representation.
DenseMap< NodeT *, NodeT * > IDoms
static NodeType * getEntryNode(DominatorTree *DT)
df_iterator< T > df_end(const T &G)
void changeImmediateDominator(DomTreeNode *N, DomTreeNode *NewIDom)
unsigned getDFSNumIn() const
static ChildIteratorType child_end(NodeType *N)
void changeImmediateDominator(DomTreeNodeBase< NodeT > *N, DomTreeNodeBase< NodeT > *NewIDom)
static NodeType * getEntryNode(NodeType *N)
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B)
bool dominates(const DomTreeNode *A, const DomTreeNode *B) const
void append(in_iter in_start, in_iter in_end)
void recalculate(FT &F)
recalculate - compute a dominator tree for the given function
void Calculate(DominatorTreeBase< typename GraphTraits< NodeT >::NodeType > &DT, FuncT &F)
static nodes_iterator nodes_end(DomTreeNode *N)
const BasicBlock * getEnd() const
virtual bool runOnFunction(Function &F)
DomTreeNodeBase< NodeT > * addNewBlock(NodeT *BB, NodeT *DomBB)
const std::vector< DomTreeNodeBase< NodeT > * > & getChildren() const
void PrintDomTree(const DomTreeNodeBase< NodeT > *N, raw_ostream &o, unsigned Lev)
void setIDom(DomTreeNodeBase< NodeT > *NewIDom)
GraphType::UnknownGraphTypeError NodeType
DomTreeNodeBase< NodeT > * getNodeForBlock(NodeT *BB)
df_iterator< DomTreeNode * > nodes_iterator
virtual void print(raw_ostream &OS, const Module *M=0) const
bool erase(const KeyT &Val)
BasicBlock * getRoot() const
std::vector< DomTreeNodeBase< llvm::MachineBasicBlock > * >::const_iterator const_iterator
NodeT * getIDom(NodeT *BB) const
DomTreeNode * getRootNode() const
DomTreeNodeBase< BasicBlock > DomTreeNode
DomTreeNodeBase< NodeT > * getNode(NodeT *BB) const
df_iterator< T > df_begin(const T &G)
virtual void releaseMemory()
DomTreeNodeBase< NodeT > * RootNode
DomTreeNodeBase< NodeT > * addChild(DomTreeNodeBase< NodeT > *C)
bool compare(DominatorTree &Other) const
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B)
unsigned getDFSNumOut() const
bool compare(DominatorTreeBase &Other) const
bool properlyDominates(const BasicBlock *A, const BasicBlock *B) const
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B)
void eraseNode(NodeT *BB)
BasicBlock * findNearestCommonDominator(BasicBlock *A, BasicBlock *B)
DomTreeNode * addNewBlock(BasicBlock *BB, BasicBlock *DomBB)
void getDescendants(BasicBlock *R, SmallVectorImpl< BasicBlock * > &Result) const
Get all nodes dominated by R, including R itself. Return true on success.
DomTreeNodeBase(NodeT *BB, DomTreeNodeBase< NodeT > *iDom)
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
virtual void verifyAnalysis() const
bool isSingleEdge() const
BasicBlockEdge(const BasicBlock *Start_, const BasicBlock *End_)
std::vector< DomTreeNodeBase< llvm::MachineBasicBlock > * >::iterator iterator
const NodeT * findNearestCommonDominator(const NodeT *A, const NodeT *B)
ValueT lookup(const KeyT &Val) const
bool isReachableFromEntry(const NodeT *A) const
bool dominates(const BasicBlock *A, const BasicBlock *B) const
static nodes_iterator nodes_begin(DomTreeNode *N)
void removeNode(NodeT *BB)
const std::vector< NodeT * > & getRoots() const
const std::vector< BasicBlock * > & getRoots() const
void getDescendants(NodeT *R, SmallVectorImpl< NodeT * > &Result) const
Get all nodes dominated by R, including R itself. Return true on success.
iterator find(const KeyT &Val)
friend unsigned DFSPass(DominatorTreeBase< typename GraphT::NodeType > &DT, typename GraphT::NodeType *V, unsigned N)
const DomTreeNodeBase< NodeT > * getRootNode() const
DomTreeNode * operator[](BasicBlock *BB) const
size_t getNumChildren() const
void splitBlock(NodeT *NewBB)