From 31b935357d1396d3be32fdf24dcb0319a6908c6f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 7 Dec 2003 00:36:16 +0000 Subject: [PATCH] Rewrite dominators implementation. Now domset is constructed from immdom, instead of the other way around. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10300 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/Dominators.h | 206 ++++++++++++++++------------- 1 file changed, 111 insertions(+), 95 deletions(-) diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h index 5688d6e8119..4179fe7dc28 100644 --- a/include/llvm/Analysis/Dominators.h +++ b/include/llvm/Analysis/Dominators.h @@ -8,9 +8,9 @@ //===----------------------------------------------------------------------===// // // This file defines the following classes: -// 1. DominatorSet: Calculates the [reverse] dominator set for a function -// 2. ImmediateDominators: Calculates and holds a mapping between BasicBlocks +// 1. ImmediateDominators: Calculates and holds a mapping between BasicBlocks // and their immediate dominator. +// 2. DominatorSet: Calculates the [reverse] dominator set for a function // 3. DominatorTree: Represent the ImmediateDominator as an explicit tree // structure. // 4. DominanceFrontier: Calculate and hold the dominance frontier for a @@ -55,6 +55,108 @@ public: bool isPostDominator() const { return IsPostDominators; } }; + +//===----------------------------------------------------------------------===// +// +// ImmediateDominators - Calculate the immediate dominator for each node in a +// function. +// +class ImmediateDominatorsBase : public DominatorBase { +protected: + std::map IDoms; +public: + ImmediateDominatorsBase(bool isPostDom) : DominatorBase(isPostDom) {} + + virtual void releaseMemory() { IDoms.clear(); } + + // Accessor interface: + typedef std::map IDomMapType; + typedef IDomMapType::const_iterator const_iterator; + inline const_iterator begin() const { return IDoms.begin(); } + inline const_iterator end() const { return IDoms.end(); } + inline const_iterator find(BasicBlock* B) const { return IDoms.find(B);} + + // operator[] - Return the idom for the specified basic block. The start + // node returns null, because it does not have an immediate dominator. + // + inline BasicBlock *operator[](BasicBlock *BB) const { + return get(BB); + } + + // get() - Synonym for operator[]. + inline BasicBlock *get(BasicBlock *BB) const { + std::map::const_iterator I = IDoms.find(BB); + return I != IDoms.end() ? I->second : 0; + } + + //===--------------------------------------------------------------------===// + // API to update Immediate(Post)Dominators information based on modifications + // to the CFG... + + /// addNewBlock - Add a new block to the CFG, with the specified immediate + /// dominator. + /// + void addNewBlock(BasicBlock *BB, BasicBlock *IDom) { + assert(get(BB) == 0 && "BasicBlock already in idom info!"); + IDoms[BB] = IDom; + } + + /// setImmediateDominator - Update the immediate dominator information to + /// change the current immediate dominator for the specified block to another + /// block. This method requires that BB already have an IDom, otherwise just + /// use addNewBlock. + void setImmediateDominator(BasicBlock *BB, BasicBlock *NewIDom) { + assert(IDoms.find(BB) != IDoms.end() && "BB doesn't have idom yet!"); + IDoms[BB] = NewIDom; + } + + // print - Convert to human readable form + virtual void print(std::ostream &OS) const; +}; + +//===------------------------------------- +// ImmediateDominators Class - Concrete subclass of ImmediateDominatorsBase that +// is used to compute a normal immediate dominator set. +// +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); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + } + +private: + struct InfoRec { + unsigned Semi; + unsigned Size; + BasicBlock *Label, *Parent, *Child, *Ancestor; + + std::vector Bucket; + + InfoRec() : Semi(0), Size(0), Label(0), Parent(0), Child(0), Ancestor(0){} + }; + + // Vertex - Map the DFS number to the BasicBlock* + std::vector Vertex; + + // Info - Collection of information used during the computation of idoms. + std::map Info; + + unsigned DFSPass(BasicBlock *V, InfoRec &VInfo, unsigned N); + void Compress(BasicBlock *V, InfoRec &VInfo); + BasicBlock *Eval(BasicBlock *v); + void Link(BasicBlock *V, BasicBlock *W, InfoRec &WInfo); +}; + + + //===----------------------------------------------------------------------===// // // DominatorSet - Maintain a set for every basic block in a @@ -162,96 +264,9 @@ struct DominatorSet : public DominatorSetBase { // getAnalysisUsage - This simply provides a dominator set virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); AU.setPreservesAll(); } -private: - void calculateDominatorsFromBlock(BasicBlock *BB); -}; - - -//===----------------------------------------------------------------------===// -// -// ImmediateDominators - Calculate the immediate dominator for each node in a -// function. -// -class ImmediateDominatorsBase : public DominatorBase { -protected: - std::map IDoms; - void calcIDoms(const DominatorSetBase &DS); -public: - ImmediateDominatorsBase(bool isPostDom) : DominatorBase(isPostDom) {} - - virtual void releaseMemory() { IDoms.clear(); } - - // Accessor interface: - typedef std::map IDomMapType; - typedef IDomMapType::const_iterator const_iterator; - inline const_iterator begin() const { return IDoms.begin(); } - inline const_iterator end() const { return IDoms.end(); } - inline const_iterator find(BasicBlock* B) const { return IDoms.find(B);} - - // operator[] - Return the idom for the specified basic block. The start - // node returns null, because it does not have an immediate dominator. - // - inline BasicBlock *operator[](BasicBlock *BB) const { - return get(BB); - } - - // get() - Synonym for operator[]. - inline BasicBlock *get(BasicBlock *BB) const { - std::map::const_iterator I = IDoms.find(BB); - return I != IDoms.end() ? I->second : 0; - } - - //===--------------------------------------------------------------------===// - // API to update Immediate(Post)Dominators information based on modifications - // to the CFG... - - /// addNewBlock - Add a new block to the CFG, with the specified immediate - /// dominator. - /// - void addNewBlock(BasicBlock *BB, BasicBlock *IDom) { - assert(get(BB) == 0 && "BasicBlock already in idom info!"); - IDoms[BB] = IDom; - } - - /// setImmediateDominator - Update the immediate dominator information to - /// change the current immediate dominator for the specified block to another - /// block. This method requires that BB already have an IDom, otherwise just - /// use addNewBlock. - void setImmediateDominator(BasicBlock *BB, BasicBlock *NewIDom) { - assert(IDoms.find(BB) != IDoms.end() && "BB doesn't have idom yet!"); - IDoms[BB] = NewIDom; - } - - // print - Convert to human readable form - virtual void print(std::ostream &OS) const; -}; - -//===------------------------------------- -// ImmediateDominators Class - Concrete subclass of ImmediateDominatorsBase that -// is used to compute a normal immediate dominator set. -// -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(); - Roots = DS.getRoots(); - calcIDoms(DS); - return false; - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequired(); - } }; @@ -374,18 +389,19 @@ struct DominatorTree : public DominatorTreeBase { virtual bool runOnFunction(Function &F) { reset(); // Reset from the last time we were run... - DominatorSet &DS = getAnalysis(); - Roots = DS.getRoots(); - calculate(DS); + ImmediateDominators &ID = getAnalysis(); + Roots = ID.getRoots(); + calculate(ID); return false; } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); - AU.addRequired(); + AU.addRequired(); } private: - void calculate(const DominatorSet &DS); + void calculate(const ImmediateDominators &ID); + Node *getNodeForBlock(BasicBlock *BB); }; //===------------------------------------- -- 2.34.1