LLVM API Documentation
00001 //===-- llvm/Support/CFG.h - Process LLVM structures as graphs --*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines specializations of GraphTraits that allow Function and 00011 // BasicBlock graphs to be treated as proper graphs for generic algorithms. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_SUPPORT_CFG_H 00016 #define LLVM_SUPPORT_CFG_H 00017 00018 #include "llvm/ADT/GraphTraits.h" 00019 #include "llvm/Function.h" 00020 #include "llvm/InstrTypes.h" 00021 #include "llvm/ADT/iterator.h" 00022 00023 namespace llvm { 00024 00025 //===--------------------------------------------------------------------===// 00026 // BasicBlock pred_iterator definition 00027 //===--------------------------------------------------------------------===// 00028 00029 template <class _Ptr, class _USE_iterator> // Predecessor Iterator 00030 class PredIterator : public forward_iterator<_Ptr, ptrdiff_t> { 00031 typedef forward_iterator<_Ptr, ptrdiff_t> super; 00032 _USE_iterator It; 00033 public: 00034 typedef PredIterator<_Ptr,_USE_iterator> _Self; 00035 typedef typename super::pointer pointer; 00036 00037 inline void advancePastNonTerminators() { 00038 // Loop to ignore non terminator uses (for example PHI nodes)... 00039 while (!It.atEnd() && !isa<TerminatorInst>(*It)) 00040 ++It; 00041 } 00042 00043 inline PredIterator(_Ptr *bb) : It(bb->use_begin()) { 00044 advancePastNonTerminators(); 00045 } 00046 inline PredIterator(_Ptr *bb, bool) : It(bb->use_end()) {} 00047 00048 inline bool operator==(const _Self& x) const { return It == x.It; } 00049 inline bool operator!=(const _Self& x) const { return !operator==(x); } 00050 00051 inline pointer operator*() const { 00052 assert(!It.atEnd() && "pred_iterator out of range!"); 00053 return cast<TerminatorInst>(*It)->getParent(); 00054 } 00055 inline pointer *operator->() const { return &(operator*()); } 00056 00057 inline _Self& operator++() { // Preincrement 00058 assert(!It.atEnd() && "pred_iterator out of range!"); 00059 ++It; advancePastNonTerminators(); 00060 return *this; 00061 } 00062 00063 inline _Self operator++(int) { // Postincrement 00064 _Self tmp = *this; ++*this; return tmp; 00065 } 00066 }; 00067 00068 typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator; 00069 typedef PredIterator<const BasicBlock, 00070 Value::use_const_iterator> pred_const_iterator; 00071 00072 inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); } 00073 inline pred_const_iterator pred_begin(const BasicBlock *BB) { 00074 return pred_const_iterator(BB); 00075 } 00076 inline pred_iterator pred_end(BasicBlock *BB) { return pred_iterator(BB, true);} 00077 inline pred_const_iterator pred_end(const BasicBlock *BB) { 00078 return pred_const_iterator(BB, true); 00079 } 00080 00081 00082 00083 //===--------------------------------------------------------------------===// 00084 // BasicBlock succ_iterator definition 00085 //===--------------------------------------------------------------------===// 00086 00087 template <class Term_, class BB_> // Successor Iterator 00088 class SuccIterator : public bidirectional_iterator<BB_, ptrdiff_t> { 00089 const Term_ Term; 00090 unsigned idx; 00091 typedef bidirectional_iterator<BB_, ptrdiff_t> super; 00092 public: 00093 typedef SuccIterator<Term_, BB_> _Self; 00094 typedef typename super::pointer pointer; 00095 // TODO: This can be random access iterator, need operator+ and stuff tho 00096 00097 inline SuccIterator(Term_ T) : Term(T), idx(0) { // begin iterator 00098 assert(T && "getTerminator returned null!"); 00099 } 00100 inline SuccIterator(Term_ T, bool) // end iterator 00101 : Term(T), idx(Term->getNumSuccessors()) { 00102 assert(T && "getTerminator returned null!"); 00103 } 00104 00105 inline const _Self &operator=(const _Self &I) { 00106 assert(Term == I.Term &&"Cannot assign iterators to two different blocks!"); 00107 idx = I.idx; 00108 return *this; 00109 } 00110 00111 /// getSuccessorIndex - This is used to interface between code that wants to 00112 /// operate on terminator instructions directly. 00113 unsigned getSuccessorIndex() const { return idx; } 00114 00115 inline bool operator==(const _Self& x) const { return idx == x.idx; } 00116 inline bool operator!=(const _Self& x) const { return !operator==(x); } 00117 00118 inline pointer operator*() const { return Term->getSuccessor(idx); } 00119 inline pointer operator->() const { return operator*(); } 00120 00121 inline _Self& operator++() { ++idx; return *this; } // Preincrement 00122 inline _Self operator++(int) { // Postincrement 00123 _Self tmp = *this; ++*this; return tmp; 00124 } 00125 00126 inline _Self& operator--() { --idx; return *this; } // Predecrement 00127 inline _Self operator--(int) { // Postdecrement 00128 _Self tmp = *this; --*this; return tmp; 00129 } 00130 }; 00131 00132 typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator; 00133 typedef SuccIterator<const TerminatorInst*, 00134 const BasicBlock> succ_const_iterator; 00135 00136 inline succ_iterator succ_begin(BasicBlock *BB) { 00137 return succ_iterator(BB->getTerminator()); 00138 } 00139 inline succ_const_iterator succ_begin(const BasicBlock *BB) { 00140 return succ_const_iterator(BB->getTerminator()); 00141 } 00142 inline succ_iterator succ_end(BasicBlock *BB) { 00143 return succ_iterator(BB->getTerminator(), true); 00144 } 00145 inline succ_const_iterator succ_end(const BasicBlock *BB) { 00146 return succ_const_iterator(BB->getTerminator(), true); 00147 } 00148 00149 00150 00151 //===--------------------------------------------------------------------===// 00152 // GraphTraits specializations for basic block graphs (CFGs) 00153 //===--------------------------------------------------------------------===// 00154 00155 // Provide specializations of GraphTraits to be able to treat a function as a 00156 // graph of basic blocks... 00157 00158 template <> struct GraphTraits<BasicBlock*> { 00159 typedef BasicBlock NodeType; 00160 typedef succ_iterator ChildIteratorType; 00161 00162 static NodeType *getEntryNode(BasicBlock *BB) { return BB; } 00163 static inline ChildIteratorType child_begin(NodeType *N) { 00164 return succ_begin(N); 00165 } 00166 static inline ChildIteratorType child_end(NodeType *N) { 00167 return succ_end(N); 00168 } 00169 }; 00170 00171 template <> struct GraphTraits<const BasicBlock*> { 00172 typedef const BasicBlock NodeType; 00173 typedef succ_const_iterator ChildIteratorType; 00174 00175 static NodeType *getEntryNode(const BasicBlock *BB) { return BB; } 00176 00177 static inline ChildIteratorType child_begin(NodeType *N) { 00178 return succ_begin(N); 00179 } 00180 static inline ChildIteratorType child_end(NodeType *N) { 00181 return succ_end(N); 00182 } 00183 }; 00184 00185 // Provide specializations of GraphTraits to be able to treat a function as a 00186 // graph of basic blocks... and to walk it in inverse order. Inverse order for 00187 // a function is considered to be when traversing the predecessor edges of a BB 00188 // instead of the successor edges. 00189 // 00190 template <> struct GraphTraits<Inverse<BasicBlock*> > { 00191 typedef BasicBlock NodeType; 00192 typedef pred_iterator ChildIteratorType; 00193 static NodeType *getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; } 00194 static inline ChildIteratorType child_begin(NodeType *N) { 00195 return pred_begin(N); 00196 } 00197 static inline ChildIteratorType child_end(NodeType *N) { 00198 return pred_end(N); 00199 } 00200 }; 00201 00202 template <> struct GraphTraits<Inverse<const BasicBlock*> > { 00203 typedef const BasicBlock NodeType; 00204 typedef pred_const_iterator ChildIteratorType; 00205 static NodeType *getEntryNode(Inverse<const BasicBlock*> G) { 00206 return G.Graph; 00207 } 00208 static inline ChildIteratorType child_begin(NodeType *N) { 00209 return pred_begin(N); 00210 } 00211 static inline ChildIteratorType child_end(NodeType *N) { 00212 return pred_end(N); 00213 } 00214 }; 00215 00216 00217 00218 //===--------------------------------------------------------------------===// 00219 // GraphTraits specializations for function basic block graphs (CFGs) 00220 //===--------------------------------------------------------------------===// 00221 00222 // Provide specializations of GraphTraits to be able to treat a function as a 00223 // graph of basic blocks... these are the same as the basic block iterators, 00224 // except that the root node is implicitly the first node of the function. 00225 // 00226 template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> { 00227 static NodeType *getEntryNode(Function *F) { return &F->getEntryBlock(); } 00228 00229 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph 00230 typedef Function::iterator nodes_iterator; 00231 static nodes_iterator nodes_begin(Function *F) { return F->begin(); } 00232 static nodes_iterator nodes_end (Function *F) { return F->end(); } 00233 }; 00234 template <> struct GraphTraits<const Function*> : 00235 public GraphTraits<const BasicBlock*> { 00236 static NodeType *getEntryNode(const Function *F) {return &F->getEntryBlock();} 00237 00238 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph 00239 typedef Function::const_iterator nodes_iterator; 00240 static nodes_iterator nodes_begin(const Function *F) { return F->begin(); } 00241 static nodes_iterator nodes_end (const Function *F) { return F->end(); } 00242 }; 00243 00244 00245 // Provide specializations of GraphTraits to be able to treat a function as a 00246 // graph of basic blocks... and to walk it in inverse order. Inverse order for 00247 // a function is considered to be when traversing the predecessor edges of a BB 00248 // instead of the successor edges. 00249 // 00250 template <> struct GraphTraits<Inverse<Function*> > : 00251 public GraphTraits<Inverse<BasicBlock*> > { 00252 static NodeType *getEntryNode(Inverse<Function*> G) { 00253 return &G.Graph->getEntryBlock(); 00254 } 00255 }; 00256 template <> struct GraphTraits<Inverse<const Function*> > : 00257 public GraphTraits<Inverse<const BasicBlock*> > { 00258 static NodeType *getEntryNode(Inverse<const Function *> G) { 00259 return &G.Graph->getEntryBlock(); 00260 } 00261 }; 00262 00263 } // End llvm namespace 00264 00265 #endif