* Add a DominatorBase base class to maintain root of Dominator info
[oota-llvm.git] / include / llvm / Analysis / Dominators.h
1 //===- llvm/Analysis/DominatorSet.h - Dominator Set Calculation --*- C++ -*--=//
2 //
3 // This file defines the following classes:
4 //  1. DominatorSet: Calculates the [reverse] dominator set for a method
5 //  2. ImmediateDominators: Calculates and holds a mapping between BasicBlocks
6 //     and their immediate dominator.
7 //  3. DominatorTree: Represent the ImmediateDominator as an explicit tree
8 //     structure.
9 //  4. DominanceFrontier: Calculate and hold the dominance frontier for a 
10 //     method.
11 //
12 //  These data structures are listed in increasing order of complexity.  It
13 //  takes longer to calculate the dominator frontier, for example, than the 
14 //  ImmediateDominator mapping.
15 // 
16 //===----------------------------------------------------------------------===//
17
18 #ifndef LLVM_DOMINATORS_H
19 #define LLVM_DOMINATORS_H
20
21 #include <set>
22 #include <map>
23 #include <vector>
24 class Method;
25 class BasicBlock;
26
27 namespace cfg {
28
29 //===----------------------------------------------------------------------===//
30 //
31 // DominatorBase - Base class that other, more interesting dominator analyses
32 // inherit from.
33 //
34 class DominatorBase {
35 protected:
36   const BasicBlock *Root;
37   inline DominatorBase(const BasicBlock *root = 0) : Root(root) {}
38 public:
39   inline const BasicBlock *getRoot() const { return Root; }
40   bool isPostDominator() const;  // Returns true if analysis based of postdoms
41 };
42
43 //===----------------------------------------------------------------------===//
44 //
45 // DominatorSet - Maintain a set<const BasicBlock*> for every basic block in a
46 // method, that represents the blocks that dominate the block.
47 //
48 class DominatorSet : public DominatorBase {
49 public:
50   typedef set<const BasicBlock*>              DomSetType;    // Dom set for a bb
51   typedef map<const BasicBlock *, DomSetType> DomSetMapType; // Map of dom sets
52 private:
53   DomSetMapType Doms;
54
55   void calcForwardDominatorSet(const Method *M);
56 public:
57   // DominatorSet ctor - Build either the dominator set or the post-dominator
58   // set for a method... Building the postdominator set may require the analysis
59   // routine to modify the method so that there is only a single return in the
60   // method.
61   //
62   DominatorSet(const Method *M);
63   DominatorSet(      Method *M, bool PostDomSet);
64
65   // Accessor interface:
66   typedef DomSetMapType::const_iterator const_iterator;
67   inline const_iterator begin() const { return Doms.begin(); }
68   inline const_iterator end()   const { return Doms.end(); }
69   inline const_iterator find(const BasicBlock* B) const { return Doms.find(B); }
70
71   // getDominators - Return the set of basic blocks that dominate the specified
72   // block.
73   //
74   inline const DomSetType &getDominators(const BasicBlock *BB) const {
75     const_iterator I = find(BB);
76     assert(I != end() && "BB not in method!");
77     return I->second;
78   }
79
80   // dominates - Return true if A dominates B.
81   //
82   inline bool dominates(const BasicBlock *A, const BasicBlock *B) const {
83     return getDominators(B).count(A) != 0;
84   }
85 };
86
87
88 //===----------------------------------------------------------------------===//
89 //
90 // ImmediateDominators - Calculate the immediate dominator for each node in a
91 // method.
92 //
93 class ImmediateDominators : public DominatorBase {
94   map<const BasicBlock*, const BasicBlock*> IDoms;
95   void calcIDoms(const DominatorSet &DS);
96 public:
97
98   // ImmediateDominators ctor - Calculate the idom mapping, for a method, or
99   // from a dominator set calculated for something else...
100   //
101   inline ImmediateDominators(const DominatorSet &DS)
102     : DominatorBase(DS.getRoot()) {
103     calcIDoms(DS);                         // Can be used to make rev-idoms
104   }
105
106   // Accessor interface:
107   typedef map<const BasicBlock*, const BasicBlock*> IDomMapType;
108   typedef IDomMapType::const_iterator const_iterator;
109   inline const_iterator begin() const { return IDoms.begin(); }
110   inline const_iterator end()   const { return IDoms.end(); }
111   inline const_iterator find(const BasicBlock* B) const { return IDoms.find(B);}
112
113   // operator[] - Return the idom for the specified basic block.  The start
114   // node returns null, because it does not have an immediate dominator.
115   //
116   inline const BasicBlock *operator[](const BasicBlock *BB) const {
117     map<const BasicBlock*, const BasicBlock*>::const_iterator I = 
118       IDoms.find(BB);
119     return I != IDoms.end() ? I->second : 0;
120   }
121 };
122
123
124 //===----------------------------------------------------------------------===//
125 //
126 // DominatorTree - Calculate the immediate dominator tree for a method.
127 //
128 class DominatorTree : public DominatorBase {
129   class Node;
130   map<const BasicBlock*, Node*> Nodes;
131   void calculate(const DominatorSet &DS);
132   typedef map<const BasicBlock*, Node*> NodeMapType;
133 public:
134   class Node : public vector<Node*> {
135     friend class DominatorTree;
136     const BasicBlock *TheNode;
137     Node * const IDom;
138   public:
139     inline const BasicBlock *getNode() const { return TheNode; }
140     inline Node *getIDom() const { return IDom; }
141     inline const vector<Node*> &getChildren() const { return *this; }
142
143     // dominates - Returns true iff this dominates N.  Note that this is not a 
144     // constant time operation!
145     inline bool dominates(const Node *N) const {
146       const Node *IDom;
147       while ((IDom = N->getIDom()) != 0 && IDom != this)
148         N = IDom;   // Walk up the tree
149       return IDom != 0;
150     }
151
152   private:
153     inline Node(const BasicBlock *node, Node *iDom) 
154       : TheNode(node), IDom(iDom) {}
155     inline Node *addChild(Node *C) { push_back(C); return C; }
156   };
157
158 public:
159   // DominatorTree ctors - Compute a dominator tree, given various amounts of
160   // previous knowledge...
161   inline DominatorTree(const DominatorSet &DS) : DominatorBase(DS.getRoot()) { 
162     calculate(DS); 
163   }
164
165   DominatorTree(const ImmediateDominators &IDoms);
166   ~DominatorTree();
167
168   inline const Node *operator[](const BasicBlock *BB) const {
169     NodeMapType::const_iterator i = Nodes.find(BB);
170     return (i != Nodes.end()) ? i->second : 0;
171   }
172 };
173
174
175 //===----------------------------------------------------------------------===//
176 //
177 // DominanceFrontier - Calculate the dominance frontiers for a method.
178 //
179 class DominanceFrontier : public DominatorBase {
180   typedef set<const BasicBlock*>              DomSetType;    // Dom set for a bb
181   typedef map<const BasicBlock *, DomSetType> DomSetMapType; // Map of dom sets
182 private:
183   DomSetMapType Frontiers;
184   const DomSetType &calcDomFrontier(const DominatorTree &DT,
185                                     const DominatorTree::Node *Node);
186   const DomSetType &calcPostDomFrontier(const DominatorTree &DT,
187                                         const DominatorTree::Node *Node);
188 public:
189   DominanceFrontier(const DominatorSet &DS) : DominatorBase(DS.getRoot()) {
190     const DominatorTree DT(DS);
191     if (isPostDominator())
192       calcPostDomFrontier(DT, DT[Root]);
193     else
194       calcDomFrontier(DT, DT[Root]);
195   }    
196   DominanceFrontier(const ImmediateDominators &ID)
197     : DominatorBase(ID.getRoot()) {
198     const DominatorTree DT(ID);
199     if (isPostDominator())
200       calcPostDomFrontier(DT, DT[Root]);
201     else
202       calcDomFrontier(DT, DT[Root]);
203   }
204   DominanceFrontier(const DominatorTree &DT) : DominatorBase(DT.getRoot()) {
205     if (isPostDominator())
206       calcPostDomFrontier(DT, DT[Root]);
207     else
208       calcDomFrontier(DT, DT[Root]);
209   }
210
211   // Accessor interface:
212   typedef DomSetMapType::const_iterator const_iterator;
213   inline const_iterator begin() const { return Frontiers.begin(); }
214   inline const_iterator end()   const { return Frontiers.end(); }
215   inline const_iterator find(const BasicBlock* B) const { return Frontiers.find(B);}
216 };
217
218 } // End namespace cfg
219
220 #endif