//===----------------------------------------------------------------------===//
//
// This file defines the following classes:
-// 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
+// 1. DominatorTree: Represent the ImmediateDominator as an explicit tree
// structure.
-// 4. ETForest: Efficient data structure for dominance comparisons and
+// 2. ETForest: Efficient data structure for dominance comparisons and
// nearest-common-ancestor queries.
-// 5. DominanceFrontier: Calculate and hold the dominance frontier for a
+// 3. DominanceFrontier: Calculate and hold the dominance frontier for a
// function.
//
// These data structures are listed in increasing order of complexity. It
bool isPostDominator() const { return IsPostDominators; }
};
-
//===----------------------------------------------------------------------===//
-/// ImmediateDominators - Calculate the immediate dominator for each node in a
-/// function.
+/// DominatorTree - Calculate the immediate dominator tree for a function.
///
-class ImmediateDominatorsBase : public DominatorBase {
+class DominatorTreeBase : public DominatorBase {
+public:
+ class Node;
protected:
+ std::map<BasicBlock*, Node*> Nodes;
+ void reset();
+ typedef std::map<BasicBlock*, Node*> NodeMapType;
+
+ Node *RootNode;
+
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){}
};
-
+
std::map<BasicBlock*, BasicBlock*> IDoms;
// 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;
-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);
- }
-
- /// dominates - Return true if A dominates B.
- ///
- bool dominates(BasicBlock *A, BasicBlock *B) const;
-
- /// properlyDominates - Return true if A dominates B and A != B.
- ///
- bool properlyDominates(BasicBlock *A, BasicBlock *B) const {
- return A != B || properlyDominates(A, B);
- }
-
- /// 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 Module* = 0) const;
-};
-
-//===-------------------------------------
-/// ImmediateDominators Class - Concrete subclass of ImmediateDominatorsBase
-/// that is used to compute a normal immediate dominator set.
-///
-class ImmediateDominators : public ImmediateDominatorsBase {
-public:
- 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:
- 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
-/// function, that represents the blocks that dominate the block. If the block
-/// is unreachable in this function, the set will be empty. This cannot happen
-/// for reachable code, because every block dominates at least itself.
-///
-class DominatorSetBase : public DominatorBase {
-public:
- typedef std::set<BasicBlock*> DomSetType; // Dom set for a bb
- // Map of dom sets
- typedef std::map<BasicBlock*, DomSetType> DomSetMapType;
-protected:
- DomSetMapType Doms;
-public:
- DominatorSetBase(bool isPostDom) : DominatorBase(isPostDom) {}
-
- virtual void releaseMemory() { Doms.clear(); }
-
- // Accessor interface:
- typedef DomSetMapType::const_iterator const_iterator;
- typedef DomSetMapType::iterator iterator;
- inline const_iterator begin() const { return Doms.begin(); }
- inline iterator begin() { return Doms.begin(); }
- inline const_iterator end() const { return Doms.end(); }
- inline iterator end() { return Doms.end(); }
- inline const_iterator find(BasicBlock* B) const { return Doms.find(B); }
- inline iterator find(BasicBlock* B) { return Doms.find(B); }
-
-
- /// getDominators - Return the set of basic blocks that dominate the specified
- /// block.
- ///
- inline const DomSetType &getDominators(BasicBlock *BB) const {
- const_iterator I = find(BB);
- assert(I != end() && "BB not in function!");
- return I->second;
- }
-
- /// isReachable - Return true if the specified basicblock is reachable. If
- /// the block is reachable, we have dominator set information for it.
- ///
- bool isReachable(BasicBlock *BB) const {
- return !getDominators(BB).empty();
- }
-
- /// dominates - Return true if A dominates B.
- ///
- inline bool dominates(BasicBlock *A, BasicBlock *B) const {
- return getDominators(B).count(A) != 0;
- }
-
- /// properlyDominates - Return true if A dominates B and A != B.
- ///
- bool properlyDominates(BasicBlock *A, BasicBlock *B) const {
- return dominates(A, B) && A != B;
- }
-
- /// print - Convert to human readable form
- ///
- virtual void print(std::ostream &OS, const Module* = 0) const;
-
- /// dominates - Return true if A dominates B. This performs the special
- /// checks necessary if A and B are in the same basic block.
- ///
- bool dominates(Instruction *A, Instruction *B) const;
-
- //===--------------------------------------------------------------------===//
- // API to update (Post)DominatorSet information based on modifications to
- // the CFG...
-
- /// addBasicBlock - Call to update the dominator set with information about a
- /// new block that was inserted into the function.
- ///
- void addBasicBlock(BasicBlock *BB, const DomSetType &Dominators) {
- assert(find(BB) == end() && "Block already in DominatorSet!");
- Doms.insert(std::make_pair(BB, Dominators));
- }
-
- /// addDominator - If a new block is inserted into the CFG, then method may be
- /// called to notify the blocks it dominates that it is in their set.
- ///
- void addDominator(BasicBlock *BB, BasicBlock *NewDominator) {
- iterator I = find(BB);
- assert(I != end() && "BB is not in DominatorSet!");
- I->second.insert(NewDominator);
- }
-};
-
-
-//===-------------------------------------
-/// DominatorSet Class - Concrete subclass of DominatorSetBase that is used to
-/// compute a normal dominator set.
-///
-class DominatorSet : public DominatorSetBase {
-public:
- DominatorSet() : DominatorSetBase(false) {}
-
- virtual bool runOnFunction(Function &F);
-
- 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.addRequired<ImmediateDominators>();
- AU.setPreservesAll();
- }
-
- // stub - dummy function, just ignore it
- static int stub;
-};
-
-
-//===----------------------------------------------------------------------===//
-/// DominatorTree - Calculate the immediate dominator tree for a function.
-///
-class DominatorTreeBase : public DominatorBase {
-public:
- class Node;
-protected:
- std::map<BasicBlock*, Node*> Nodes;
- void reset();
- typedef std::map<BasicBlock*, Node*> NodeMapType;
-
- Node *RootNode;
public:
class Node {
- friend struct DominatorTree;
+ friend class DominatorTree;
friend struct PostDominatorTree;
- friend struct DominatorTreeBase;
+ friend class DominatorTreeBase;
BasicBlock *TheBB;
Node *IDom;
std::vector<Node*> Children;
/// print - Convert to human readable form
///
virtual void print(std::ostream &OS, const Module* = 0) const;
+ void print(std::ostream *OS, const Module* M = 0) const {
+ if (OS) print(*OS, M);
+ }
+};
+
+//===-------------------------------------
+/// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to
+/// compute a normal dominator tree.
+///
+class DominatorTree : public DominatorTreeBase {
+public:
+ DominatorTree() : DominatorTreeBase(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:
+ void calculate(Function& F);
+ Node *getNodeForBlock(BasicBlock *BB);
+ 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);
+ inline BasicBlock *getIDom(BasicBlock *BB) const {
+ std::map<BasicBlock*, BasicBlock*>::const_iterator I = IDoms.find(BB);
+ return I != IDoms.end() ? I->second : 0;
+ }
+};
+
+//===-------------------------------------
+/// DominatorTree GraphTraits specialization so the DominatorTree can be
+/// iterable by generic graph iterators.
+///
+template <> struct GraphTraits<DominatorTree::Node*> {
+ typedef DominatorTree::Node NodeType;
+ typedef NodeType::iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(NodeType *N) {
+ return N;
+ }
+ static inline ChildIteratorType child_begin(NodeType* N) {
+ return N->begin();
+ }
+ static inline ChildIteratorType child_end(NodeType* N) {
+ return N->end();
+ }
+};
+
+template <> struct GraphTraits<DominatorTree*>
+ : public GraphTraits<DominatorTree::Node*> {
+ static NodeType *getEntryNode(DominatorTree *DT) {
+ return DT->getRootNode();
+ }
};
}
}
+ // dominates - Return true if A dominates B. This performs the
+ // special checks necessary if A and B are in the same basic block.
+ bool dominates(Instruction *A, Instruction *B);
+
/// properlyDominates - Return true if A dominates B and A != B.
///
bool properlyDominates(BasicBlock *A, BasicBlock *B) {
return dominates(A, B) && A != B;
}
+ /// isReachableFromEntry - Return true if A is dominated by the entry
+ /// block of the function containing it.
+ const bool isReachableFromEntry(BasicBlock* A);
+
/// Return the nearest common dominator of A and B.
BasicBlock *nearestCommonDominator(BasicBlock *A, BasicBlock *B) const {
ETNode *NodeA = getNode(A);
return NULL;
return Common->getData<BasicBlock>();
}
+
+ /// Return the immediate dominator of A.
+ BasicBlock *getIDom(BasicBlock *A) const {
+ ETNode *NodeA = getNode(A);
+ if (!NodeA) return 0;
+ const ETNode *idom = NodeA->getFather();
+ return idom ? idom->getData<BasicBlock>() : 0;
+ }
+
+ void getChildren(BasicBlock *A, std::vector<BasicBlock*>& children) const {
+ ETNode *NodeA = getNode(A);
+ if (!NodeA) return;
+ const ETNode* son = NodeA->getSon();
+
+ if (!son) return;
+ children.push_back(son->getData<BasicBlock>());
+
+ const ETNode* brother = son->getBrother();
+ while (brother != son) {
+ children.push_back(brother->getData<BasicBlock>());
+ brother = brother->getBrother();
+ }
+ }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
- AU.addRequired<ImmediateDominators>();
+ AU.addRequired<DominatorTree>();
}
//===--------------------------------------------------------------------===//
// API to update Forest information based on modifications
/// print - Convert to human readable form
///
virtual void print(std::ostream &OS, const Module* = 0) const;
+ void print(std::ostream *OS, const Module* M = 0) const {
+ if (OS) print(*OS, M);
+ }
protected:
/// getNode - return the (Post)DominatorTree node for the specified basic
/// block. This is the same as using operator[] on this class.
virtual bool runOnFunction(Function &F) {
reset(); // Reset from the last time we were run...
- ImmediateDominators &ID = getAnalysis<ImmediateDominators>();
- Roots = ID.getRoots();
- calculate(ID);
+ DominatorTree &DT = getAnalysis<DominatorTree>();
+ Roots = DT.getRoots();
+ calculate(DT);
return false;
}
- void calculate(const ImmediateDominators &ID);
+ void calculate(const DominatorTree &DT);
ETNode *getNodeForBlock(BasicBlock *BB);
};
-//===-------------------------------------
-/// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to
-/// compute a normal dominator tree.
-///
-class DominatorTree : public DominatorTreeBase {
-public:
- 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...
- ImmediateDominators &ID = getAnalysis<ImmediateDominators>();
- Roots = ID.getRoots();
- calculate(ID);
- return false;
- }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequired<ImmediateDominators>();
- }
-private:
- void calculate(const ImmediateDominators &ID);
- Node *getNodeForBlock(BasicBlock *BB);
-};
-
-//===-------------------------------------
-/// DominatorTree GraphTraits specialization so the DominatorTree can be
-/// iterable by generic graph iterators.
-///
-template <> struct GraphTraits<DominatorTree::Node*> {
- typedef DominatorTree::Node NodeType;
- typedef NodeType::iterator ChildIteratorType;
-
- static NodeType *getEntryNode(NodeType *N) {
- return N;
- }
- static inline ChildIteratorType child_begin(NodeType* N) {
- return N->begin();
- }
- static inline ChildIteratorType child_end(NodeType* N) {
- return N->end();
- }
-};
-
-template <> struct GraphTraits<DominatorTree*>
- : public GraphTraits<DominatorTree::Node*> {
- static NodeType *getEntryNode(DominatorTree *DT) {
- return DT->getRootNode();
- }
-};
-
//===----------------------------------------------------------------------===//
/// DominanceFrontierBase - Common base class for computing forward and inverse
/// dominance frontiers for a function.
/// print - Convert to human readable form
///
virtual void print(std::ostream &OS, const Module* = 0) const;
+ void print(std::ostream *OS, const Module* M = 0) const {
+ if (OS) print(*OS, M);
+ }
};
} // End llvm namespace
-// Make sure that any clients of this file link in Dominators.cpp
-FORCE_DEFINING_FILE_TO_BE_LINKED(DominatorSet)
-
#endif