diff --git a/include/llvm/Analysis/DominatorInternals.h b/include/llvm/Analysis/DominatorInternals.h index 5d5714a5c78..3486b77d77b 100644 --- a/include/llvm/Analysis/DominatorInternals.h +++ b/include/llvm/Analysis/DominatorInternals.h @@ -35,8 +35,8 @@ namespace llvm { template -unsigned DFSPass(DominatorTreeBase& DT, typename GraphT::NodeType* V, - unsigned N) { +unsigned DFSPass(DominatorTreeBase& DT, + typename GraphT::NodeType* V, unsigned N) { // This is more understandable as a recursive algorithm, but we can't use the // recursive algorithm due to stack depth issues. Keep it here for // documentation purposes. @@ -67,7 +67,8 @@ unsigned DFSPass(DominatorTreeBase& DT, typename GraphT::NodeType* V, // First time we visited this BB? if (NextSucc == GraphT::child_begin(BB)) { - DominatorTree::InfoRec &BBInfo = DT.Info[BB]; + typename DominatorTreeBase::InfoRec &BBInfo = + DT.Info[BB]; BBInfo.Semi = ++N; BBInfo.Label = BB; @@ -89,7 +90,8 @@ unsigned DFSPass(DominatorTreeBase& DT, typename GraphT::NodeType* V, // Visit the successor next, if it isn't already visited. typename GraphT::NodeType* Succ = *NextSucc; - DominatorTree::InfoRec &SuccVInfo = DT.Info[Succ]; + typename DominatorTreeBase::InfoRec &SuccVInfo = + DT.Info[Succ]; if (SuccVInfo.Semi == 0) { SuccVInfo.Parent = BB; Worklist.push_back(std::make_pair(Succ, GraphT::child_begin(Succ))); @@ -100,20 +102,24 @@ unsigned DFSPass(DominatorTreeBase& DT, typename GraphT::NodeType* V, } template -void Compress(DominatorTreeBase& DT, typename GraphT::NodeType *VIn) { +void Compress(DominatorTreeBase& DT, + typename GraphT::NodeType *VIn) { std::vector Work; SmallPtrSet Visited; typename GraphT::NodeType* VInAncestor = DT.Info[VIn].Ancestor; - DominatorTreeBase::InfoRec &VInVAInfo = DT.Info[VInAncestor]; + typename DominatorTreeBase::InfoRec &VInVAInfo = + DT.Info[VInAncestor]; if (VInVAInfo.Ancestor != 0) Work.push_back(VIn); while (!Work.empty()) { typename GraphT::NodeType* V = Work.back(); - DominatorTree::InfoRec &VInfo = DT.Info[V]; + typename DominatorTreeBase::InfoRec &VInfo = + DT.Info[V]; typename GraphT::NodeType* VAncestor = VInfo.Ancestor; - DominatorTreeBase::InfoRec &VAInfo = DT.Info[VAncestor]; + typename DominatorTreeBase::InfoRec &VAInfo = + DT.Info[VAncestor]; // Process Ancestor first if (Visited.insert(VAncestor) && @@ -135,9 +141,10 @@ void Compress(DominatorTreeBase& DT, typename GraphT::NodeType *VIn) { } template -typename GraphT::NodeType* Eval(DominatorTreeBase& DT, +typename GraphT::NodeType* Eval(DominatorTreeBase& DT, typename GraphT::NodeType *V) { - DominatorTreeBase::InfoRec &VInfo = DT.Info[V]; + typename DominatorTreeBase::InfoRec &VInfo = + DT.Info[V]; #if !BALANCE_IDOM_TREE // Higher-complexity but faster implementation if (VInfo.Ancestor == 0) @@ -160,8 +167,9 @@ typename GraphT::NodeType* Eval(DominatorTreeBase& DT, } template -void Link(DominatorTreeBase& DT, typename GraphT::NodeType* V, - typename GraphT::NodeType* W, DominatorTreeBase::InfoRec &WInfo) { +void Link(DominatorTreeBase& DT, + typename GraphT::NodeType* V, typename GraphT::NodeType* W, + typename DominatorTreeBase::InfoRec &WInfo) { #if !BALANCE_IDOM_TREE // Higher-complexity but faster implementation WInfo.Ancestor = V; @@ -208,49 +216,49 @@ void Link(DominatorTreeBase& DT, typename GraphT::NodeType* V, #endif } -template -void Calculate(DominatorTreeBase& DT, Function& F) { +template +void Calculate(DominatorTreeBase& DT, Function& F) { // Step #1: Number blocks in depth-first order and initialize variables used // in later stages of the algorithm. unsigned N = 0; for (unsigned i = 0, e = DT.Roots.size(); i != e; ++i) - N = DFSPass >(DT, DT.Roots[i], N); + N = DFSPass(DT, DT.Roots[i], N); for (unsigned i = N; i >= 2; --i) { - typename GraphTraits::NodeType* W = DT.Vertex[i]; - DominatorTree::InfoRec &WInfo = DT.Info[W]; + typename GraphT::NodeType* W = DT.Vertex[i]; + typename DominatorTreeBase::InfoRec &WInfo = + DT.Info[W]; // Step #2: Calculate the semidominators of all vertices for (typename GraphTraits >::ChildIteratorType CI = GraphTraits >::child_begin(W), E = GraphTraits >::child_end(W); CI != E; ++CI) if (DT.Info.count(*CI)) { // Only if this predecessor is reachable! - unsigned SemiU = DT.Info[Eval >(DT, *CI)].Semi; + unsigned SemiU = DT.Info[Eval(DT, *CI)].Semi; if (SemiU < WInfo.Semi) WInfo.Semi = SemiU; } DT.Info[DT.Vertex[WInfo.Semi]].Bucket.push_back(W); - typename GraphTraits::NodeType* WParent = WInfo.Parent; - Link >(DT, WParent, W, WInfo); + typename GraphT::NodeType* WParent = WInfo.Parent; + Link(DT, WParent, W, WInfo); // Step #3: Implicitly define the immediate dominator of vertices - std::vector::NodeType*> &WParentBucket = + std::vector &WParentBucket = DT.Info[WParent].Bucket; while (!WParentBucket.empty()) { - typename GraphTraits::NodeType* V = WParentBucket.back(); + typename GraphT::NodeType* V = WParentBucket.back(); WParentBucket.pop_back(); - typename GraphTraits::NodeType* U = - Eval >(DT, V); + typename GraphT::NodeType* U = Eval(DT, V); DT.IDoms[V] = DT.Info[U].Semi < DT.Info[V].Semi ? U : WParent; } } // Step #4: Explicitly define the immediate dominator of each vertex for (unsigned i = 2; i <= N; ++i) { - typename GraphTraits::NodeType* W = DT.Vertex[i]; - typename GraphTraits::NodeType*& WIDom = DT.IDoms[W]; + typename GraphT::NodeType* W = DT.Vertex[i]; + typename GraphT::NodeType*& WIDom = DT.IDoms[W]; if (WIDom != DT.Vertex[DT.Info[W].Semi]) WIDom = DT.IDoms[WIDom]; } @@ -260,13 +268,13 @@ void Calculate(DominatorTreeBase& DT, Function& F) { // Add a node for the root. This node might be the actual root, if there is // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0) // which postdominates all real exits if there are multiple exit blocks. - typename GraphTraits::NodeType* Root = DT.Roots.size() == 1 ? DT.Roots[0] - : 0; + typename GraphT::NodeType* Root = DT.Roots.size() == 1 ? DT.Roots[0] + : 0; DT.DomTreeNodes[Root] = DT.RootNode = new DomTreeNode(Root, 0); // Loop over all of the reachable blocks in the function... for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) - if (typename GraphTraits::NodeType* ImmDom = DT.getIDom(I)) { + if (typename GraphT::NodeType* ImmDom = DT.getIDom(I)) { // Reachable block. DomTreeNode *BBNode = DT.DomTreeNodes[I]; if (BBNode) continue; // Haven't calculated this node yet? @@ -283,7 +291,7 @@ void Calculate(DominatorTreeBase& DT, Function& F) { // Free temporary memory used to construct idom's DT.IDoms.clear(); DT.Info.clear(); - std::vector::NodeType*>().swap(DT.Vertex); + std::vector().swap(DT.Vertex); // FIXME: This does not work on PostDomTrees. It seems likely that this is // due to an error in the algorithm for post-dominators. This really should diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h index 6dcf2a42410..855180d6953 100644 --- a/include/llvm/Analysis/Dominators.h +++ b/include/llvm/Analysis/Dominators.h @@ -22,23 +22,28 @@ #define LLVM_ANALYSIS_DOMINATORS_H #include "llvm/Pass.h" +#include "llvm/Instruction.h" +#include "llvm/Instructions.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Assembly/Writer.h" +#include "llvm/Support/Compiler.h" #include #include -#include "llvm/ADT/DenseMap.h" namespace llvm { -class Instruction; - template struct GraphTraits; //===----------------------------------------------------------------------===// /// DominatorBase - Base class that other, more interesting dominator analyses /// inherit from. /// +template class DominatorBase : public FunctionPass { protected: - std::vector Roots; + std::vector Roots; const bool IsPostDominators; inline DominatorBase(intptr_t ID, bool isPostDom) : FunctionPass(ID), Roots(), IsPostDominators(isPostDom) {} @@ -48,7 +53,7 @@ public: /// multiple blocks if we are computing post dominators. For forward /// dominators, this will always be a single block (the entry node). /// - inline const std::vector &getRoots() const { return Roots; } + inline const std::vector &getRoots() const { return Roots; } /// isPostDominator - Returns true if analysis based of postdoms /// @@ -58,7 +63,7 @@ public: //===----------------------------------------------------------------------===// // DomTreeNode - Dominator Tree Node -class DominatorTreeBase; +template class DominatorTreeBase; class PostDominatorTree; class MachineBasicBlock; @@ -69,7 +74,7 @@ class DomTreeNodeBase { std::vector *> Children; int DFSNumIn, DFSNumOut; - friend class DominatorTreeBase; + template friend class DominatorTreeBase; friend class PostDominatorTree; public: typedef typename std::vector *>::iterator iterator; @@ -124,18 +129,43 @@ private: } }; +EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase); + +template +static std::ostream &operator<<(std::ostream &o, + const DomTreeNodeBase *Node) { + if (Node->getBlock()) + WriteAsOperand(o, Node->getBlock(), false); + else + o << " <>"; + + o << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}"; + + return o << "\n"; +} + +template +static void PrintDomTree(const DomTreeNodeBase *N, std::ostream &o, + unsigned Lev) { + o << std::string(2*Lev, ' ') << "[" << Lev << "] " << N; + for (typename DomTreeNodeBase::const_iterator I = N->begin(), + E = N->end(); I != E; ++I) + PrintDomTree(*I, o, Lev+1); +} + typedef DomTreeNodeBase DomTreeNode; typedef DomTreeNodeBase MachineDomTreeNode; //===----------------------------------------------------------------------===// /// DominatorTree - Calculate the immediate dominator tree for a function. /// -class DominatorTreeBase : public DominatorBase { + +template +class DominatorTreeBase : public DominatorBase { protected: - void reset(); - typedef DenseMap DomTreeNodeMapType; + typedef DenseMap*> DomTreeNodeMapType; DomTreeNodeMapType DomTreeNodes; - DomTreeNode *RootNode; + DomTreeNodeBase *RootNode; bool DFSInfoValid; unsigned int SlowQueries; @@ -143,24 +173,35 @@ protected: struct InfoRec { unsigned Semi; unsigned Size; - BasicBlock *Label, *Parent, *Child, *Ancestor; + NodeT *Label, *Parent, *Child, *Ancestor; - std::vector Bucket; + std::vector Bucket; InfoRec() : Semi(0), Size(0), Label(0), Parent(0), Child(0), Ancestor(0) {} }; - DenseMap IDoms; + DenseMap IDoms; // Vertex - Map the DFS number to the BasicBlock* - std::vector Vertex; + std::vector Vertex; // Info - Collection of information used during the computation of idoms. - DenseMap Info; + DenseMap Info; + + void reset() { + for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(), + E = DomTreeNodes.end(); I != E; ++I) + delete I->second; + DomTreeNodes.clear(); + IDoms.clear(); + this->Roots.clear(); + Vertex.clear(); + RootNode = 0; + } public: DominatorTreeBase(intptr_t ID, bool isPostDom) - : DominatorBase(ID, isPostDom), DFSInfoValid(false), SlowQueries(0) {} + : DominatorBase(ID, isPostDom), DFSInfoValid(false), SlowQueries(0) {} ~DominatorTreeBase() { reset(); } virtual void releaseMemory() { reset(); } @@ -168,12 +209,12 @@ public: /// getNode - return the (Post)DominatorTree node for the specified basic /// block. This is the same as using operator[] on this class. /// - inline DomTreeNode *getNode(BasicBlock *BB) const { - DomTreeNodeMapType::const_iterator I = DomTreeNodes.find(BB); + inline DomTreeNodeBase *getNode(NodeT *BB) const { + typename DomTreeNodeMapType::const_iterator I = DomTreeNodes.find(BB); return I != DomTreeNodes.end() ? I->second : 0; } - inline DomTreeNode *operator[](BasicBlock *BB) const { + inline DomTreeNodeBase *operator[](NodeT *BB) const { return getNode(BB); } @@ -184,25 +225,25 @@ public: /// post-dominance information must be capable of dealing with this /// possibility. /// - DomTreeNode *getRootNode() { return RootNode; } - const DomTreeNode *getRootNode() const { return RootNode; } + DomTreeNodeBase *getRootNode() { return RootNode; } + const DomTreeNodeBase *getRootNode() const { return RootNode; } /// properlyDominates - Returns true iff this dominates N and this != N. /// Note that this is not a constant time operation! /// - bool properlyDominates(const DomTreeNode *A, - DomTreeNode *B) const { + bool properlyDominates(const DomTreeNodeBase *A, + DomTreeNodeBase *B) const { if (A == 0 || B == 0) return false; return dominatedBySlowTreeWalk(A, B); } - inline bool properlyDominates(BasicBlock *A, BasicBlock *B) { + inline bool properlyDominates(NodeT *A, NodeT *B) { return properlyDominates(getNode(A), getNode(B)); } - bool dominatedBySlowTreeWalk(const DomTreeNode *A, - const DomTreeNode *B) const { - const DomTreeNode *IDom; + bool dominatedBySlowTreeWalk(const DomTreeNodeBase *A, + const DomTreeNodeBase *B) const { + const DomTreeNodeBase *IDom; if (A == 0 || B == 0) return false; while ((IDom = B->getIDom()) != 0 && IDom != A && IDom != B) B = IDom; // Walk up the tree @@ -212,13 +253,17 @@ public: /// isReachableFromEntry - Return true if A is dominated by the entry /// block of the function containing it. - const bool isReachableFromEntry(BasicBlock* A); + const bool isReachableFromEntry(NodeT* A) { + assert (!this->isPostDominator() + && "This is not implemented for post dominators"); + return dominates(&A->getParent()->getEntryBlock(), A); + } /// dominates - Returns true iff A dominates B. Note that this is not a /// constant time operation! /// - inline bool dominates(const DomTreeNode *A, - DomTreeNode *B) { + inline bool dominates(const DomTreeNodeBase *A, + DomTreeNodeBase *B) { if (B == A) return true; // A node trivially dominates itself. @@ -239,7 +284,7 @@ public: return dominatedBySlowTreeWalk(A, B); } - inline bool dominates(BasicBlock *A, BasicBlock *B) { + inline bool dominates(NodeT *A, NodeT *B) { if (A == B) return true; @@ -248,11 +293,73 @@ public: /// findNearestCommonDominator - Find nearest common dominator basic block /// for basic block A and B. If there is no such block then return NULL. - BasicBlock *findNearestCommonDominator(BasicBlock *A, BasicBlock *B); + NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) { + + assert (!this->isPostDominator() + && "This is not implemented for post dominators"); + assert (A->getParent() == B->getParent() + && "Two blocks are not in same function"); + + // If either A or B is a entry block then it is nearest common dominator. + NodeT &Entry = A->getParent()->getEntryBlock(); + if (A == &Entry || B == &Entry) + return &Entry; + + // If B dominates A then B is nearest common dominator. + if (dominates(B, A)) + return B; + + // If A dominates B then A is nearest common dominator. + if (dominates(A, B)) + return A; + + DomTreeNodeBase *NodeA = getNode(A); + DomTreeNodeBase *NodeB = getNode(B); + + // Collect NodeA dominators set. + SmallPtrSet*, 16> NodeADoms; + NodeADoms.insert(NodeA); + DomTreeNodeBase *IDomA = NodeA->getIDom(); + while (IDomA) { + NodeADoms.insert(IDomA); + IDomA = IDomA->getIDom(); + } + + // Walk NodeB immediate dominators chain and find common dominator node. + DomTreeNodeBase *IDomB = NodeB->getIDom(); + while(IDomB) { + if (NodeADoms.count(IDomB) != 0) + return IDomB->getBlock(); + + IDomB = IDomB->getIDom(); + } + + return NULL; + } // dominates - Return true if A dominates B. This performs the // special checks necessary if A and B are in the same basic block. - bool dominates(Instruction *A, Instruction *B); + bool dominates(Instruction *A, Instruction *B) { + NodeT *BBA = A->getParent(), *BBB = B->getParent(); + if (BBA != BBB) return this->dominates(BBA, BBB); + + // It is not possible to determine dominance between two PHI nodes + // based on their ordering. + if (isa(A) && isa(B)) + return false; + + // Loop through the basic block until we find A or B. + typename NodeT::iterator I = BBA->begin(); + for (; &*I != A && &*I != B; ++I) /*empty*/; + + if(!this->IsPostDominators) { + // A dominates B if it is found first in the basic block. + return &*I == A; + } else { + // A post-dominates B if B is found first in the basic block. + return &*I == B; + } + } //===--------------------------------------------------------------------===// // API to update (Post)DominatorTree information based on modifications to @@ -261,9 +368,9 @@ public: /// addNewBlock - Add a new node to the dominator tree information. This /// creates a new node as a child of DomBB dominator node,linking it into /// the children list of the immediate dominator. - DomTreeNode *addNewBlock(BasicBlock *BB, BasicBlock *DomBB) { + DomTreeNodeBase *addNewBlock(NodeT *BB, NodeT *DomBB) { assert(getNode(BB) == 0 && "Block already in dominator tree!"); - DomTreeNode *IDomNode = getNode(DomBB); + DomTreeNodeBase *IDomNode = getNode(DomBB); assert(IDomNode && "Not immediate dominator specified for block!"); DFSInfoValid = false; return DomTreeNodes[BB] = @@ -273,76 +380,156 @@ public: /// changeImmediateDominator - This method is used to update the dominator /// tree information when a node's immediate dominator changes. /// - void changeImmediateDominator(DomTreeNode *N, - DomTreeNode *NewIDom) { + void changeImmediateDominator(DomTreeNodeBase *N, + DomTreeNodeBase *NewIDom) { assert(N && NewIDom && "Cannot change null node pointers!"); DFSInfoValid = false; N->setIDom(NewIDom); } - void changeImmediateDominator(BasicBlock *BB, BasicBlock *NewBB) { + void changeImmediateDominator(NodeT *BB, NodeT *NewBB) { changeImmediateDominator(getNode(BB), getNode(NewBB)); } /// eraseNode - Removes a node from the dominator tree. Block must not /// domiante any other blocks. Removes node from its immediate dominator's /// children list. Deletes dominator node associated with basic block BB. - void eraseNode(BasicBlock *BB); + void eraseNode(NodeT *BB) { + DomTreeNodeBase *Node = getNode(BB); + assert (Node && "Removing node that isn't in dominator tree."); + assert (Node->getChildren().empty() && "Node is not a leaf node."); + + // Remove node from immediate dominator's children list. + DomTreeNodeBase *IDom = Node->getIDom(); + if (IDom) { + typename std::vector*>::iterator I = + std::find(IDom->Children.begin(), IDom->Children.end(), Node); + assert(I != IDom->Children.end() && + "Not in immediate dominator children set!"); + // I am no longer your child... + IDom->Children.erase(I); + } + + DomTreeNodes.erase(BB); + delete Node; + } /// removeNode - Removes a node from the dominator tree. Block must not /// dominate any other blocks. Invalidates any node pointing to removed /// block. - void removeNode(BasicBlock *BB) { + void removeNode(NodeT *BB) { assert(getNode(BB) && "Removing node that isn't in dominator tree."); DomTreeNodes.erase(BB); } /// print - Convert to human readable form /// - virtual void print(std::ostream &OS, const Module* = 0) const; + virtual void print(std::ostream &o, const Module* ) const { + o << "=============================--------------------------------\n"; + o << "Inorder Dominator Tree: "; + if (this->DFSInfoValid) + o << "DFSNumbers invalid: " << SlowQueries << " slow queries."; + o << "\n"; + + PrintDomTree(getRootNode(), o, 1); + } + void print(std::ostream *OS, const Module* M = 0) const { if (OS) print(*OS, M); } - virtual void dump(); + + virtual void dump() { + print(llvm::cerr); + } protected: - template friend void Compress(DominatorTreeBase& DT, + template friend void Compress(DominatorTreeBase& DT, typename GraphT::NodeType* VIn); template friend typename GraphT::NodeType* Eval( - DominatorTreeBase& DT, + DominatorTreeBase& DT, typename GraphT::NodeType* V); - template friend void Link(DominatorTreeBase& DT, + template friend void Link(DominatorTreeBase& DT, typename GraphT::NodeType* V, typename GraphT::NodeType* W, - InfoRec &WInfo); + typename DominatorTreeBase::InfoRec &WInfo); - template friend unsigned DFSPass(DominatorTreeBase& DT, + template friend unsigned DFSPass( + DominatorTreeBase& DT, typename GraphT::NodeType* V, unsigned N); - template friend void Calculate(DominatorTreeBase& DT, - Function& F); + template friend void Calculate(DominatorTreeBase& DT, + Function& F); /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking /// dominator tree in dfs order. - void updateDFSNumbers(); + void updateDFSNumbers() { + unsigned DFSNum = 0; + + SmallVector*, + typename DomTreeNodeBase::iterator>, 32> WorkStack; + + for (unsigned i = 0, e = this->Roots.size(); i != e; ++i) { + DomTreeNodeBase *ThisRoot = getNode(this->Roots[i]); + WorkStack.push_back(std::make_pair(ThisRoot, ThisRoot->begin())); + ThisRoot->DFSNumIn = DFSNum++; + + while (!WorkStack.empty()) { + DomTreeNodeBase *Node = WorkStack.back().first; + typename DomTreeNodeBase::iterator ChildIt = + WorkStack.back().second; + + // If we visited all of the children of this node, "recurse" back up the + // stack setting the DFOutNum. + if (ChildIt == Node->end()) { + Node->DFSNumOut = DFSNum++; + WorkStack.pop_back(); + } else { + // Otherwise, recursively visit this child. + DomTreeNodeBase *Child = *ChildIt; + ++WorkStack.back().second; + + WorkStack.push_back(std::make_pair(Child, Child->begin())); + Child->DFSNumIn = DFSNum++; + } + } + } + + SlowQueries = 0; + DFSInfoValid = true; + } - DomTreeNode *getNodeForBlock(BasicBlock *BB); + DomTreeNodeBase *getNodeForBlock(NodeT *BB) { + if (DomTreeNodeBase *BBNode = this->DomTreeNodes[BB]) + return BBNode; + + // Haven't calculated this node yet? Get or calculate the node for the + // immediate dominator. + NodeT *IDom = getIDom(BB); + DomTreeNodeBase *IDomNode = getNodeForBlock(IDom); + + // Add a new tree node for this BasicBlock, and link it as a child of + // IDomNode + DomTreeNodeBase *C = new DomTreeNodeBase(BB, IDomNode); + return this->DomTreeNodes[BB] = IDomNode->addChild(C); + } - inline BasicBlock *getIDom(BasicBlock *BB) const { - DenseMap::const_iterator I = IDoms.find(BB); + inline NodeT *getIDom(NodeT *BB) const { + typename DenseMap::const_iterator I = IDoms.find(BB); return I != IDoms.end() ? I->second : 0; } }; +EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase); + //===------------------------------------- /// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to /// compute a normal dominator tree. /// -class DominatorTree : public DominatorTreeBase { +class DominatorTree : public DominatorTreeBase { public: static char ID; // Pass ID, replacement for typeid - DominatorTree() : DominatorTreeBase(intptr_t(&ID), false) {} + DominatorTree() : DominatorTreeBase(intptr_t(&ID), false) {} BasicBlock *getRoot() const { assert(Roots.size() == 1 && "Should always have entry node!"); @@ -392,7 +579,7 @@ template <> struct GraphTraits /// DominanceFrontierBase - Common base class for computing forward and inverse /// dominance frontiers for a function. /// -class DominanceFrontierBase : public DominatorBase { +class DominanceFrontierBase : public DominatorBase { public: typedef std::set DomSetType; // Dom set for a bb typedef std::map DomSetMapType; // Dom set map @@ -400,7 +587,7 @@ protected: DomSetMapType Frontiers; public: DominanceFrontierBase(intptr_t ID, bool isPostDom) - : DominatorBase(ID, isPostDom) {} + : DominatorBase(ID, isPostDom) {} virtual void releaseMemory() { Frontiers.clear(); } diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h index 50fe984cc3c..71b06e2877e 100644 --- a/include/llvm/Analysis/PostDominators.h +++ b/include/llvm/Analysis/PostDominators.h @@ -21,11 +21,11 @@ namespace llvm { /// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to /// compute the a post-dominator tree. /// -struct PostDominatorTree : public DominatorTreeBase { +struct PostDominatorTree : public DominatorTreeBase { static char ID; // Pass identification, replacement for typeid PostDominatorTree() : - DominatorTreeBase((intptr_t)&ID, true) {} + DominatorTreeBase((intptr_t)&ID, true) {} virtual bool runOnFunction(Function &F); diff --git a/lib/Analysis/PostDominators.cpp b/lib/Analysis/PostDominators.cpp index f066f7ae525..0384fad732e 100644 --- a/lib/Analysis/PostDominators.cpp +++ b/lib/Analysis/PostDominators.cpp @@ -47,7 +47,7 @@ bool PostDominatorTree::runOnFunction(Function &F) { Vertex.push_back(0); - Calculate >(*this, F); + Calculate, GraphTraits > >(*this, F); return false; } diff --git a/lib/VMCore/Dominators.cpp b/lib/VMCore/Dominators.cpp index 84a60257d22..a9900fe1a73 100644 --- a/lib/VMCore/Dominators.cpp +++ b/lib/VMCore/Dominators.cpp @@ -16,7 +16,7 @@ #include "llvm/Analysis/Dominators.h" #include "llvm/Support/CFG.h" -#include "llvm/Assembly/Writer.h" +#include "llvm/Support/Compiler.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/SetOperations.h" #include "llvm/ADT/SmallPtrSet.h" @@ -49,6 +49,9 @@ static std::ostream &operator<<(std::ostream &o, // //===----------------------------------------------------------------------===// +TEMPLATE_INSTANTIATION(class DomTreeNodeBase); +TEMPLATE_INSTANTIATION(class DominatorTreeBase); + char DominatorTree::ID = 0; static RegisterPass E("domtree", "Dominator Tree Construction", true); @@ -135,203 +138,6 @@ void DominatorTree::splitBlock(BasicBlock *NewBB) { } } -void DominatorTreeBase::updateDFSNumbers() { - unsigned DFSNum = 0; - - SmallVector, 32> WorkStack; - - for (unsigned i = 0, e = Roots.size(); i != e; ++i) { - DomTreeNode *ThisRoot = getNode(Roots[i]); - WorkStack.push_back(std::make_pair(ThisRoot, ThisRoot->begin())); - ThisRoot->DFSNumIn = DFSNum++; - - while (!WorkStack.empty()) { - DomTreeNode *Node = WorkStack.back().first; - DomTreeNode::iterator ChildIt = WorkStack.back().second; - - // If we visited all of the children of this node, "recurse" back up the - // stack setting the DFOutNum. - if (ChildIt == Node->end()) { - Node->DFSNumOut = DFSNum++; - WorkStack.pop_back(); - } else { - // Otherwise, recursively visit this child. - DomTreeNode *Child = *ChildIt; - ++WorkStack.back().second; - - WorkStack.push_back(std::make_pair(Child, Child->begin())); - Child->DFSNumIn = DFSNum++; - } - } - } - - SlowQueries = 0; - DFSInfoValid = true; -} - -/// isReachableFromEntry - Return true if A is dominated by the entry -/// block of the function containing it. -const bool DominatorTreeBase::isReachableFromEntry(BasicBlock* A) { - assert (!isPostDominator() - && "This is not implemented for post dominators"); - return dominates(&A->getParent()->getEntryBlock(), A); -} - -// dominates - Return true if A dominates B. THis performs the -// special checks necessary if A and B are in the same basic block. -bool DominatorTreeBase::dominates(Instruction *A, Instruction *B) { - BasicBlock *BBA = A->getParent(), *BBB = B->getParent(); - if (BBA != BBB) return dominates(BBA, BBB); - - // It is not possible to determine dominance between two PHI nodes - // based on their ordering. - if (isa(A) && isa(B)) - return false; - - // Loop through the basic block until we find A or B. - BasicBlock::iterator I = BBA->begin(); - for (; &*I != A && &*I != B; ++I) /*empty*/; - - if(!IsPostDominators) { - // A dominates B if it is found first in the basic block. - return &*I == A; - } else { - // A post-dominates B if B is found first in the basic block. - return &*I == B; - } -} - -// DominatorTreeBase::reset - Free all of the tree node memory. -// -void DominatorTreeBase::reset() { - for (DomTreeNodeMapType::iterator I = DomTreeNodes.begin(), - E = DomTreeNodes.end(); I != E; ++I) - delete I->second; - DomTreeNodes.clear(); - IDoms.clear(); - Roots.clear(); - Vertex.clear(); - RootNode = 0; -} - -DomTreeNode *DominatorTreeBase::getNodeForBlock(BasicBlock *BB) { - if (DomTreeNode *BBNode = DomTreeNodes[BB]) - return BBNode; - - // Haven't calculated this node yet? Get or calculate the node for the - // immediate dominator. - BasicBlock *IDom = getIDom(BB); - DomTreeNode *IDomNode = getNodeForBlock(IDom); - - // Add a new tree node for this BasicBlock, and link it as a child of - // IDomNode - DomTreeNode *C = new DomTreeNode(BB, IDomNode); - return DomTreeNodes[BB] = IDomNode->addChild(C); -} - -/// findNearestCommonDominator - Find nearest common dominator basic block -/// for basic block A and B. If there is no such block then return NULL. -BasicBlock *DominatorTreeBase::findNearestCommonDominator(BasicBlock *A, - BasicBlock *B) { - - assert (!isPostDominator() - && "This is not implemented for post dominators"); - assert (A->getParent() == B->getParent() - && "Two blocks are not in same function"); - - // If either A or B is a entry block then it is nearest common dominator. - BasicBlock &Entry = A->getParent()->getEntryBlock(); - if (A == &Entry || B == &Entry) - return &Entry; - - // If B dominates A then B is nearest common dominator. - if (dominates(B, A)) - return B; - - // If A dominates B then A is nearest common dominator. - if (dominates(A, B)) - return A; - - DomTreeNode *NodeA = getNode(A); - DomTreeNode *NodeB = getNode(B); - - // Collect NodeA dominators set. - SmallPtrSet NodeADoms; - NodeADoms.insert(NodeA); - DomTreeNode *IDomA = NodeA->getIDom(); - while (IDomA) { - NodeADoms.insert(IDomA); - IDomA = IDomA->getIDom(); - } - - // Walk NodeB immediate dominators chain and find common dominator node. - DomTreeNode *IDomB = NodeB->getIDom(); - while(IDomB) { - if (NodeADoms.count(IDomB) != 0) - return IDomB->getBlock(); - - IDomB = IDomB->getIDom(); - } - - return NULL; -} - -static std::ostream &operator<<(std::ostream &o, const DomTreeNode *Node) { - if (Node->getBlock()) - WriteAsOperand(o, Node->getBlock(), false); - else - o << " <>"; - - o << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}"; - - return o << "\n"; -} - -static void PrintDomTree(const DomTreeNode *N, std::ostream &o, - unsigned Lev) { - o << std::string(2*Lev, ' ') << "[" << Lev << "] " << N; - for (DomTreeNode::const_iterator I = N->begin(), E = N->end(); - I != E; ++I) - PrintDomTree(*I, o, Lev+1); -} - -/// eraseNode - Removes a node from the domiantor tree. Block must not -/// domiante any other blocks. Removes node from its immediate dominator's -/// children list. Deletes dominator node associated with basic block BB. -void DominatorTreeBase::eraseNode(BasicBlock *BB) { - DomTreeNode *Node = getNode(BB); - assert (Node && "Removing node that isn't in dominator tree."); - assert (Node->getChildren().empty() && "Node is not a leaf node."); - - // Remove node from immediate dominator's children list. - DomTreeNode *IDom = Node->getIDom(); - if (IDom) { - std::vector::iterator I = - std::find(IDom->Children.begin(), IDom->Children.end(), Node); - assert(I != IDom->Children.end() && - "Not in immediate dominator children set!"); - // I am no longer your child... - IDom->Children.erase(I); - } - - DomTreeNodes.erase(BB); - delete Node; -} - -void DominatorTreeBase::print(std::ostream &o, const Module* ) const { - o << "=============================--------------------------------\n"; - o << "Inorder Dominator Tree: "; - if (DFSInfoValid) - o << "DFSNumbers invalid: " << SlowQueries << " slow queries."; - o << "\n"; - - PrintDomTree(getRootNode(), o, 1); -} - -void DominatorTreeBase::dump() { - print(llvm::cerr); -} - bool DominatorTree::runOnFunction(Function &F) { reset(); // Reset from the last time we were run... @@ -341,7 +147,7 @@ bool DominatorTree::runOnFunction(Function &F) { DomTreeNodes[&F.getEntryBlock()] = 0; Vertex.push_back(0); - Calculate(*this, F); + Calculate >(*this, F); updateDFSNumbers();