Rewrite dominators implementation. Now domset is constructed from immdom,

instead of the other way around.

llvm-svn: 10300
This commit is contained in:
Chris Lattner 2003-12-07 00:36:16 +00:00
parent f9f7c2d302
commit 31b77bbf7e
1 changed files with 111 additions and 95 deletions

View File

@ -8,9 +8,9 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file defines the following classes: // This file defines the following classes:
// 1. DominatorSet: Calculates the [reverse] dominator set for a function // 1. ImmediateDominators: Calculates and holds a mapping between BasicBlocks
// 2. ImmediateDominators: Calculates and holds a mapping between BasicBlocks
// and their immediate dominator. // and their immediate dominator.
// 2. DominatorSet: Calculates the [reverse] dominator set for a function
// 3. DominatorTree: Represent the ImmediateDominator as an explicit tree // 3. DominatorTree: Represent the ImmediateDominator as an explicit tree
// structure. // structure.
// 4. DominanceFrontier: Calculate and hold the dominance frontier for a // 4. DominanceFrontier: Calculate and hold the dominance frontier for a
@ -55,6 +55,108 @@ public:
bool isPostDominator() const { return IsPostDominators; } bool isPostDominator() const { return IsPostDominators; }
}; };
//===----------------------------------------------------------------------===//
//
// ImmediateDominators - Calculate the immediate dominator for each node in a
// function.
//
class ImmediateDominatorsBase : public DominatorBase {
protected:
std::map<BasicBlock*, BasicBlock*> IDoms;
public:
ImmediateDominatorsBase(bool isPostDom) : DominatorBase(isPostDom) {}
virtual void releaseMemory() { IDoms.clear(); }
// Accessor interface:
typedef std::map<BasicBlock*, BasicBlock*> 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<BasicBlock*, BasicBlock*>::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<BasicBlock*> Bucket;
InfoRec() : Semi(0), Size(0), Label(0), Parent(0), Child(0), Ancestor(0){}
};
// Vertex - Map the DFS number to the BasicBlock*
std::vector<BasicBlock*> Vertex;
// Info - Collection of information used during the computation of idoms.
std::map<BasicBlock*, InfoRec> 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<BasicBlock*> for every basic block in a // DominatorSet - Maintain a set<BasicBlock*> for every basic block in a
@ -162,96 +264,9 @@ struct DominatorSet : public DominatorSetBase {
// getAnalysisUsage - This simply provides a dominator set // getAnalysisUsage - This simply provides a dominator set
virtual void getAnalysisUsage(AnalysisUsage &AU) const { virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<ImmediateDominators>();
AU.setPreservesAll(); 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<BasicBlock*, BasicBlock*> IDoms;
void calcIDoms(const DominatorSetBase &DS);
public:
ImmediateDominatorsBase(bool isPostDom) : DominatorBase(isPostDom) {}
virtual void releaseMemory() { IDoms.clear(); }
// Accessor interface:
typedef std::map<BasicBlock*, BasicBlock*> 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<BasicBlock*, BasicBlock*>::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<DominatorSet>();
Roots = DS.getRoots();
calcIDoms(DS);
return false;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<DominatorSet>();
}
}; };
@ -374,18 +389,19 @@ struct DominatorTree : public DominatorTreeBase {
virtual bool runOnFunction(Function &F) { virtual bool runOnFunction(Function &F) {
reset(); // Reset from the last time we were run... reset(); // Reset from the last time we were run...
DominatorSet &DS = getAnalysis<DominatorSet>(); ImmediateDominators &ID = getAnalysis<ImmediateDominators>();
Roots = DS.getRoots(); Roots = ID.getRoots();
calculate(DS); calculate(ID);
return false; return false;
} }
virtual void getAnalysisUsage(AnalysisUsage &AU) const { virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll(); AU.setPreservesAll();
AU.addRequired<DominatorSet>(); AU.addRequired<ImmediateDominators>();
} }
private: private:
void calculate(const DominatorSet &DS); void calculate(const ImmediateDominators &ID);
Node *getNodeForBlock(BasicBlock *BB);
}; };
//===------------------------------------- //===-------------------------------------