LLVM API Documentation

CFG.h

Go to the documentation of this file.
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