From: Chris Lattner Date: Wed, 10 Sep 2003 20:36:51 +0000 (+0000) Subject: Rework dominator and post dominator information so that we do not have to X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=420a8bf2b2276acdb4d7004ae251a2460999c0e4;p=oota-llvm.git 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. :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8459 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h index a6df5560515..17b5efa52a0 100644 --- a/include/llvm/Analysis/Dominators.h +++ b/include/llvm/Analysis/Dominators.h @@ -32,12 +32,15 @@ template struct GraphTraits; // class DominatorBase : public FunctionPass { protected: - BasicBlock *Root; + std::vector 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 &getRoots() const { return Roots; } // Returns true if analysis based of postdoms bool isPostDominator() const { return IsPostDominators; } @@ -144,6 +147,11 @@ struct DominatorSet : public DominatorSetBase { /// 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 @@ public: 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(); - Root = DS.getRoot(); + Roots = DS.getRoots(); calcIDoms(DS); return false; } @@ -247,6 +260,8 @@ protected: std::map Nodes; void reset(); typedef std::map NodeMapType; + + Node *RootNode; public: class Node2 { friend class DominatorTree; @@ -303,7 +318,18 @@ public: 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 @@ public: 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(); - Root = DS.getRoot(); + Roots = DS.getRoots(); calculate(DS); return false; } @@ -374,7 +405,7 @@ template <> struct GraphTraits { template <> struct GraphTraits : public GraphTraits { static NodeType *getEntryNode(DominatorTree *DT) { - return DT->getNode(DT->getRoot()); + return DT->getRootNode(); } }; @@ -431,11 +462,17 @@ public: 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(); - 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; } diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h index 3a4ac7f92c1..f7131f2a45e 100644 --- a/include/llvm/Analysis/PostDominators.h +++ b/include/llvm/Analysis/PostDominators.h @@ -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 @@ struct ImmediatePostDominators : public ImmediateDominatorsBase { virtual bool runOnFunction(Function &F) { IDoms.clear(); // Reset from the last time we were run... PostDominatorSet &DS = getAnalysis(); - Root = DS.getRoot(); + Roots = DS.getRoots(); calcIDoms(DS); return false; } @@ -59,7 +63,7 @@ struct PostDominatorTree : public DominatorTreeBase { virtual bool runOnFunction(Function &F) { reset(); // Reset from the last time we were run... PostDominatorSet &DS = getAnalysis(); - Root = DS.getRoot(); + Roots = DS.getRoots(); calculate(DS); return false; } @@ -83,8 +87,8 @@ struct PostDominanceFrontier : public DominanceFrontierBase { virtual bool runOnFunction(Function &) { Frontiers.clear(); PostDominatorTree &DT = getAnalysis(); - Root = DT.getRoot(); - calculate(DT, DT[Root]); + Roots = DT.getRoots(); + calculate(DT, DT.getRootNode()); return false; }