[llvm-commits] CVS: llvm/include/llvm/Analysis/Dominators.h PostDominators.h

Chris Lattner lattner at cs.uiuc.edu
Wed Sep 10 15:38:01 PDT 2003


Changes in directory llvm/include/llvm/Analysis:

Dominators.h updated: 1.37 -> 1.38
PostDominators.h updated: 1.1 -> 1.2

---
Log message:

Rework dominator and post dominator information so that we do not have to 
unify all exit nodes of a function to compute post-dominance information.
This does not work with functions that have both unwind and return nodes,
because we cannot unify these blocks.  The new implementation is better 
anyway. :)


---
Diffs of the changes:

Index: llvm/include/llvm/Analysis/Dominators.h
diff -u llvm/include/llvm/Analysis/Dominators.h:1.37 llvm/include/llvm/Analysis/Dominators.h:1.38
--- llvm/include/llvm/Analysis/Dominators.h:1.37	Mon Aug 18 17:10:57 2003
+++ llvm/include/llvm/Analysis/Dominators.h	Wed Sep 10 15:36:51 2003
@@ -32,12 +32,15 @@
 //
 class DominatorBase : public FunctionPass {
 protected:
-  BasicBlock *Root;
+  std::vector<BasicBlock*> Roots;
   const bool IsPostDominators;
 
-  inline DominatorBase(bool isPostDom) : Root(0), IsPostDominators(isPostDom) {}
+  inline DominatorBase(bool isPostDom) : Roots(), IsPostDominators(isPostDom) {}
 public:
-  inline BasicBlock *getRoot() const { return Root; }
+  // Return the root blocks of the current CFG.  This may include 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; }
 
   // Returns true if analysis based of postdoms
   bool isPostDominator() const { return IsPostDominators; }
@@ -144,6 +147,11 @@
   /// obviously really slow, so it should be avoided if at all possible.
   void recalculate();
 
+  BasicBlock *getRoot() const {
+    assert(Roots.size() == 1 && "Should always have entry node!");
+    return Roots[0];
+  }
+
   // getAnalysisUsage - This simply provides a dominator set
   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
     AU.setPreservesAll();
@@ -219,10 +227,15 @@
 struct ImmediateDominators : public ImmediateDominatorsBase {
   ImmediateDominators() : ImmediateDominatorsBase(false) {}
 
+  BasicBlock *getRoot() const {
+    assert(Roots.size() == 1 && "Should always have entry node!");
+    return Roots[0];
+  }
+
   virtual bool runOnFunction(Function &F) {
     IDoms.clear();     // Reset from the last time we were run...
     DominatorSet &DS = getAnalysis<DominatorSet>();
-    Root = DS.getRoot();
+    Roots = DS.getRoots();
     calcIDoms(DS);
     return false;
   }
@@ -247,6 +260,8 @@
   std::map<BasicBlock*, Node*> Nodes;
   void reset();
   typedef std::map<BasicBlock*, Node*> NodeMapType;
+
+  Node *RootNode;
 public:
   class Node2 {
     friend class DominatorTree;
@@ -303,7 +318,18 @@
     return getNode(BB);
   }
 
-  //===--------------------------------------------------------------------===//  // API to update (Post)DominatorTree information based on modifications to
+  // getRootNode - This returns the entry node for the CFG of the function.  If
+  // this tree represents the post-dominance relations for a function, however,
+  // this root may be a node with the block == NULL.  This is the case when
+  // there are multiple exit nodes from a particular function.  Consumers of
+  // post-dominance information must be capable of dealing with this
+  // possibility.
+  //
+  Node *getRootNode() { return RootNode; }
+  const Node *getRootNode() const { return RootNode; }
+
+  //===--------------------------------------------------------------------===//
+  // API to update (Post)DominatorTree information based on modifications to
   // the CFG...
 
   /// createNewNode - Add a new node to the dominator tree information.  This
@@ -336,10 +362,15 @@
 struct DominatorTree : public DominatorTreeBase {
   DominatorTree() : DominatorTreeBase(false) {}
 
+  BasicBlock *getRoot() const {
+    assert(Roots.size() == 1 && "Should always have entry node!");
+    return Roots[0];
+  }
+
   virtual bool runOnFunction(Function &F) {
     reset();     // Reset from the last time we were run...
     DominatorSet &DS = getAnalysis<DominatorSet>();
-    Root = DS.getRoot();
+    Roots = DS.getRoots();
     calculate(DS);
     return false;
   }
@@ -374,7 +405,7 @@
 template <> struct GraphTraits<DominatorTree*>
   : public GraphTraits<DominatorTree::Node*> {
   static NodeType *getEntryNode(DominatorTree *DT) {
-    return DT->getNode(DT->getRoot());
+    return DT->getRootNode();
   }
 };
 
@@ -431,11 +462,17 @@
 struct DominanceFrontier : public DominanceFrontierBase {
   DominanceFrontier() : DominanceFrontierBase(false) {}
 
+  BasicBlock *getRoot() const {
+    assert(Roots.size() == 1 && "Should always have entry node!");
+    return Roots[0];
+  }
+
   virtual bool runOnFunction(Function &) {
     Frontiers.clear();
     DominatorTree &DT = getAnalysis<DominatorTree>();
-    Root = DT.getRoot();
-    calculate(DT, DT[Root]);
+    Roots = DT.getRoots();
+    assert(Roots.size() == 1 && "Only one entry block for forward domfronts!");
+    calculate(DT, DT[Roots[0]]);
     return false;
   }
 


Index: llvm/include/llvm/Analysis/PostDominators.h
diff -u llvm/include/llvm/Analysis/PostDominators.h:1.1 llvm/include/llvm/Analysis/PostDominators.h:1.2
--- llvm/include/llvm/Analysis/PostDominators.h:1.1	Wed Aug 21 18:43:30 2002
+++ llvm/include/llvm/Analysis/PostDominators.h	Wed Sep 10 15:36:51 2003
@@ -10,19 +10,23 @@
 #include "llvm/Analysis/Dominators.h"
 
 
-//===-------------------------------------
-// DominatorSet Class - Concrete subclass of DominatorSetBase that is used to
-// compute the post-dominator set.
-//
+/// PostDominatorSet Class - Concrete subclass of DominatorSetBase that is used
+/// to compute the post-dominator set.  Because there can be multiple exit nodes
+/// in an LLVM function, we calculate post dominators with a special null block
+/// which is the virtual exit node that the real exit nodes all virtually branch
+/// to.  Clients should be prepared to see an entry in the dominator sets with a
+/// null BasicBlock*.
+///
 struct PostDominatorSet : public DominatorSetBase {
   PostDominatorSet() : DominatorSetBase(true) {}
 
   virtual bool runOnFunction(Function &F);
 
-  // getAnalysisUsage - This obviously provides a dominator set, but it also
-  // uses the UnifyFunctionExitNode pass if building post-dominators
+  // getAnalysisUsage - This pass does not modify the function at all.
   //
-  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+    AU.setPreservesAll();
+  }
 };
 
 
@@ -37,7 +41,7 @@
   virtual bool runOnFunction(Function &F) {
     IDoms.clear();     // Reset from the last time we were run...
     PostDominatorSet &DS = getAnalysis<PostDominatorSet>();
-    Root = DS.getRoot();
+    Roots = DS.getRoots();
     calcIDoms(DS);
     return false;
   }
@@ -59,7 +63,7 @@
   virtual bool runOnFunction(Function &F) {
     reset();     // Reset from the last time we were run...
     PostDominatorSet &DS = getAnalysis<PostDominatorSet>();
-    Root = DS.getRoot();
+    Roots = DS.getRoots();
     calculate(DS);
     return false;
   }
@@ -83,8 +87,8 @@
   virtual bool runOnFunction(Function &) {
     Frontiers.clear();
     PostDominatorTree &DT = getAnalysis<PostDominatorTree>();
-    Root = DT.getRoot();
-    calculate(DT, DT[Root]);
+    Roots = DT.getRoots();
+    calculate(DT, DT.getRootNode());
     return false;
   }
 





More information about the llvm-commits mailing list