CFG.h revision fe8041ae397ebbcc311469aa39dfb79f8191b412
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
21template <class _Ptr,  class _USE_iterator> // Predecessor Iterator
22class PredIterator : public bidirectional_iterator<_Ptr, ptrdiff_t> {
23  typedef bidirectional_iterator<_Ptr, ptrdiff_t> super;
24  _Ptr *BB;
25  _USE_iterator It;
26public:
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
67typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator;
68typedef PredIterator<const BasicBlock,
69                     Value::use_const_iterator> pred_const_iterator;
70
71inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
72inline pred_const_iterator pred_begin(const BasicBlock *BB) {
73  return pred_const_iterator(BB);
74}
75inline pred_iterator pred_end(BasicBlock *BB) { return pred_iterator(BB, true);}
76inline 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
86template <class _Term, class _BB>           // Successor Iterator
87class SuccIterator : public bidirectional_iterator<_BB, ptrdiff_t> {
88  const _Term Term;
89  unsigned idx;
90  typedef bidirectional_iterator<_BB, ptrdiff_t> super;
91public:
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
121typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator;
122typedef SuccIterator<const TerminatorInst*,
123                     const BasicBlock> succ_const_iterator;
124
125inline succ_iterator succ_begin(BasicBlock *BB) {
126  return succ_iterator(BB->getTerminator());
127}
128inline succ_const_iterator succ_begin(const BasicBlock *BB) {
129  return succ_const_iterator(BB->getTerminator());
130}
131inline succ_iterator succ_end(BasicBlock *BB) {
132  return succ_iterator(BB->getTerminator(), true);
133}
134inline 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
147template <> 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
160template <> 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//
179template <> 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
191template <> 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//
215template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
216  static NodeType *getEntryNode(Function *F) { return &F->getEntryNode(); }
217};
218template <> 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//
229template <> struct GraphTraits<Inverse<Function*> > :
230  public GraphTraits<Inverse<BasicBlock*> > {
231  static NodeType *getEntryNode(Inverse<Function*> G) {
232    return &G.Graph->getEntryNode();
233  }
234};
235template <> 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
243