CFG.h revision 4bf393a13e779d7a8eac3647df1781068a6dc732
1//===-- llvm/Support/CFG.h - Process LLVM structures as graphs --*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines specializations of GraphTraits that allow Function and
11// BasicBlock graphs to be treated as proper graphs for generic algorithms.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_SUPPORT_CFG_H
16#define LLVM_SUPPORT_CFG_H
17
18#include "llvm/ADT/GraphTraits.h"
19#include "llvm/Function.h"
20#include "llvm/InstrTypes.h"
21#include "llvm/ADT/iterator"
22
23namespace llvm {
24
25//===--------------------------------------------------------------------===//
26// BasicBlock pred_iterator definition
27//===--------------------------------------------------------------------===//
28
29template <class _Ptr,  class _USE_iterator> // Predecessor Iterator
30class PredIterator : public forward_iterator<_Ptr, ptrdiff_t> {
31  typedef forward_iterator<_Ptr, ptrdiff_t> super;
32  _USE_iterator It;
33public:
34  typedef PredIterator<_Ptr,_USE_iterator> _Self;
35  typedef typename super::pointer pointer;
36
37  inline void advancePastNonPreds() {
38    // Loop to ignore non predecessor uses (for example PHI nodes)...
39    while (!It.atEnd()) {
40      if (isa<TerminatorInst>(*It) || isa<BasicBlock>(*It))
41	break;
42      ++It;
43    }
44  }
45
46  inline PredIterator(_Ptr *bb) : It(bb->use_begin()) {
47    advancePastNonPreds();
48  }
49  inline PredIterator(_Ptr *bb, bool) : It(bb->use_end()) {}
50
51  inline bool operator==(const _Self& x) const { return It == x.It; }
52  inline bool operator!=(const _Self& x) const { return !operator==(x); }
53
54  inline pointer operator*() const {
55    assert(!It.atEnd() && "pred_iterator out of range!");
56    if (isa<TerminatorInst>(*It))      // not dyn_cast due to const-correctness
57      return cast<TerminatorInst>(*It)->getParent();
58
59    return cast<_Ptr>(*It);
60  }
61  inline pointer *operator->() const { return &(operator*()); }
62
63  inline _Self& operator++() {   // Preincrement
64    assert(!It.atEnd() && "pred_iterator out of range!");
65    ++It; advancePastNonPreds();
66    return *this;
67  }
68
69  inline _Self operator++(int) { // Postincrement
70    _Self tmp = *this; ++*this; return tmp;
71  }
72};
73
74typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator;
75typedef PredIterator<const BasicBlock,
76                     Value::use_const_iterator> pred_const_iterator;
77
78inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
79inline pred_const_iterator pred_begin(const BasicBlock *BB) {
80  return pred_const_iterator(BB);
81}
82inline pred_iterator pred_end(BasicBlock *BB) { return pred_iterator(BB, true);}
83inline pred_const_iterator pred_end(const BasicBlock *BB) {
84  return pred_const_iterator(BB, true);
85}
86
87
88
89//===--------------------------------------------------------------------===//
90// BasicBlock succ_iterator definition
91//===--------------------------------------------------------------------===//
92
93template <class Term_, class BB_>           // Successor Iterator
94class SuccIterator : public bidirectional_iterator<BB_, ptrdiff_t> {
95  const Term_ Term;
96  unsigned idx;
97  typedef bidirectional_iterator<BB_, ptrdiff_t> super;
98public:
99  typedef SuccIterator<Term_, BB_> _Self;
100  typedef typename super::pointer pointer;
101  // TODO: This can be random access iterator, need operator+ and stuff tho
102
103  inline SuccIterator(Term_ T) : Term(T), idx(0) {         // begin iterator
104    assert(T && "getTerminator returned null!");
105  }
106  inline SuccIterator(Term_ T, bool)                       // end iterator
107    : Term(T), idx(Term->getNumSuccessors()) {
108    assert(T && "getTerminator returned null!");
109    if (Term->getParent()->getUnwindDest())
110      ++idx;
111  }
112
113  inline const _Self &operator=(const _Self &I) {
114    assert(Term == I.Term &&"Cannot assign iterators to two different blocks!");
115    idx = I.idx;
116    return *this;
117  }
118
119  /// getSuccessorIndex - This is used to interface between code that wants to
120  /// operate on terminator instructions directly.
121  unsigned getSuccessorIndex() const { return idx; }
122
123  inline bool operator==(const _Self& x) const { return idx == x.idx; }
124  inline bool operator!=(const _Self& x) const { return !operator==(x); }
125
126  inline pointer operator*() const {
127    if (idx == Term->getNumSuccessors())
128      return Term->getParent()->getUnwindDest();
129
130    return Term->getSuccessor(idx);
131  }
132  inline pointer operator->() const { return operator*(); }
133
134  inline _Self& operator++() { ++idx; return *this; } // Preincrement
135  inline _Self operator++(int) { // Postincrement
136    _Self tmp = *this; ++*this; return tmp;
137  }
138
139  inline _Self& operator--() { --idx; return *this; }  // Predecrement
140  inline _Self operator--(int) { // Postdecrement
141    _Self tmp = *this; --*this; return tmp;
142  }
143};
144
145typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator;
146typedef SuccIterator<const TerminatorInst*,
147                     const BasicBlock> succ_const_iterator;
148
149inline succ_iterator succ_begin(BasicBlock *BB) {
150  return succ_iterator(BB->getTerminator());
151}
152inline succ_const_iterator succ_begin(const BasicBlock *BB) {
153  return succ_const_iterator(BB->getTerminator());
154}
155inline succ_iterator succ_end(BasicBlock *BB) {
156  return succ_iterator(BB->getTerminator(), true);
157}
158inline succ_const_iterator succ_end(const BasicBlock *BB) {
159  return succ_const_iterator(BB->getTerminator(), true);
160}
161
162
163
164//===--------------------------------------------------------------------===//
165// GraphTraits specializations for basic block graphs (CFGs)
166//===--------------------------------------------------------------------===//
167
168// Provide specializations of GraphTraits to be able to treat a function as a
169// graph of basic blocks...
170
171template <> struct GraphTraits<BasicBlock*> {
172  typedef BasicBlock NodeType;
173  typedef succ_iterator ChildIteratorType;
174
175  static NodeType *getEntryNode(BasicBlock *BB) { return BB; }
176  static inline ChildIteratorType child_begin(NodeType *N) {
177    return succ_begin(N);
178  }
179  static inline ChildIteratorType child_end(NodeType *N) {
180    return succ_end(N);
181  }
182};
183
184template <> struct GraphTraits<const BasicBlock*> {
185  typedef const BasicBlock NodeType;
186  typedef succ_const_iterator ChildIteratorType;
187
188  static NodeType *getEntryNode(const BasicBlock *BB) { return BB; }
189
190  static inline ChildIteratorType child_begin(NodeType *N) {
191    return succ_begin(N);
192  }
193  static inline ChildIteratorType child_end(NodeType *N) {
194    return succ_end(N);
195  }
196};
197
198// Provide specializations of GraphTraits to be able to treat a function as a
199// graph of basic blocks... and to walk it in inverse order.  Inverse order for
200// a function is considered to be when traversing the predecessor edges of a BB
201// instead of the successor edges.
202//
203template <> struct GraphTraits<Inverse<BasicBlock*> > {
204  typedef BasicBlock NodeType;
205  typedef pred_iterator ChildIteratorType;
206  static NodeType *getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; }
207  static inline ChildIteratorType child_begin(NodeType *N) {
208    return pred_begin(N);
209  }
210  static inline ChildIteratorType child_end(NodeType *N) {
211    return pred_end(N);
212  }
213};
214
215template <> struct GraphTraits<Inverse<const BasicBlock*> > {
216  typedef const BasicBlock NodeType;
217  typedef pred_const_iterator ChildIteratorType;
218  static NodeType *getEntryNode(Inverse<const BasicBlock*> G) {
219    return G.Graph;
220  }
221  static inline ChildIteratorType child_begin(NodeType *N) {
222    return pred_begin(N);
223  }
224  static inline ChildIteratorType child_end(NodeType *N) {
225    return pred_end(N);
226  }
227};
228
229
230
231//===--------------------------------------------------------------------===//
232// GraphTraits specializations for function basic block graphs (CFGs)
233//===--------------------------------------------------------------------===//
234
235// Provide specializations of GraphTraits to be able to treat a function as a
236// graph of basic blocks... these are the same as the basic block iterators,
237// except that the root node is implicitly the first node of the function.
238//
239template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
240  static NodeType *getEntryNode(Function *F) { return &F->getEntryBlock(); }
241
242  // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
243  typedef Function::iterator nodes_iterator;
244  static nodes_iterator nodes_begin(Function *F) { return F->begin(); }
245  static nodes_iterator nodes_end  (Function *F) { return F->end(); }
246};
247template <> struct GraphTraits<const Function*> :
248  public GraphTraits<const BasicBlock*> {
249  static NodeType *getEntryNode(const Function *F) {return &F->getEntryBlock();}
250
251  // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
252  typedef Function::const_iterator nodes_iterator;
253  static nodes_iterator nodes_begin(const Function *F) { return F->begin(); }
254  static nodes_iterator nodes_end  (const Function *F) { return F->end(); }
255};
256
257
258// Provide specializations of GraphTraits to be able to treat a function as a
259// graph of basic blocks... and to walk it in inverse order.  Inverse order for
260// a function is considered to be when traversing the predecessor edges of a BB
261// instead of the successor edges.
262//
263template <> struct GraphTraits<Inverse<Function*> > :
264  public GraphTraits<Inverse<BasicBlock*> > {
265  static NodeType *getEntryNode(Inverse<Function*> G) {
266    return &G.Graph->getEntryBlock();
267  }
268};
269template <> struct GraphTraits<Inverse<const Function*> > :
270  public GraphTraits<Inverse<const BasicBlock*> > {
271  static NodeType *getEntryNode(Inverse<const Function *> G) {
272    return &G.Graph->getEntryBlock();
273  }
274};
275
276} // End llvm namespace
277
278#endif
279