Changes to compile with GCC 2.96
[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 Node2;
130 public:
131   typedef Node2 Node;
132 private:
133   map<const BasicBlock*, Node*> Nodes;
134   void calculate(const DominatorSet &DS);
135   typedef map<const BasicBlock*, Node*> NodeMapType;
136 public:
137   class Node2 : public vector<Node*> {
138     friend class DominatorTree;
139     const BasicBlock *TheNode;
140     Node2 * const IDom;
141   public:
142     inline const BasicBlock *getNode() const { return TheNode; }
143     inline Node2 *getIDom() const { return IDom; }
144     inline const vector<Node*> &getChildren() const { return *this; }
145
146     // dominates - Returns true iff this dominates N.  Note that this is not a 
147     // constant time operation!
148     inline bool dominates(const Node2 *N) const {
149       const Node2 *IDom;
150       while ((IDom = N->getIDom()) != 0 && IDom != this)
151         N = IDom;   // Walk up the tree
152       return IDom != 0;
153     }
154
155   private:
156     inline Node2(const BasicBlock *node, Node *iDom) 
157       : TheNode(node), IDom(iDom) {}
158     inline Node2 *addChild(Node *C) { push_back(C); return C; }
159   };
160
161 public:
162   // DominatorTree ctors - Compute a dominator tree, given various amounts of
163   // previous knowledge...
164   inline DominatorTree(const DominatorSet &DS) : DominatorBase(DS.getRoot()) { 
165     calculate(DS); 
166   }
167
168   DominatorTree(const ImmediateDominators &IDoms);
169   ~DominatorTree();
170
171   inline const Node *operator[](const BasicBlock *BB) const {
172     NodeMapType::const_iterator i = Nodes.find(BB);
173     return (i != Nodes.end()) ? i->second : 0;
174   }
175 };
176
177
178 //===----------------------------------------------------------------------===//
179 //
180 // DominanceFrontier - Calculate the dominance frontiers for a method.
181 //
182 class DominanceFrontier : public DominatorBase {
183 public:
184   typedef set<const BasicBlock*>              DomSetType;    // Dom set for a bb
185   typedef map<const BasicBlock *, DomSetType> DomSetMapType; // Map of dom sets
186 private:
187   DomSetMapType Frontiers;
188   const DomSetType &calcDomFrontier(const DominatorTree &DT,
189                                     const DominatorTree::Node *Node);
190   const DomSetType &calcPostDomFrontier(const DominatorTree &DT,
191                                         const DominatorTree::Node *Node);
192 public:
193   DominanceFrontier(const DominatorSet &DS) : DominatorBase(DS.getRoot()) {
194     const DominatorTree DT(DS);
195     if (isPostDominator())
196       calcPostDomFrontier(DT, DT[Root]);
197     else
198       calcDomFrontier(DT, DT[Root]);
199   }    
200   DominanceFrontier(const ImmediateDominators &ID)
201     : DominatorBase(ID.getRoot()) {
202     const DominatorTree DT(ID);
203     if (isPostDominator())
204       calcPostDomFrontier(DT, DT[Root]);
205     else
206       calcDomFrontier(DT, DT[Root]);
207   }
208   DominanceFrontier(const DominatorTree &DT) : DominatorBase(DT.getRoot()) {
209     if (isPostDominator())
210       calcPostDomFrontier(DT, DT[Root]);
211     else
212       calcDomFrontier(DT, DT[Root]);
213   }
214
215   // Accessor interface:
216   typedef DomSetMapType::const_iterator const_iterator;
217   inline const_iterator begin() const { return Frontiers.begin(); }
218   inline const_iterator end()   const { return Frontiers.end(); }
219   inline const_iterator find(const BasicBlock* B) const { return Frontiers.find(B);}
220 };
221
222 } // End namespace cfg
223
224 #endif