forked from OSchip/llvm-project
Rewrite dominators implementation. Now domset is constructed from immdom,
instead of the other way around. llvm-svn: 10300
This commit is contained in:
parent
f9f7c2d302
commit
31b77bbf7e
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
//===-------------------------------------
|
//===-------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue