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