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