0e48ef506ad9aa31a5079fe5d5ab6c4949843652
[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/BasicBlock.h"
14 #include "llvm/InstrTypes.h"
15 #include "Support/iterator"
16
17 //===--------------------------------------------------------------------===//
18 // BasicBlock pred_iterator definition
19 //===--------------------------------------------------------------------===//
20
21 template <class _Ptr,  class _USE_iterator> // Predecessor Iterator
22 class PredIterator : public bidirectional_iterator<_Ptr, ptrdiff_t> {
23   typedef bidirectional_iterator<_Ptr, ptrdiff_t> super;
24   _Ptr *BB;
25   _USE_iterator It;
26 public:
27   typedef PredIterator<_Ptr,_USE_iterator> _Self;
28   typedef typename super::pointer pointer;
29   
30   inline void advancePastConstants() {
31     // TODO: This is bad
32     // Loop to ignore constant pool references
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<Instruction>(*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   }
108     
109   inline bool operator==(const _Self& x) const { return idx == x.idx; }
110   inline bool operator!=(const _Self& x) const { return !operator==(x); }
111   
112   inline pointer operator*() const { return Term->getSuccessor(idx); }
113   inline pointer operator->() const { return operator*(); }
114   
115   inline _Self& operator++() { ++idx; return *this; } // Preincrement
116   inline _Self operator++(int) { // Postincrement
117     _Self tmp = *this; ++*this; return tmp; 
118   }
119     
120   inline _Self& operator--() { --idx; return *this; }  // Predecrement
121   inline _Self operator--(int) { // Postdecrement
122     _Self tmp = *this; --*this; return tmp;
123   }
124 };
125
126 typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator;
127 typedef SuccIterator<const TerminatorInst*,
128                      const BasicBlock> succ_const_iterator;
129
130 inline succ_iterator succ_begin(BasicBlock *BB) {
131   return succ_iterator(BB->getTerminator());
132 }
133 inline succ_const_iterator succ_begin(const BasicBlock *BB) {
134   return succ_const_iterator(BB->getTerminator());
135 }
136 inline succ_iterator succ_end(BasicBlock *BB) {
137   return succ_iterator(BB->getTerminator(), true);
138 }
139 inline succ_const_iterator succ_end(const BasicBlock *BB) {
140   return succ_const_iterator(BB->getTerminator(), true);
141 }
142
143
144
145 //===--------------------------------------------------------------------===//
146 // GraphTraits specializations for basic block graphs (CFGs)
147 //===--------------------------------------------------------------------===//
148
149 // Provide specializations of GraphTraits to be able to treat a function as a 
150 // graph of basic blocks...
151
152 template <> struct GraphTraits<BasicBlock*> {
153   typedef BasicBlock NodeType;
154   typedef succ_iterator ChildIteratorType;
155
156   static NodeType *getEntryNode(BasicBlock *BB) { return BB; }
157   static inline ChildIteratorType child_begin(NodeType *N) { 
158     return succ_begin(N);
159   }
160   static inline ChildIteratorType child_end(NodeType *N) { 
161     return succ_end(N);
162   }
163 };
164
165 template <> struct GraphTraits<const BasicBlock*> {
166   typedef const BasicBlock NodeType;
167   typedef succ_const_iterator ChildIteratorType;
168
169   static NodeType *getEntryNode(const BasicBlock *BB) { return BB; }
170
171   static inline ChildIteratorType child_begin(NodeType *N) { 
172     return succ_begin(N);
173   }
174   static inline ChildIteratorType child_end(NodeType *N) { 
175     return succ_end(N);
176   }
177 };
178
179 // Provide specializations of GraphTraits to be able to treat a function as a 
180 // graph of basic blocks... and to walk it in inverse order.  Inverse order for
181 // a function is considered to be when traversing the predecessor edges of a BB
182 // instead of the successor edges.
183 //
184 template <> struct GraphTraits<Inverse<BasicBlock*> > {
185   typedef BasicBlock NodeType;
186   typedef pred_iterator ChildIteratorType;
187   static NodeType *getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; }
188   static inline ChildIteratorType child_begin(NodeType *N) { 
189     return pred_begin(N);
190   }
191   static inline ChildIteratorType child_end(NodeType *N) { 
192     return pred_end(N);
193   }
194 };
195
196 template <> struct GraphTraits<Inverse<const BasicBlock*> > {
197   typedef const BasicBlock NodeType;
198   typedef pred_const_iterator ChildIteratorType;
199   static NodeType *getEntryNode(Inverse<const BasicBlock*> G) {
200     return G.Graph; 
201   }
202   static inline ChildIteratorType child_begin(NodeType *N) { 
203     return pred_begin(N);
204   }
205   static inline ChildIteratorType child_end(NodeType *N) { 
206     return pred_end(N);
207   }
208 };
209
210
211
212 //===--------------------------------------------------------------------===//
213 // GraphTraits specializations for function basic block graphs (CFGs)
214 //===--------------------------------------------------------------------===//
215
216 // Provide specializations of GraphTraits to be able to treat a function as a 
217 // graph of basic blocks... these are the same as the basic block iterators,
218 // except that the root node is implicitly the first node of the function.
219 //
220 template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
221   static NodeType *getEntryNode(Function *F) { return &F->getEntryNode(); }
222 };
223 template <> struct GraphTraits<const Function*> :
224   public GraphTraits<const BasicBlock*> {
225   static NodeType *getEntryNode(const Function *F) { return &F->getEntryNode();}
226 };
227
228
229 // Provide specializations of GraphTraits to be able to treat a function as a 
230 // graph of basic blocks... and to walk it in inverse order.  Inverse order for
231 // a function is considered to be when traversing the predecessor edges of a BB
232 // instead of the successor edges.
233 //
234 template <> struct GraphTraits<Inverse<Function*> > :
235   public GraphTraits<Inverse<BasicBlock*> > {
236   static NodeType *getEntryNode(Inverse<Function*> G) {
237     return &G.Graph->getEntryNode();
238   }
239 };
240 template <> struct GraphTraits<Inverse<const Function*> > :
241   public GraphTraits<Inverse<const BasicBlock*> > {
242   static NodeType *getEntryNode(Inverse<const Function *> G) {
243     return &G.Graph->getEntryNode();
244   }
245 };
246
247 #endif