LLVM API Documentation

IR/CFG.h
Go to the documentation of this file.
00001 //===- 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_IR_CFG_H
00016 #define LLVM_IR_CFG_H
00017 
00018 #include "llvm/ADT/GraphTraits.h"
00019 #include "llvm/IR/Function.h"
00020 #include "llvm/IR/InstrTypes.h"
00021 
00022 namespace llvm {
00023 
00024 //===----------------------------------------------------------------------===//
00025 // BasicBlock pred_iterator definition
00026 //===----------------------------------------------------------------------===//
00027 
00028 template <class Ptr, class USE_iterator> // Predecessor Iterator
00029 class PredIterator : public std::iterator<std::forward_iterator_tag,
00030                                           Ptr, ptrdiff_t, Ptr*, Ptr*> {
00031   typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t, Ptr*,
00032                                                                     Ptr*> super;
00033   typedef PredIterator<Ptr, USE_iterator> Self;
00034   USE_iterator It;
00035 
00036   inline void advancePastNonTerminators() {
00037     // Loop to ignore non-terminator uses (for example BlockAddresses).
00038     while (!It.atEnd() && !isa<TerminatorInst>(*It))
00039       ++It;
00040   }
00041 
00042 public:
00043   typedef typename super::pointer pointer;
00044   typedef typename super::reference reference;
00045 
00046   PredIterator() {}
00047   explicit inline PredIterator(Ptr *bb) : It(bb->user_begin()) {
00048     advancePastNonTerminators();
00049   }
00050   inline PredIterator(Ptr *bb, bool) : It(bb->user_end()) {}
00051 
00052   inline bool operator==(const Self& x) const { return It == x.It; }
00053   inline bool operator!=(const Self& x) const { return !operator==(x); }
00054 
00055   inline reference operator*() const {
00056     assert(!It.atEnd() && "pred_iterator out of range!");
00057     return cast<TerminatorInst>(*It)->getParent();
00058   }
00059   inline pointer *operator->() const { return &operator*(); }
00060 
00061   inline Self& operator++() {   // Preincrement
00062     assert(!It.atEnd() && "pred_iterator out of range!");
00063     ++It; advancePastNonTerminators();
00064     return *this;
00065   }
00066 
00067   inline Self operator++(int) { // Postincrement
00068     Self tmp = *this; ++*this; return tmp;
00069   }
00070 
00071   /// getOperandNo - Return the operand number in the predecessor's
00072   /// terminator of the successor.
00073   unsigned getOperandNo() const {
00074     return It.getOperandNo();
00075   }
00076 
00077   /// getUse - Return the operand Use in the predecessor's terminator
00078   /// of the successor.
00079   Use &getUse() const {
00080     return It.getUse();
00081   }
00082 };
00083 
00084 typedef PredIterator<BasicBlock, Value::user_iterator> pred_iterator;
00085 typedef PredIterator<const BasicBlock,
00086                      Value::const_user_iterator> const_pred_iterator;
00087 
00088 inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
00089 inline const_pred_iterator pred_begin(const BasicBlock *BB) {
00090   return const_pred_iterator(BB);
00091 }
00092 inline pred_iterator pred_end(BasicBlock *BB) { return pred_iterator(BB, true);}
00093 inline const_pred_iterator pred_end(const BasicBlock *BB) {
00094   return const_pred_iterator(BB, true);
00095 }
00096 
00097 
00098 
00099 //===----------------------------------------------------------------------===//
00100 // BasicBlock succ_iterator definition
00101 //===----------------------------------------------------------------------===//
00102 
00103 template <class Term_, class BB_>           // Successor Iterator
00104 class SuccIterator : public std::iterator<std::random_access_iterator_tag, BB_,
00105                                           int, BB_ *, BB_ *> {
00106   typedef std::iterator<std::random_access_iterator_tag, BB_, int, BB_ *, BB_ *>
00107   super;
00108 
00109 public:
00110   typedef typename super::pointer pointer;
00111   typedef typename super::reference reference;
00112 
00113 private:
00114   const Term_ Term;
00115   unsigned idx;
00116   typedef SuccIterator<Term_, BB_> Self;
00117 
00118   inline bool index_is_valid(int idx) {
00119     return idx >= 0 && (unsigned) idx < Term->getNumSuccessors();
00120   }
00121 
00122   /// \brief Proxy object to allow write access in operator[]
00123   class SuccessorProxy {
00124     Self it;
00125 
00126   public:
00127     explicit SuccessorProxy(const Self &it) : it(it) {}
00128 
00129     SuccessorProxy &operator=(SuccessorProxy r) {
00130       *this = reference(r);
00131       return *this;
00132     }
00133 
00134     SuccessorProxy &operator=(reference r) {
00135       it.Term->setSuccessor(it.idx, r);
00136       return *this;
00137     }
00138 
00139     operator reference() const { return *it; }
00140   };
00141 
00142 public:
00143   explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator
00144   }
00145   inline SuccIterator(Term_ T, bool)                       // end iterator
00146     : Term(T) {
00147     if (Term)
00148       idx = Term->getNumSuccessors();
00149     else
00150       // Term == NULL happens, if a basic block is not fully constructed and
00151       // consequently getTerminator() returns NULL. In this case we construct a
00152       // SuccIterator which describes a basic block that has zero successors.
00153       // Defining SuccIterator for incomplete and malformed CFGs is especially
00154       // useful for debugging.
00155       idx = 0;
00156   }
00157 
00158   inline const Self &operator=(const Self &I) {
00159     assert(Term == I.Term &&"Cannot assign iterators to two different blocks!");
00160     idx = I.idx;
00161     return *this;
00162   }
00163 
00164   /// getSuccessorIndex - This is used to interface between code that wants to
00165   /// operate on terminator instructions directly.
00166   unsigned getSuccessorIndex() const { return idx; }
00167 
00168   inline bool operator==(const Self& x) const { return idx == x.idx; }
00169   inline bool operator!=(const Self& x) const { return !operator==(x); }
00170 
00171   inline reference operator*() const { return Term->getSuccessor(idx); }
00172   inline pointer operator->() const { return operator*(); }
00173 
00174   inline Self& operator++() { ++idx; return *this; } // Preincrement
00175 
00176   inline Self operator++(int) { // Postincrement
00177     Self tmp = *this; ++*this; return tmp;
00178   }
00179 
00180   inline Self& operator--() { --idx; return *this; }  // Predecrement
00181   inline Self operator--(int) { // Postdecrement
00182     Self tmp = *this; --*this; return tmp;
00183   }
00184 
00185   inline bool operator<(const Self& x) const {
00186     assert(Term == x.Term && "Cannot compare iterators of different blocks!");
00187     return idx < x.idx;
00188   }
00189 
00190   inline bool operator<=(const Self& x) const {
00191     assert(Term == x.Term && "Cannot compare iterators of different blocks!");
00192     return idx <= x.idx;
00193   }
00194   inline bool operator>=(const Self& x) const {
00195     assert(Term == x.Term && "Cannot compare iterators of different blocks!");
00196     return idx >= x.idx;
00197   }
00198 
00199   inline bool operator>(const Self& x) const {
00200     assert(Term == x.Term && "Cannot compare iterators of different blocks!");
00201     return idx > x.idx;
00202   }
00203 
00204   inline Self& operator+=(int Right) {
00205     unsigned new_idx = idx + Right;
00206     assert(index_is_valid(new_idx) && "Iterator index out of bound");
00207     idx = new_idx;
00208     return *this;
00209   }
00210 
00211   inline Self operator+(int Right) const {
00212     Self tmp = *this;
00213     tmp += Right;
00214     return tmp;
00215   }
00216 
00217   inline Self& operator-=(int Right) {
00218     return operator+=(-Right);
00219   }
00220 
00221   inline Self operator-(int Right) const {
00222     return operator+(-Right);
00223   }
00224 
00225   inline int operator-(const Self& x) const {
00226     assert(Term == x.Term && "Cannot work on iterators of different blocks!");
00227     int distance = idx - x.idx;
00228     return distance;
00229   }
00230 
00231   inline SuccessorProxy operator[](int offset) {
00232    Self tmp = *this;
00233    tmp += offset;
00234    return SuccessorProxy(tmp);
00235   }
00236 
00237   /// Get the source BB of this iterator.
00238   inline BB_ *getSource() {
00239     assert(Term && "Source not available, if basic block was malformed");
00240     return Term->getParent();
00241   }
00242 };
00243 
00244 typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator;
00245 typedef SuccIterator<const TerminatorInst*,
00246                      const BasicBlock> succ_const_iterator;
00247 
00248 inline succ_iterator succ_begin(BasicBlock *BB) {
00249   return succ_iterator(BB->getTerminator());
00250 }
00251 inline succ_const_iterator succ_begin(const BasicBlock *BB) {
00252   return succ_const_iterator(BB->getTerminator());
00253 }
00254 inline succ_iterator succ_end(BasicBlock *BB) {
00255   return succ_iterator(BB->getTerminator(), true);
00256 }
00257 inline succ_const_iterator succ_end(const BasicBlock *BB) {
00258   return succ_const_iterator(BB->getTerminator(), true);
00259 }
00260 
00261 template <typename T, typename U> struct isPodLike<SuccIterator<T, U> > {
00262   static const bool value = isPodLike<T>::value;
00263 };
00264 
00265 
00266 
00267 //===--------------------------------------------------------------------===//
00268 // GraphTraits specializations for basic block graphs (CFGs)
00269 //===--------------------------------------------------------------------===//
00270 
00271 // Provide specializations of GraphTraits to be able to treat a function as a
00272 // graph of basic blocks...
00273 
00274 template <> struct GraphTraits<BasicBlock*> {
00275   typedef BasicBlock NodeType;
00276   typedef succ_iterator ChildIteratorType;
00277 
00278   static NodeType *getEntryNode(BasicBlock *BB) { return BB; }
00279   static inline ChildIteratorType child_begin(NodeType *N) {
00280     return succ_begin(N);
00281   }
00282   static inline ChildIteratorType child_end(NodeType *N) {
00283     return succ_end(N);
00284   }
00285 };
00286 
00287 template <> struct GraphTraits<const BasicBlock*> {
00288   typedef const BasicBlock NodeType;
00289   typedef succ_const_iterator ChildIteratorType;
00290 
00291   static NodeType *getEntryNode(const BasicBlock *BB) { return BB; }
00292 
00293   static inline ChildIteratorType child_begin(NodeType *N) {
00294     return succ_begin(N);
00295   }
00296   static inline ChildIteratorType child_end(NodeType *N) {
00297     return succ_end(N);
00298   }
00299 };
00300 
00301 // Provide specializations of GraphTraits to be able to treat a function as a
00302 // graph of basic blocks... and to walk it in inverse order.  Inverse order for
00303 // a function is considered to be when traversing the predecessor edges of a BB
00304 // instead of the successor edges.
00305 //
00306 template <> struct GraphTraits<Inverse<BasicBlock*> > {
00307   typedef BasicBlock NodeType;
00308   typedef pred_iterator ChildIteratorType;
00309   static NodeType *getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; }
00310   static inline ChildIteratorType child_begin(NodeType *N) {
00311     return pred_begin(N);
00312   }
00313   static inline ChildIteratorType child_end(NodeType *N) {
00314     return pred_end(N);
00315   }
00316 };
00317 
00318 template <> struct GraphTraits<Inverse<const BasicBlock*> > {
00319   typedef const BasicBlock NodeType;
00320   typedef const_pred_iterator ChildIteratorType;
00321   static NodeType *getEntryNode(Inverse<const BasicBlock*> G) {
00322     return G.Graph;
00323   }
00324   static inline ChildIteratorType child_begin(NodeType *N) {
00325     return pred_begin(N);
00326   }
00327   static inline ChildIteratorType child_end(NodeType *N) {
00328     return pred_end(N);
00329   }
00330 };
00331 
00332 
00333 
00334 //===--------------------------------------------------------------------===//
00335 // GraphTraits specializations for function basic block graphs (CFGs)
00336 //===--------------------------------------------------------------------===//
00337 
00338 // Provide specializations of GraphTraits to be able to treat a function as a
00339 // graph of basic blocks... these are the same as the basic block iterators,
00340 // except that the root node is implicitly the first node of the function.
00341 //
00342 template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
00343   static NodeType *getEntryNode(Function *F) { return &F->getEntryBlock(); }
00344 
00345   // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
00346   typedef Function::iterator nodes_iterator;
00347   static nodes_iterator nodes_begin(Function *F) { return F->begin(); }
00348   static nodes_iterator nodes_end  (Function *F) { return F->end(); }
00349   static size_t         size       (Function *F) { return F->size(); }
00350 };
00351 template <> struct GraphTraits<const Function*> :
00352   public GraphTraits<const BasicBlock*> {
00353   static NodeType *getEntryNode(const Function *F) {return &F->getEntryBlock();}
00354 
00355   // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
00356   typedef Function::const_iterator nodes_iterator;
00357   static nodes_iterator nodes_begin(const Function *F) { return F->begin(); }
00358   static nodes_iterator nodes_end  (const Function *F) { return F->end(); }
00359   static size_t         size       (const Function *F) { return F->size(); }
00360 };
00361 
00362 
00363 // Provide specializations of GraphTraits to be able to treat a function as a
00364 // graph of basic blocks... and to walk it in inverse order.  Inverse order for
00365 // a function is considered to be when traversing the predecessor edges of a BB
00366 // instead of the successor edges.
00367 //
00368 template <> struct GraphTraits<Inverse<Function*> > :
00369   public GraphTraits<Inverse<BasicBlock*> > {
00370   static NodeType *getEntryNode(Inverse<Function*> G) {
00371     return &G.Graph->getEntryBlock();
00372   }
00373 };
00374 template <> struct GraphTraits<Inverse<const Function*> > :
00375   public GraphTraits<Inverse<const BasicBlock*> > {
00376   static NodeType *getEntryNode(Inverse<const Function *> G) {
00377     return &G.Graph->getEntryBlock();
00378   }
00379 };
00380 
00381 } // End llvm namespace
00382 
00383 #endif