Add facility to compute peak memory usage
[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 void advancePastConstants() {
30     // TODO: This is bad
31     // Loop to ignore constant pool references
32     while (It != BB->use_end() && !isa<TerminatorInst>(*It))
33       ++It;
34   }
35   
36   inline PredIterator(_Ptr *bb) : BB(bb), It(bb->use_begin()) {
37     advancePastConstants();
38   }
39   inline PredIterator(_Ptr *bb, bool) : BB(bb), It(bb->use_end()) {}
40     
41   inline bool operator==(const _Self& x) const { return It == x.It; }
42   inline bool operator!=(const _Self& x) const { return !operator==(x); }
43   
44   inline pointer operator*() const { 
45     assert(It != BB->use_end() && "pred_iterator out of range!");
46     return cast<Instruction>(*It)->getParent(); 
47   }
48   inline pointer *operator->() const { return &(operator*()); }
49   
50   inline _Self& operator++() {   // Preincrement
51     assert(It != BB->use_end() && "pred_iterator out of range!");
52     ++It; advancePastConstants();
53     return *this; 
54   }
55   
56   inline _Self operator++(int) { // Postincrement
57     _Self tmp = *this; ++*this; return tmp; 
58   }
59   
60   inline _Self& operator--() { --It; return *this; }  // Predecrement
61   inline _Self operator--(int) { // Postdecrement
62     _Self tmp = *this; --*this; return tmp;
63   }
64 };
65
66 typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator;
67 typedef PredIterator<const BasicBlock, 
68                      Value::use_const_iterator> pred_const_iterator;
69
70 inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
71 inline pred_const_iterator pred_begin(const BasicBlock *BB) {
72   return pred_const_iterator(BB);
73 }
74 inline pred_iterator pred_end(BasicBlock *BB) { return pred_iterator(BB, true);}
75 inline pred_const_iterator pred_end(const BasicBlock *BB) {
76   return pred_const_iterator(BB, true);
77 }
78
79
80
81 //===--------------------------------------------------------------------===//
82 // BasicBlock succ_iterator definition
83 //===--------------------------------------------------------------------===//
84
85 template <class _Term, class _BB>           // Successor Iterator
86 class SuccIterator : public bidirectional_iterator<_BB, ptrdiff_t> {
87   const _Term Term;
88   unsigned idx;
89   typedef bidirectional_iterator<_BB, ptrdiff_t> super;
90 public:
91   typedef SuccIterator<_Term, _BB> _Self;
92   typedef typename super::pointer pointer;
93   // TODO: This can be random access iterator, need operator+ and stuff tho
94     
95   inline SuccIterator(_Term T) : Term(T), idx(0) {         // begin iterator
96     assert(T && "getTerminator returned null!");
97   }
98   inline SuccIterator(_Term T, bool)                       // end iterator
99     : Term(T), idx(Term->getNumSuccessors()) {
100     assert(T && "getTerminator returned null!");
101   }
102
103   inline const _Self &operator=(const _Self &I) {
104     assert(Term == I.Term &&"Cannot assign iterators to two different blocks!");
105     idx = I.idx;
106     return *this;
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   // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
224   typedef Function::iterator nodes_iterator;
225   static nodes_iterator nodes_begin(Function *F) { return F->begin(); }
226   static nodes_iterator nodes_end  (Function *F) { return F->end(); }
227 };
228 template <> struct GraphTraits<const Function*> :
229   public GraphTraits<const BasicBlock*> {
230   static NodeType *getEntryNode(const Function *F) { return &F->getEntryNode();}
231
232   // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
233   typedef Function::const_iterator nodes_iterator;
234   static nodes_iterator nodes_begin(const Function *F) { return F->begin(); }
235   static nodes_iterator nodes_end  (const Function *F) { return F->end(); }
236 };
237
238
239 // Provide specializations of GraphTraits to be able to treat a function as a 
240 // graph of basic blocks... and to walk it in inverse order.  Inverse order for
241 // a function is considered to be when traversing the predecessor edges of a BB
242 // instead of the successor edges.
243 //
244 template <> struct GraphTraits<Inverse<Function*> > :
245   public GraphTraits<Inverse<BasicBlock*> > {
246   static NodeType *getEntryNode(Inverse<Function*> G) {
247     return &G.Graph->getEntryNode();
248   }
249 };
250 template <> struct GraphTraits<Inverse<const Function*> > :
251   public GraphTraits<Inverse<const BasicBlock*> > {
252   static NodeType *getEntryNode(Inverse<const Function *> G) {
253     return &G.Graph->getEntryNode();
254   }
255 };
256
257 #endif