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