Expand the pass to unify all of the unwind blocks as well
[oota-llvm.git] / include / llvm / Support / InstIterator.h
1 //===-- llvm/Support/InstIterator.h - Classes for inst iteration -*- C++ -*--=//
2 //
3 // This file contains definitions of two iterators for iterating over the
4 // instructions in a function.  This is effectively a wrapper around a two level
5 // iterator that can probably be genericized later.
6 //
7 // Note that this iterator gets invalidated any time that basic blocks or
8 // instructions are moved around.
9 //
10 //===----------------------------------------------------------------------===//
11
12 #ifndef LLVM_INST_ITERATOR_H
13 #define LLVM_INST_ITERATOR_H
14
15 #include "llvm/BasicBlock.h"
16 #include "llvm/Function.h"
17
18 // This class is implements inst_begin() & inst_end() for
19 // inst_iterator and const_inst_iterator's.
20 //
21 template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t>
22 class InstIterator {
23   typedef _BB_t   BBty;
24   typedef _BB_i_t BBIty;
25   typedef _BI_t   BIty;
26   typedef _II_t   IIty;
27   _BB_t  &BBs;      // BasicBlocksType
28   _BB_i_t BB;       // BasicBlocksType::iterator
29   _BI_t   BI;       // BasicBlock::iterator
30 public:
31   typedef std::bidirectional_iterator_tag iterator_category;
32   typedef IIty                            value_type;
33   typedef unsigned                        difference_type;
34   typedef BIty                            pointer;
35   typedef IIty                            reference;
36
37   // Copy constructor...
38   template<typename A, typename B, typename C, typename D>
39   InstIterator(const InstIterator<A,B,C,D> &II)
40     : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
41
42   template<typename A, typename B, typename C, typename D>
43   InstIterator(InstIterator<A,B,C,D> &II)
44     : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
45   
46   template<class M> InstIterator(M &m) 
47     : BBs(m.getBasicBlockList()), BB(BBs.begin()) {    // begin ctor
48     if (BB != BBs.end()) {
49       BI = BB->begin();
50       advanceToNextBB();
51     }
52   }
53
54   template<class M> InstIterator(M &m, bool) 
55     : BBs(m.getBasicBlockList()), BB(BBs.end()) {    // end ctor
56   }
57
58   // Accessors to get at the underlying iterators...
59   inline BBIty &getBasicBlockIterator()  { return BB; }
60   inline BIty  &getInstructionIterator() { return BI; }
61   
62   inline IIty operator*()  const { return BI; }
63   inline IIty operator->() const { return operator*(); }
64   
65   inline bool operator==(const InstIterator &y) const { 
66     return BB == y.BB && (BB == BBs.end() || BI == y.BI);
67   }
68   inline bool operator!=(const InstIterator& y) const { 
69     return !operator==(y);
70   }
71
72   InstIterator& operator++() { 
73     ++BI;
74     advanceToNextBB();
75     return *this; 
76   }
77   inline InstIterator operator++(int) { 
78     InstIterator tmp = *this; ++*this; return tmp; 
79   }
80     
81   InstIterator& operator--() { 
82     while (BB == BBs.end() || BI == BB->begin()) {
83       --BB;
84       BI = BB->end();
85     }
86     --BI;
87     return *this; 
88   }
89   inline InstIterator  operator--(int) { 
90     InstIterator tmp = *this; --*this; return tmp; 
91   }
92
93   inline bool atEnd() const { return BB == BBs.end(); }
94
95 private:
96   inline void advanceToNextBB() {
97     // The only way that the II could be broken is if it is now pointing to
98     // the end() of the current BasicBlock and there are successor BBs.
99     while (BI == BB->end()) {
100       ++BB;
101       if (BB == BBs.end()) break;
102       BI = BB->begin();
103     }
104   }
105 };
106
107
108 typedef InstIterator<iplist<BasicBlock>,
109                      Function::iterator, BasicBlock::iterator,
110                      Instruction*> inst_iterator;
111 typedef InstIterator<const iplist<BasicBlock>,
112                      Function::const_iterator, 
113                      BasicBlock::const_iterator,
114                      const Instruction*> const_inst_iterator;
115
116 inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
117 inline inst_iterator inst_end(Function *F)   { return inst_iterator(*F, true); }
118 inline const_inst_iterator inst_begin(const Function *F) {
119   return const_inst_iterator(*F);
120 }
121 inline const_inst_iterator inst_end(const Function *F) {
122   return const_inst_iterator(*F, true);
123 }
124 inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); }
125 inline inst_iterator inst_end(Function &F)   { return inst_iterator(F, true); }
126 inline const_inst_iterator inst_begin(const Function &F) {
127   return const_inst_iterator(F);
128 }
129 inline const_inst_iterator inst_end(const Function &F) {
130   return const_inst_iterator(F, true);
131 }
132
133 #endif