e84f1db3ebc49de31b667a5814993bf2e57a7f90
[oota-llvm.git] / include / llvm / Support / CFG.h
1 //===-- llvm/Support/CFG.h - Process LLVM structures as graphs ---*- C++ -*--=//
2 //
3 // This file defines specializations of GraphTraits that allow Function and
4 // BasicBlock graphs to be treated as proper graphs for generic algorithms.
5 //
6 //===----------------------------------------------------------------------===//
7
8 #ifndef LLVM_CFG_H
9 #define LLVM_CFG_H
10
11 #include "Support/GraphTraits.h"
12 #include "llvm/Function.h"
13 #include "llvm/InstrTypes.h"
14 #include "Support/iterator"
15
16 //===--------------------------------------------------------------------===//
17 // BasicBlock pred_iterator definition
18 //===--------------------------------------------------------------------===//
19
20 template <class _Ptr,  class _USE_iterator> // Predecessor Iterator
21 class PredIterator : public bidirectional_iterator<_Ptr, ptrdiff_t> {
22   typedef bidirectional_iterator<_Ptr, ptrdiff_t> super;
23   _Ptr *BB;
24   _USE_iterator It;
25 public:
26   typedef PredIterator<_Ptr,_USE_iterator> _Self;
27   typedef typename super::pointer pointer;
28   
29   inline PredIterator(_Ptr *bb) : BB(bb), It(bb->use_begin()) {
30   }
31   inline PredIterator(_Ptr *bb, bool) : BB(bb), It(bb->use_end()) {}
32     
33   inline bool operator==(const _Self& x) const { return It == x.It; }
34   inline bool operator!=(const _Self& x) const { return !operator==(x); }
35   
36   inline pointer operator*() const { 
37     assert(It != BB->use_end() && "pred_iterator out of range!");
38     return cast<TerminatorInst>(*It)->getParent(); 
39   }
40   inline pointer *operator->() const { return &(operator*()); }
41   
42   inline _Self& operator++() {   // Preincrement
43     assert(It != BB->use_end() && "pred_iterator out of range!");
44     ++It;
45     return *this; 
46   }
47   
48   inline _Self operator++(int) { // Postincrement
49     _Self tmp = *this; ++*this; return tmp; 
50   }
51   
52   inline _Self& operator--() { --It; return *this; }  // Predecrement
53   inline _Self operator--(int) { // Postdecrement
54     _Self tmp = *this; --*this; return tmp;
55   }
56 };
57
58 typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator;
59 typedef PredIterator<const BasicBlock, 
60                      Value::use_const_iterator> pred_const_iterator;
61
62 inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
63 inline pred_const_iterator pred_begin(const BasicBlock *BB) {
64   return pred_const_iterator(BB);
65 }
66 inline pred_iterator pred_end(BasicBlock *BB) { return pred_iterator(BB, true);}
67 inline pred_const_iterator pred_end(const BasicBlock *BB) {
68   return pred_const_iterator(BB, true);
69 }
70
71
72
73 //===--------------------------------------------------------------------===//
74 // BasicBlock succ_iterator definition
75 //===--------------------------------------------------------------------===//
76
77 template <class _Term, class _BB>           // Successor Iterator
78 class SuccIterator : public bidirectional_iterator<_BB, ptrdiff_t> {
79   const _Term Term;
80   unsigned idx;
81   typedef bidirectional_iterator<_BB, ptrdiff_t> super;
82 public:
83   typedef SuccIterator<_Term, _BB> _Self;
84   typedef typename super::pointer pointer;
85   // TODO: This can be random access iterator, need operator+ and stuff tho
86     
87   inline SuccIterator(_Term T) : Term(T), idx(0) {         // begin iterator
88     assert(T && "getTerminator returned null!");
89   }
90   inline SuccIterator(_Term T, bool)                       // end iterator
91     : Term(T), idx(Term->getNumSuccessors()) {
92     assert(T && "getTerminator returned null!");
93   }
94
95   inline const _Self &operator=(const _Self &I) {
96     assert(Term == I.Term &&"Cannot assign iterators to two different blocks!");
97     idx = I.idx;
98     return *this;
99   }
100     
101   inline bool operator==(const _Self& x) const { return idx == x.idx; }
102   inline bool operator!=(const _Self& x) const { return !operator==(x); }
103   
104   inline pointer operator*() const { return Term->getSuccessor(idx); }
105   inline pointer operator->() const { return operator*(); }
106   
107   inline _Self& operator++() { ++idx; return *this; } // Preincrement
108   inline _Self operator++(int) { // Postincrement
109     _Self tmp = *this; ++*this; return tmp; 
110   }
111     
112   inline _Self& operator--() { --idx; return *this; }  // Predecrement
113   inline _Self operator--(int) { // Postdecrement
114     _Self tmp = *this; --*this; return tmp;
115   }
116 };
117
118 typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator;
119 typedef SuccIterator<const TerminatorInst*,
120                      const BasicBlock> succ_const_iterator;
121
122 inline succ_iterator succ_begin(BasicBlock *BB) {
123   return succ_iterator(BB->getTerminator());
124 }
125 inline succ_const_iterator succ_begin(const BasicBlock *BB) {
126   return succ_const_iterator(BB->getTerminator());
127 }
128 inline succ_iterator succ_end(BasicBlock *BB) {
129   return succ_iterator(BB->getTerminator(), true);
130 }
131 inline succ_const_iterator succ_end(const BasicBlock *BB) {
132   return succ_const_iterator(BB->getTerminator(), true);
133 }
134
135
136
137 //===--------------------------------------------------------------------===//
138 // GraphTraits specializations for basic block graphs (CFGs)
139 //===--------------------------------------------------------------------===//
140
141 // Provide specializations of GraphTraits to be able to treat a function as a 
142 // graph of basic blocks...
143
144 template <> struct GraphTraits<BasicBlock*> {
145   typedef BasicBlock NodeType;
146   typedef succ_iterator ChildIteratorType;
147
148   static NodeType *getEntryNode(BasicBlock *BB) { return BB; }
149   static inline ChildIteratorType child_begin(NodeType *N) { 
150     return succ_begin(N);
151   }
152   static inline ChildIteratorType child_end(NodeType *N) { 
153     return succ_end(N);
154   }
155 };
156
157 template <> struct GraphTraits<const BasicBlock*> {
158   typedef const BasicBlock NodeType;
159   typedef succ_const_iterator ChildIteratorType;
160
161   static NodeType *getEntryNode(const BasicBlock *BB) { return BB; }
162
163   static inline ChildIteratorType child_begin(NodeType *N) { 
164     return succ_begin(N);
165   }
166   static inline ChildIteratorType child_end(NodeType *N) { 
167     return succ_end(N);
168   }
169 };
170
171 // Provide specializations of GraphTraits to be able to treat a function as a 
172 // graph of basic blocks... and to walk it in inverse order.  Inverse order for
173 // a function is considered to be when traversing the predecessor edges of a BB
174 // instead of the successor edges.
175 //
176 template <> struct GraphTraits<Inverse<BasicBlock*> > {
177   typedef BasicBlock NodeType;
178   typedef pred_iterator ChildIteratorType;
179   static NodeType *getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; }
180   static inline ChildIteratorType child_begin(NodeType *N) { 
181     return pred_begin(N);
182   }
183   static inline ChildIteratorType child_end(NodeType *N) { 
184     return pred_end(N);
185   }
186 };
187
188 template <> struct GraphTraits<Inverse<const BasicBlock*> > {
189   typedef const BasicBlock NodeType;
190   typedef pred_const_iterator ChildIteratorType;
191   static NodeType *getEntryNode(Inverse<const BasicBlock*> G) {
192     return G.Graph; 
193   }
194   static inline ChildIteratorType child_begin(NodeType *N) { 
195     return pred_begin(N);
196   }
197   static inline ChildIteratorType child_end(NodeType *N) { 
198     return pred_end(N);
199   }
200 };
201
202
203
204 //===--------------------------------------------------------------------===//
205 // GraphTraits specializations for function basic block graphs (CFGs)
206 //===--------------------------------------------------------------------===//
207
208 // Provide specializations of GraphTraits to be able to treat a function as a 
209 // graph of basic blocks... these are the same as the basic block iterators,
210 // except that the root node is implicitly the first node of the function.
211 //
212 template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
213   static NodeType *getEntryNode(Function *F) { return &F->getEntryNode(); }
214
215   // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
216   typedef Function::iterator nodes_iterator;
217   static nodes_iterator nodes_begin(Function *F) { return F->begin(); }
218   static nodes_iterator nodes_end  (Function *F) { return F->end(); }
219 };
220 template <> struct GraphTraits<const Function*> :
221   public GraphTraits<const BasicBlock*> {
222   static NodeType *getEntryNode(const Function *F) { return &F->getEntryNode();}
223
224   // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
225   typedef Function::const_iterator nodes_iterator;
226   static nodes_iterator nodes_begin(const Function *F) { return F->begin(); }
227   static nodes_iterator nodes_end  (const Function *F) { return F->end(); }
228 };
229
230
231 // Provide specializations of GraphTraits to be able to treat a function as a 
232 // graph of basic blocks... and to walk it in inverse order.  Inverse order for
233 // a function is considered to be when traversing the predecessor edges of a BB
234 // instead of the successor edges.
235 //
236 template <> struct GraphTraits<Inverse<Function*> > :
237   public GraphTraits<Inverse<BasicBlock*> > {
238   static NodeType *getEntryNode(Inverse<Function*> G) {
239     return &G.Graph->getEntryNode();
240   }
241 };
242 template <> struct GraphTraits<Inverse<const Function*> > :
243   public GraphTraits<Inverse<const BasicBlock*> > {
244   static NodeType *getEntryNode(Inverse<const Function *> G) {
245     return &G.Graph->getEntryNode();
246   }
247 };
248
249 #endif