1 //===-- llvm/Support/CFG.h - Process LLVM structures as graphs --*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines specializations of GraphTraits that allow Function and
11 // BasicBlock graphs to be treated as proper graphs for generic algorithms.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_SUPPORT_CFG_H
16 #define LLVM_SUPPORT_CFG_H
18 #include "llvm/ADT/GraphTraits.h"
19 #include "llvm/Function.h"
20 #include "llvm/InstrTypes.h"
21 #include "llvm/ADT/iterator"
25 //===--------------------------------------------------------------------===//
26 // BasicBlock pred_iterator definition
27 //===--------------------------------------------------------------------===//
29 template <class _Ptr, class _USE_iterator> // Predecessor Iterator
30 class PredIterator : public forward_iterator<_Ptr, ptrdiff_t> {
31 typedef forward_iterator<_Ptr, ptrdiff_t> super;
34 typedef PredIterator<_Ptr,_USE_iterator> _Self;
35 typedef typename super::pointer pointer;
37 inline void advancePastNonPreds() {
38 // Loop to ignore non predecessor uses (for example PHI nodes)...
40 if (isa<TerminatorInst>(*It) || isa<BasicBlock>(*It))
46 inline PredIterator(_Ptr *bb) : It(bb->use_begin()) {
47 advancePastNonPreds();
49 inline PredIterator(_Ptr *bb, bool) : It(bb->use_end()) {}
51 inline bool operator==(const _Self& x) const { return It == x.It; }
52 inline bool operator!=(const _Self& x) const { return !operator==(x); }
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();
59 return cast<_Ptr>(*It);
61 inline pointer *operator->() const { return &(operator*()); }
63 inline _Self& operator++() { // Preincrement
64 assert(!It.atEnd() && "pred_iterator out of range!");
65 ++It; advancePastNonPreds();
69 inline _Self operator++(int) { // Postincrement
70 _Self tmp = *this; ++*this; return tmp;
74 typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator;
75 typedef PredIterator<const BasicBlock,
76 Value::use_const_iterator> pred_const_iterator;
78 inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
79 inline pred_const_iterator pred_begin(const BasicBlock *BB) {
80 return pred_const_iterator(BB);
82 inline pred_iterator pred_end(BasicBlock *BB) { return pred_iterator(BB, true);}
83 inline pred_const_iterator pred_end(const BasicBlock *BB) {
84 return pred_const_iterator(BB, true);
89 //===--------------------------------------------------------------------===//
90 // BasicBlock succ_iterator definition
91 //===--------------------------------------------------------------------===//
93 template <class Term_, class BB_> // Successor Iterator
94 class SuccIterator : public bidirectional_iterator<BB_, ptrdiff_t> {
97 typedef bidirectional_iterator<BB_, ptrdiff_t> super;
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
103 inline SuccIterator(Term_ T) : Term(T), idx(0) { // begin iterator
104 assert(T && "getTerminator returned null!");
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())
113 inline const _Self &operator=(const _Self &I) {
114 assert(Term == I.Term &&"Cannot assign iterators to two different blocks!");
119 /// getSuccessorIndex - This is used to interface between code that wants to
120 /// operate on terminator instructions directly.
121 unsigned getSuccessorIndex() const { return idx; }
123 inline bool operator==(const _Self& x) const { return idx == x.idx; }
124 inline bool operator!=(const _Self& x) const { return !operator==(x); }
126 inline pointer operator*() const {
127 if (idx == Term->getNumSuccessors())
128 return Term->getParent()->getUnwindDest();
130 return Term->getSuccessor(idx);
132 inline pointer operator->() const { return operator*(); }
134 inline _Self& operator++() { ++idx; return *this; } // Preincrement
135 inline _Self operator++(int) { // Postincrement
136 _Self tmp = *this; ++*this; return tmp;
139 inline _Self& operator--() { --idx; return *this; } // Predecrement
140 inline _Self operator--(int) { // Postdecrement
141 _Self tmp = *this; --*this; return tmp;
145 typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator;
146 typedef SuccIterator<const TerminatorInst*,
147 const BasicBlock> succ_const_iterator;
149 inline succ_iterator succ_begin(BasicBlock *BB) {
150 return succ_iterator(BB->getTerminator());
152 inline succ_const_iterator succ_begin(const BasicBlock *BB) {
153 return succ_const_iterator(BB->getTerminator());
155 inline succ_iterator succ_end(BasicBlock *BB) {
156 return succ_iterator(BB->getTerminator(), true);
158 inline succ_const_iterator succ_end(const BasicBlock *BB) {
159 return succ_const_iterator(BB->getTerminator(), true);
164 //===--------------------------------------------------------------------===//
165 // GraphTraits specializations for basic block graphs (CFGs)
166 //===--------------------------------------------------------------------===//
168 // Provide specializations of GraphTraits to be able to treat a function as a
169 // graph of basic blocks...
171 template <> struct GraphTraits<BasicBlock*> {
172 typedef BasicBlock NodeType;
173 typedef succ_iterator ChildIteratorType;
175 static NodeType *getEntryNode(BasicBlock *BB) { return BB; }
176 static inline ChildIteratorType child_begin(NodeType *N) {
177 return succ_begin(N);
179 static inline ChildIteratorType child_end(NodeType *N) {
184 template <> struct GraphTraits<const BasicBlock*> {
185 typedef const BasicBlock NodeType;
186 typedef succ_const_iterator ChildIteratorType;
188 static NodeType *getEntryNode(const BasicBlock *BB) { return BB; }
190 static inline ChildIteratorType child_begin(NodeType *N) {
191 return succ_begin(N);
193 static inline ChildIteratorType child_end(NodeType *N) {
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.
203 template <> 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);
210 static inline ChildIteratorType child_end(NodeType *N) {
215 template <> struct GraphTraits<Inverse<const BasicBlock*> > {
216 typedef const BasicBlock NodeType;
217 typedef pred_const_iterator ChildIteratorType;
218 static NodeType *getEntryNode(Inverse<const BasicBlock*> G) {
221 static inline ChildIteratorType child_begin(NodeType *N) {
222 return pred_begin(N);
224 static inline ChildIteratorType child_end(NodeType *N) {
231 //===--------------------------------------------------------------------===//
232 // GraphTraits specializations for function basic block graphs (CFGs)
233 //===--------------------------------------------------------------------===//
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.
239 template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
240 static NodeType *getEntryNode(Function *F) { return &F->getEntryBlock(); }
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(); }
247 template <> struct GraphTraits<const Function*> :
248 public GraphTraits<const BasicBlock*> {
249 static NodeType *getEntryNode(const Function *F) {return &F->getEntryBlock();}
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(); }
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.
263 template <> struct GraphTraits<Inverse<Function*> > :
264 public GraphTraits<Inverse<BasicBlock*> > {
265 static NodeType *getEntryNode(Inverse<Function*> G) {
266 return &G.Graph->getEntryBlock();
269 template <> struct GraphTraits<Inverse<const Function*> > :
270 public GraphTraits<Inverse<const BasicBlock*> > {
271 static NodeType *getEntryNode(Inverse<const Function *> G) {
272 return &G.Graph->getEntryBlock();
276 } // End llvm namespace