[llvm-commits] [llvm] r43036 - in /llvm/trunk: include/llvm/Analysis/DominatorInternals.h include/llvm/Analysis/Dominators.h include/llvm/Analysis/PostDominators.h lib/Analysis/PostDominators.cpp lib/VMCore/Dominators.cpp

Owen Anderson resistor at mac.com
Tue Oct 16 12:59:25 PDT 2007


Author: resistor
Date: Tue Oct 16 14:59:25 2007
New Revision: 43036

URL: http://llvm.org/viewvc/llvm-project?rev=43036&view=rev
Log:
Template DominatorTreeBase by node type.  This is the next major step towards
having dominator information on MBB's.

Modified:
    llvm/trunk/include/llvm/Analysis/DominatorInternals.h
    llvm/trunk/include/llvm/Analysis/Dominators.h
    llvm/trunk/include/llvm/Analysis/PostDominators.h
    llvm/trunk/lib/Analysis/PostDominators.cpp
    llvm/trunk/lib/VMCore/Dominators.cpp

Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DominatorInternals.h?rev=43036&r1=43035&r2=43036&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/DominatorInternals.h (original)
+++ llvm/trunk/include/llvm/Analysis/DominatorInternals.h Tue Oct 16 14:59:25 2007
@@ -35,8 +35,8 @@
 namespace llvm {
 
 template<class GraphT>
-unsigned DFSPass(DominatorTreeBase& DT, typename GraphT::NodeType* V,
-                 unsigned N) {
+unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& 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 @@
 
     // First time we visited this BB?
     if (NextSucc == GraphT::child_begin(BB)) {
-      DominatorTree::InfoRec &BBInfo = DT.Info[BB];
+      typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo =
+                                                                    DT.Info[BB];
       BBInfo.Semi = ++N;
       BBInfo.Label = BB;
 
@@ -89,7 +90,8 @@
     // Visit the successor next, if it isn't already visited.
     typename GraphT::NodeType* Succ = *NextSucc;
 
-    DominatorTree::InfoRec &SuccVInfo = DT.Info[Succ];
+    typename DominatorTreeBase<typename GraphT::NodeType>::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 @@
 }
 
 template<class GraphT>
-void Compress(DominatorTreeBase& DT, typename GraphT::NodeType *VIn) {
+void Compress(DominatorTreeBase<typename GraphT::NodeType>& DT,
+              typename GraphT::NodeType *VIn) {
   std::vector<typename GraphT::NodeType*> Work;
   SmallPtrSet<typename GraphT::NodeType*, 32> Visited;
   typename GraphT::NodeType* VInAncestor = DT.Info[VIn].Ancestor;
-  DominatorTreeBase::InfoRec &VInVAInfo = DT.Info[VInAncestor];
+  typename DominatorTreeBase<typename GraphT::NodeType>::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<typename GraphT::NodeType>::InfoRec &VInfo =
+                                                                     DT.Info[V];
     typename GraphT::NodeType* VAncestor = VInfo.Ancestor;
-    DominatorTreeBase::InfoRec &VAInfo = DT.Info[VAncestor];
+    typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VAInfo =
+                                                             DT.Info[VAncestor];
 
     // Process Ancestor first
     if (Visited.insert(VAncestor) &&
@@ -135,9 +141,10 @@
 }
 
 template<class GraphT>
-typename GraphT::NodeType* Eval(DominatorTreeBase& DT,
+typename GraphT::NodeType* Eval(DominatorTreeBase<typename GraphT::NodeType>& DT,
                                 typename GraphT::NodeType *V) {
-  DominatorTreeBase::InfoRec &VInfo = DT.Info[V];
+  typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInfo =
+                                                                     DT.Info[V];
 #if !BALANCE_IDOM_TREE
   // Higher-complexity but faster implementation
   if (VInfo.Ancestor == 0)
@@ -160,8 +167,9 @@
 }
 
 template<class GraphT>
-void Link(DominatorTreeBase& DT, typename GraphT::NodeType* V,
-          typename GraphT::NodeType* W, DominatorTreeBase::InfoRec &WInfo) {
+void Link(DominatorTreeBase<typename GraphT::NodeType>& DT,
+          typename GraphT::NodeType* V, typename GraphT::NodeType* W,
+        typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo) {
 #if !BALANCE_IDOM_TREE
   // Higher-complexity but faster implementation
   WInfo.Ancestor = V;
@@ -208,49 +216,49 @@
 #endif
 }
 
-template<class NodeT>
-void Calculate(DominatorTreeBase& DT, Function& F) {
+template<class NodeT, class GraphT>
+void Calculate(DominatorTreeBase<typename GraphT::NodeType>& 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<GraphTraits<NodeT> >(DT, DT.Roots[i], N);
+    N = DFSPass<GraphT>(DT, DT.Roots[i], N);
 
   for (unsigned i = N; i >= 2; --i) {
-    typename GraphTraits<NodeT>::NodeType* W = DT.Vertex[i];
-    DominatorTree::InfoRec &WInfo = DT.Info[W];
+    typename GraphT::NodeType* W = DT.Vertex[i];
+    typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo =
+                                                                     DT.Info[W];
 
     // Step #2: Calculate the semidominators of all vertices
     for (typename GraphTraits<Inverse<NodeT> >::ChildIteratorType CI =
          GraphTraits<Inverse<NodeT> >::child_begin(W),
          E = GraphTraits<Inverse<NodeT> >::child_end(W); CI != E; ++CI)
       if (DT.Info.count(*CI)) {  // Only if this predecessor is reachable!
-        unsigned SemiU = DT.Info[Eval<GraphTraits<NodeT> >(DT, *CI)].Semi;
+        unsigned SemiU = DT.Info[Eval<GraphT>(DT, *CI)].Semi;
         if (SemiU < WInfo.Semi)
           WInfo.Semi = SemiU;
       }
 
     DT.Info[DT.Vertex[WInfo.Semi]].Bucket.push_back(W);
 
-    typename GraphTraits<NodeT>::NodeType* WParent = WInfo.Parent;
-    Link<GraphTraits<NodeT> >(DT, WParent, W, WInfo);
+    typename GraphT::NodeType* WParent = WInfo.Parent;
+    Link<GraphT>(DT, WParent, W, WInfo);
 
     // Step #3: Implicitly define the immediate dominator of vertices
-    std::vector<typename GraphTraits<NodeT>::NodeType*> &WParentBucket =
+    std::vector<typename GraphT::NodeType*> &WParentBucket =
                                                         DT.Info[WParent].Bucket;
     while (!WParentBucket.empty()) {
-      typename GraphTraits<NodeT>::NodeType* V = WParentBucket.back();
+      typename GraphT::NodeType* V = WParentBucket.back();
       WParentBucket.pop_back();
-      typename GraphTraits<NodeT>::NodeType* U =
-                                               Eval<GraphTraits<NodeT> >(DT, V);
+      typename GraphT::NodeType* U = Eval<GraphT>(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<NodeT>::NodeType* W = DT.Vertex[i];
-    typename GraphTraits<NodeT>::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 @@
   // 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<NodeT>::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<NodeT>::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 @@
   // Free temporary memory used to construct idom's
   DT.IDoms.clear();
   DT.Info.clear();
-  std::vector<typename GraphTraits<NodeT>::NodeType*>().swap(DT.Vertex);
+  std::vector<typename GraphT::NodeType*>().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

Modified: llvm/trunk/include/llvm/Analysis/Dominators.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Dominators.h?rev=43036&r1=43035&r2=43036&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/Dominators.h (original)
+++ llvm/trunk/include/llvm/Analysis/Dominators.h Tue Oct 16 14:59:25 2007
@@ -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 <algorithm>
 #include <set>
-#include "llvm/ADT/DenseMap.h"
 
 namespace llvm {
 
-class Instruction;
-
 template <typename GraphType> struct GraphTraits;
 
 //===----------------------------------------------------------------------===//
 /// DominatorBase - Base class that other, more interesting dominator analyses
 /// inherit from.
 ///
+template <class NodeT>
 class DominatorBase : public FunctionPass {
 protected:
-  std::vector<BasicBlock*> Roots;
+  std::vector<NodeT*> Roots;
   const bool IsPostDominators;
   inline DominatorBase(intptr_t ID, bool isPostDom) : 
     FunctionPass(ID), Roots(), IsPostDominators(isPostDom) {}
@@ -48,7 +53,7 @@
   /// 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<BasicBlock*> &getRoots() const { return Roots; }
+  inline const std::vector<NodeT*> &getRoots() const { return Roots; }
 
   /// isPostDominator - Returns true if analysis based of postdoms
   ///
@@ -58,7 +63,7 @@
 
 //===----------------------------------------------------------------------===//
 // DomTreeNode - Dominator Tree Node
-class DominatorTreeBase;
+template<class NodeT> class DominatorTreeBase;
 class PostDominatorTree;
 class MachineBasicBlock;
 
@@ -69,7 +74,7 @@
   std::vector<DomTreeNodeBase<NodeT> *> Children;
   int DFSNumIn, DFSNumOut;
 
-  friend class DominatorTreeBase;
+  template<class N> friend class DominatorTreeBase;
   friend class PostDominatorTree;
 public:
   typedef typename std::vector<DomTreeNodeBase<NodeT> *>::iterator iterator;
@@ -124,18 +129,43 @@
   }
 };
 
+EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<BasicBlock>);
+
+template<class NodeT>
+static std::ostream &operator<<(std::ostream &o,
+                                const DomTreeNodeBase<NodeT> *Node) {
+  if (Node->getBlock())
+    WriteAsOperand(o, Node->getBlock(), false);
+  else
+    o << " <<exit node>>";
+  
+  o << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}";
+  
+  return o << "\n";
+}
+
+template<class NodeT>
+static void PrintDomTree(const DomTreeNodeBase<NodeT> *N, std::ostream &o,
+                         unsigned Lev) {
+  o << std::string(2*Lev, ' ') << "[" << Lev << "] " << N;
+  for (typename DomTreeNodeBase<NodeT>::const_iterator I = N->begin(),
+       E = N->end(); I != E; ++I)
+    PrintDomTree<NodeT>(*I, o, Lev+1);
+}
+
 typedef DomTreeNodeBase<BasicBlock> DomTreeNode;
 typedef DomTreeNodeBase<MachineBasicBlock> MachineDomTreeNode;
 
 //===----------------------------------------------------------------------===//
 /// DominatorTree - Calculate the immediate dominator tree for a function.
 ///
-class DominatorTreeBase : public DominatorBase {
+
+template<class NodeT>
+class DominatorTreeBase : public DominatorBase<NodeT> {
 protected:
-  void reset();
-  typedef DenseMap<BasicBlock*, DomTreeNode*> DomTreeNodeMapType;
+  typedef DenseMap<NodeT*, DomTreeNodeBase<NodeT>*> DomTreeNodeMapType;
   DomTreeNodeMapType DomTreeNodes;
-  DomTreeNode *RootNode;
+  DomTreeNodeBase<NodeT> *RootNode;
 
   bool DFSInfoValid;
   unsigned int SlowQueries;
@@ -143,24 +173,35 @@
   struct InfoRec {
     unsigned Semi;
     unsigned Size;
-    BasicBlock *Label, *Parent, *Child, *Ancestor;
+    NodeT *Label, *Parent, *Child, *Ancestor;
 
-    std::vector<BasicBlock*> Bucket;
+    std::vector<NodeT*> Bucket;
 
     InfoRec() : Semi(0), Size(0), Label(0), Parent(0), Child(0), Ancestor(0) {}
   };
 
-  DenseMap<BasicBlock*, BasicBlock*> IDoms;
+  DenseMap<NodeT*, NodeT*> IDoms;
 
   // Vertex - Map the DFS number to the BasicBlock*
-  std::vector<BasicBlock*> Vertex;
+  std::vector<NodeT*> Vertex;
 
   // Info - Collection of information used during the computation of idoms.
-  DenseMap<BasicBlock*, InfoRec> Info;
+  DenseMap<NodeT*, InfoRec> 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<NodeT>(ID, isPostDom), DFSInfoValid(false), SlowQueries(0) {}
   ~DominatorTreeBase() { reset(); }
 
   virtual void releaseMemory() { reset(); }
@@ -168,12 +209,12 @@
   /// 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<NodeT> *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<NodeT> *operator[](NodeT *BB) const {
     return getNode(BB);
   }
 
@@ -184,25 +225,25 @@
   /// post-dominance information must be capable of dealing with this
   /// possibility.
   ///
-  DomTreeNode *getRootNode() { return RootNode; }
-  const DomTreeNode *getRootNode() const { return RootNode; }
+  DomTreeNodeBase<NodeT> *getRootNode() { return RootNode; }
+  const DomTreeNodeBase<NodeT> *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<NodeT> *A,
+                         DomTreeNodeBase<NodeT> *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<NodeT> *A, 
+                               const DomTreeNodeBase<NodeT> *B) const {
+    const DomTreeNodeBase<NodeT> *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 @@
 
   /// 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<NodeT> *A,
+                        DomTreeNodeBase<NodeT> *B) {
     if (B == A) 
       return true;  // A node trivially dominates itself.
 
@@ -239,7 +284,7 @@
     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 @@
 
   /// 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<NodeT> *NodeA = getNode(A);
+    DomTreeNodeBase<NodeT> *NodeB = getNode(B);
+
+    // Collect NodeA dominators set.
+    SmallPtrSet<DomTreeNodeBase<NodeT>*, 16> NodeADoms;
+    NodeADoms.insert(NodeA);
+    DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom();
+    while (IDomA) {
+      NodeADoms.insert(IDomA);
+      IDomA = IDomA->getIDom();
+    }
+
+    // Walk NodeB immediate dominators chain and find common dominator node.
+    DomTreeNodeBase<NodeT> *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<PHINode>(A) && isa<PHINode>(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 @@
   /// 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<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) {
     assert(getNode(BB) == 0 && "Block already in dominator tree!");
-    DomTreeNode *IDomNode = getNode(DomBB);
+    DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
     assert(IDomNode && "Not immediate dominator specified for block!");
     DFSInfoValid = false;
     return DomTreeNodes[BB] = 
@@ -273,76 +380,156 @@
   /// 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<NodeT> *N,
+                                DomTreeNodeBase<NodeT> *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<NodeT> *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<NodeT> *IDom = Node->getIDom();
+    if (IDom) {
+      typename std::vector<DomTreeNodeBase<NodeT>*>::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<NodeT>(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<class GraphT> friend void Compress(DominatorTreeBase& DT,
+  template<class GraphT> friend void Compress(DominatorTreeBase<typename GraphT::NodeType>& DT,
                                               typename GraphT::NodeType* VIn);
   template<class GraphT> friend typename GraphT::NodeType* Eval(
-                                                  DominatorTreeBase& DT,
+                                                  DominatorTreeBase<typename GraphT::NodeType>& DT,
                                                   typename GraphT::NodeType* V);
-  template<class GraphT> friend void Link(DominatorTreeBase& DT,
+  template<class GraphT> friend void Link(DominatorTreeBase<typename GraphT::NodeType>& DT,
                                           typename GraphT::NodeType* V,
                                           typename GraphT::NodeType* W,
-                                          InfoRec &WInfo);
+                                 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo);
   
-  template<class GraphT> friend unsigned DFSPass(DominatorTreeBase& DT,
+  template<class GraphT> friend unsigned DFSPass(
+                                                 DominatorTreeBase<typename GraphT::NodeType>& DT,
                                                  typename GraphT::NodeType* V,
                                                  unsigned N);
   
-  template<class NodeT> friend void Calculate(DominatorTreeBase& DT,
-                                              Function& F);
+  template<class N, class GraphT> friend void Calculate(DominatorTreeBase<typename GraphT::NodeType>& 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<std::pair<DomTreeNodeBase<NodeT>*,
+                typename DomTreeNodeBase<NodeT>::iterator>, 32> WorkStack;
+
+    for (unsigned i = 0, e = this->Roots.size(); i != e; ++i) {
+      DomTreeNodeBase<NodeT> *ThisRoot = getNode(this->Roots[i]);
+      WorkStack.push_back(std::make_pair(ThisRoot, ThisRoot->begin()));
+      ThisRoot->DFSNumIn = DFSNum++;
+
+      while (!WorkStack.empty()) {
+        DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
+        typename DomTreeNodeBase<NodeT>::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<NodeT> *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<NodeT> *getNodeForBlock(NodeT *BB) {
+    if (DomTreeNodeBase<NodeT> *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<NodeT> *IDomNode = getNodeForBlock(IDom);
+
+    // Add a new tree node for this BasicBlock, and link it as a child of
+    // IDomNode
+    DomTreeNodeBase<NodeT> *C = new DomTreeNodeBase<NodeT>(BB, IDomNode);
+    return this->DomTreeNodes[BB] = IDomNode->addChild(C);
+  }
   
-  inline BasicBlock *getIDom(BasicBlock *BB) const {
-    DenseMap<BasicBlock*, BasicBlock*>::const_iterator I = IDoms.find(BB);
+  inline NodeT *getIDom(NodeT *BB) const {
+    typename DenseMap<NodeT*, NodeT*>::const_iterator I = IDoms.find(BB);
     return I != IDoms.end() ? I->second : 0;
   }
 };
 
+EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<BasicBlock>);
+
 //===-------------------------------------
 /// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to
 /// compute a normal dominator tree.
 ///
-class DominatorTree : public DominatorTreeBase {
+class DominatorTree : public DominatorTreeBase<BasicBlock> {
 public:
   static char ID; // Pass ID, replacement for typeid
-  DominatorTree() : DominatorTreeBase(intptr_t(&ID), false) {}
+  DominatorTree() : DominatorTreeBase<BasicBlock>(intptr_t(&ID), false) {}
   
   BasicBlock *getRoot() const {
     assert(Roots.size() == 1 && "Should always have entry node!");
@@ -392,7 +579,7 @@
 /// DominanceFrontierBase - Common base class for computing forward and inverse
 /// dominance frontiers for a function.
 ///
-class DominanceFrontierBase : public DominatorBase {
+class DominanceFrontierBase : public DominatorBase<BasicBlock> {
 public:
   typedef std::set<BasicBlock*>             DomSetType;    // Dom set for a bb
   typedef std::map<BasicBlock*, DomSetType> DomSetMapType; // Dom set map
@@ -400,7 +587,7 @@
   DomSetMapType Frontiers;
 public:
   DominanceFrontierBase(intptr_t ID, bool isPostDom) 
-    : DominatorBase(ID, isPostDom) {}
+    : DominatorBase<BasicBlock>(ID, isPostDom) {}
 
   virtual void releaseMemory() { Frontiers.clear(); }
 

Modified: llvm/trunk/include/llvm/Analysis/PostDominators.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/PostDominators.h?rev=43036&r1=43035&r2=43036&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/PostDominators.h (original)
+++ llvm/trunk/include/llvm/Analysis/PostDominators.h Tue Oct 16 14:59:25 2007
@@ -21,11 +21,11 @@
 /// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to
 /// compute the a post-dominator tree.
 ///
-struct PostDominatorTree : public DominatorTreeBase {
+struct PostDominatorTree : public DominatorTreeBase<BasicBlock> {
   static char ID; // Pass identification, replacement for typeid
 
   PostDominatorTree() : 
-    DominatorTreeBase((intptr_t)&ID, true) {}
+    DominatorTreeBase<BasicBlock>((intptr_t)&ID, true) {}
 
   virtual bool runOnFunction(Function &F);
 

Modified: llvm/trunk/lib/Analysis/PostDominators.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PostDominators.cpp?rev=43036&r1=43035&r2=43036&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/PostDominators.cpp (original)
+++ llvm/trunk/lib/Analysis/PostDominators.cpp Tue Oct 16 14:59:25 2007
@@ -47,7 +47,7 @@
   
   Vertex.push_back(0);
     
-  Calculate<Inverse<BasicBlock*> >(*this, F);
+  Calculate<Inverse<BasicBlock*>, GraphTraits<Inverse<BasicBlock*> > >(*this, F);
   return false;
 }
 

Modified: llvm/trunk/lib/VMCore/Dominators.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Dominators.cpp?rev=43036&r1=43035&r2=43036&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/Dominators.cpp (original)
+++ llvm/trunk/lib/VMCore/Dominators.cpp Tue Oct 16 14:59:25 2007
@@ -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 @@
 //
 //===----------------------------------------------------------------------===//
 
+TEMPLATE_INSTANTIATION(class DomTreeNodeBase<BasicBlock>);
+TEMPLATE_INSTANTIATION(class DominatorTreeBase<BasicBlock>);
+
 char DominatorTree::ID = 0;
 static RegisterPass<DominatorTree>
 E("domtree", "Dominator Tree Construction", true);
@@ -135,203 +138,6 @@
   }
 }
 
-void DominatorTreeBase::updateDFSNumbers() {
-  unsigned DFSNum = 0;
-
-  SmallVector<std::pair<DomTreeNode*, DomTreeNode::iterator>, 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<PHINode>(A) && isa<PHINode>(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<DomTreeNode*, 16> 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 << " <<exit node>>";
-  
-  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<DomTreeNode*>::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 @@
   DomTreeNodes[&F.getEntryBlock()] = 0;
   Vertex.push_back(0);
   
-  Calculate<BasicBlock*>(*this, F);
+  Calculate<BasicBlock*, GraphTraits<BasicBlock*> >(*this, F);
   
   updateDFSNumbers();
   





More information about the llvm-commits mailing list