1 //===-- llvm/CFG.h - CFG definitions and useful classes ----------*- C++ -*--=//
3 // This file contains the class definitions useful for operating on the control
6 // Currently it contains functionality for these three applications:
8 // 1. Iterate over the predecessors of a basic block:
9 // pred_iterator, pred_const_iterator, pred_begin, pred_end
10 // 2. Iterate over the successors of a basic block:
11 // succ_iterator, succ_const_iterator, succ_begin, succ_end
12 // 3. Iterate over the basic blocks of a method in depth first ordering or
13 // reverse depth first order. df_iterator, df_const_iterator,
14 // df_begin, df_end. df_begin takes an arg to specify reverse or not.
15 // 4. Iterator over the basic blocks of a method in post order.
16 // 5. Iterator over a method in reverse post order.
18 //===----------------------------------------------------------------------===//
23 #include "llvm/CFGdecls.h" // See this file for concise interface info
24 #include "llvm/BasicBlock.h"
25 #include "llvm/InstrTypes.h"
26 #include "llvm/Type.h"
31 //===----------------------------------------------------------------------===//
33 //===----------------------------------------------------------------------===//
35 //===----------------------------------------------------------------------===//
36 // Basic Block Predecessor Iterator
39 template <class _Ptr, class _USE_iterator> // Predecessor Iterator
40 class PredIterator : public std::bidirectional_iterator<_Ptr, ptrdiff_t> {
44 typedef PredIterator<_Ptr,_USE_iterator> _Self;
46 inline void advancePastConstPool() {
48 // Loop to ignore constant pool references
49 while (It != BB->use_end() &&
50 ((!(*It)->isInstruction()) ||
51 !(((Instruction*)(*It))->isTerminator())))
55 inline PredIterator(_Ptr *bb) : BB(bb), It(bb->use_begin()) {
56 advancePastConstPool();
58 inline PredIterator(_Ptr *bb, bool) : BB(bb), It(bb->use_end()) {}
60 inline bool operator==(const _Self& x) const { return It == x.It; }
61 inline bool operator!=(const _Self& x) const { return !operator==(x); }
63 inline pointer operator*() const {
64 return (*It)->castInstructionAsserting()->getParent();
66 inline pointer *operator->() const { return &(operator*()); }
68 inline _Self& operator++() { // Preincrement
69 ++It; advancePastConstPool();
73 inline _Self operator++(int) { // Postincrement
74 _Self tmp = *this; ++*this; return tmp;
77 inline _Self& operator--() { --It; return *this; } // Predecrement
78 inline _Self operator--(int) { // Postdecrement
79 _Self tmp = *this; --*this; return tmp;
83 inline pred_iterator pred_begin( BasicBlock *BB) {
84 return pred_iterator(BB);
86 inline pred_const_iterator pred_begin(const BasicBlock *BB) {
87 return pred_const_iterator(BB);
89 inline pred_iterator pred_end( BasicBlock *BB) {
90 return pred_iterator(BB,true);
92 inline pred_const_iterator pred_end(const BasicBlock *BB) {
93 return pred_const_iterator(BB,true);
97 //===----------------------------------------------------------------------===//
98 // Basic Block Successor Iterator
101 template <class _Term, class _BB> // Successor Iterator
102 class SuccIterator : public std::bidirectional_iterator<_BB, ptrdiff_t> {
106 typedef SuccIterator<_Term, _BB> _Self;
107 // TODO: This can be random access iterator, need operator+ and stuff tho
109 inline SuccIterator(_Term T) : Term(T), idx(0) { // begin iterator
110 assert(T && "getTerminator returned null!");
112 inline SuccIterator(_Term T, bool) // end iterator
113 : Term(T), idx(Term->getNumSuccessors()) {
114 assert(T && "getTerminator returned null!");
117 inline bool operator==(const _Self& x) const { return idx == x.idx; }
118 inline bool operator!=(const _Self& x) const { return !operator==(x); }
120 inline pointer operator*() const { return Term->getSuccessor(idx); }
121 inline pointer operator->() const { return operator*(); }
123 inline _Self& operator++() { ++idx; return *this; } // Preincrement
124 inline _Self operator++(int) { // Postincrement
125 _Self tmp = *this; ++*this; return tmp;
128 inline _Self& operator--() { --idx; return *this; } // Predecrement
129 inline _Self operator--(int) { // Postdecrement
130 _Self tmp = *this; --*this; return tmp;
134 inline succ_iterator succ_begin( BasicBlock *BB) {
135 return succ_iterator(BB->getTerminator());
137 inline succ_const_iterator succ_begin(const BasicBlock *BB) {
138 return succ_const_iterator(BB->getTerminator());
140 inline succ_iterator succ_end( BasicBlock *BB) {
141 return succ_iterator(BB->getTerminator(),true);
143 inline succ_const_iterator succ_end(const BasicBlock *BB) {
144 return succ_const_iterator(BB->getTerminator(),true);
147 } // End namespace cfg