1*9880d681SAndroid Build Coastguard Worker //===- InstIterator.h - Classes for inst iteration --------------*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains definitions of two iterators for iterating over the
11*9880d681SAndroid Build Coastguard Worker // instructions in a function. This is effectively a wrapper around a two level
12*9880d681SAndroid Build Coastguard Worker // iterator that can probably be genericized later.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker // Note that this iterator gets invalidated any time that basic blocks or
15*9880d681SAndroid Build Coastguard Worker // instructions are moved around.
16*9880d681SAndroid Build Coastguard Worker //
17*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_IR_INSTITERATOR_H
20*9880d681SAndroid Build Coastguard Worker #define LLVM_IR_INSTITERATOR_H
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/BasicBlock.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker namespace llvm {
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker // This class implements inst_begin() & inst_end() for
28*9880d681SAndroid Build Coastguard Worker // inst_iterator and const_inst_iterator's.
29*9880d681SAndroid Build Coastguard Worker //
30*9880d681SAndroid Build Coastguard Worker template <class BB_t, class BB_i_t, class BI_t, class II_t> class InstIterator {
31*9880d681SAndroid Build Coastguard Worker typedef BB_t BBty;
32*9880d681SAndroid Build Coastguard Worker typedef BB_i_t BBIty;
33*9880d681SAndroid Build Coastguard Worker typedef BI_t BIty;
34*9880d681SAndroid Build Coastguard Worker typedef II_t IIty;
35*9880d681SAndroid Build Coastguard Worker BB_t *BBs; // BasicBlocksType
36*9880d681SAndroid Build Coastguard Worker BB_i_t BB; // BasicBlocksType::iterator
37*9880d681SAndroid Build Coastguard Worker BI_t BI; // BasicBlock::iterator
38*9880d681SAndroid Build Coastguard Worker public:
39*9880d681SAndroid Build Coastguard Worker typedef std::bidirectional_iterator_tag iterator_category;
40*9880d681SAndroid Build Coastguard Worker typedef IIty value_type;
41*9880d681SAndroid Build Coastguard Worker typedef signed difference_type;
42*9880d681SAndroid Build Coastguard Worker typedef IIty* pointer;
43*9880d681SAndroid Build Coastguard Worker typedef IIty& reference;
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker // Default constructor
InstIterator()46*9880d681SAndroid Build Coastguard Worker InstIterator() {}
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker // Copy constructor...
49*9880d681SAndroid Build Coastguard Worker template<typename A, typename B, typename C, typename D>
InstIterator(const InstIterator<A,B,C,D> & II)50*9880d681SAndroid Build Coastguard Worker InstIterator(const InstIterator<A,B,C,D> &II)
51*9880d681SAndroid Build Coastguard Worker : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker template<typename A, typename B, typename C, typename D>
InstIterator(InstIterator<A,B,C,D> & II)54*9880d681SAndroid Build Coastguard Worker InstIterator(InstIterator<A,B,C,D> &II)
55*9880d681SAndroid Build Coastguard Worker : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
56*9880d681SAndroid Build Coastguard Worker
InstIterator(M & m)57*9880d681SAndroid Build Coastguard Worker template<class M> InstIterator(M &m)
58*9880d681SAndroid Build Coastguard Worker : BBs(&m.getBasicBlockList()), BB(BBs->begin()) { // begin ctor
59*9880d681SAndroid Build Coastguard Worker if (BB != BBs->end()) {
60*9880d681SAndroid Build Coastguard Worker BI = BB->begin();
61*9880d681SAndroid Build Coastguard Worker advanceToNextBB();
62*9880d681SAndroid Build Coastguard Worker }
63*9880d681SAndroid Build Coastguard Worker }
64*9880d681SAndroid Build Coastguard Worker
InstIterator(M & m,bool)65*9880d681SAndroid Build Coastguard Worker template<class M> InstIterator(M &m, bool)
66*9880d681SAndroid Build Coastguard Worker : BBs(&m.getBasicBlockList()), BB(BBs->end()) { // end ctor
67*9880d681SAndroid Build Coastguard Worker }
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker // Accessors to get at the underlying iterators...
getBasicBlockIterator()70*9880d681SAndroid Build Coastguard Worker inline BBIty &getBasicBlockIterator() { return BB; }
getInstructionIterator()71*9880d681SAndroid Build Coastguard Worker inline BIty &getInstructionIterator() { return BI; }
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Worker inline reference operator*() const { return *BI; }
74*9880d681SAndroid Build Coastguard Worker inline pointer operator->() const { return &operator*(); }
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Worker inline bool operator==(const InstIterator &y) const {
77*9880d681SAndroid Build Coastguard Worker return BB == y.BB && (BB == BBs->end() || BI == y.BI);
78*9880d681SAndroid Build Coastguard Worker }
79*9880d681SAndroid Build Coastguard Worker inline bool operator!=(const InstIterator& y) const {
80*9880d681SAndroid Build Coastguard Worker return !operator==(y);
81*9880d681SAndroid Build Coastguard Worker }
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Worker InstIterator& operator++() {
84*9880d681SAndroid Build Coastguard Worker ++BI;
85*9880d681SAndroid Build Coastguard Worker advanceToNextBB();
86*9880d681SAndroid Build Coastguard Worker return *this;
87*9880d681SAndroid Build Coastguard Worker }
88*9880d681SAndroid Build Coastguard Worker inline InstIterator operator++(int) {
89*9880d681SAndroid Build Coastguard Worker InstIterator tmp = *this; ++*this; return tmp;
90*9880d681SAndroid Build Coastguard Worker }
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Worker InstIterator& operator--() {
93*9880d681SAndroid Build Coastguard Worker while (BB == BBs->end() || BI == BB->begin()) {
94*9880d681SAndroid Build Coastguard Worker --BB;
95*9880d681SAndroid Build Coastguard Worker BI = BB->end();
96*9880d681SAndroid Build Coastguard Worker }
97*9880d681SAndroid Build Coastguard Worker --BI;
98*9880d681SAndroid Build Coastguard Worker return *this;
99*9880d681SAndroid Build Coastguard Worker }
100*9880d681SAndroid Build Coastguard Worker inline InstIterator operator--(int) {
101*9880d681SAndroid Build Coastguard Worker InstIterator tmp = *this; --*this; return tmp;
102*9880d681SAndroid Build Coastguard Worker }
103*9880d681SAndroid Build Coastguard Worker
atEnd()104*9880d681SAndroid Build Coastguard Worker inline bool atEnd() const { return BB == BBs->end(); }
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker private:
advanceToNextBB()107*9880d681SAndroid Build Coastguard Worker inline void advanceToNextBB() {
108*9880d681SAndroid Build Coastguard Worker // The only way that the II could be broken is if it is now pointing to
109*9880d681SAndroid Build Coastguard Worker // the end() of the current BasicBlock and there are successor BBs.
110*9880d681SAndroid Build Coastguard Worker while (BI == BB->end()) {
111*9880d681SAndroid Build Coastguard Worker ++BB;
112*9880d681SAndroid Build Coastguard Worker if (BB == BBs->end()) break;
113*9880d681SAndroid Build Coastguard Worker BI = BB->begin();
114*9880d681SAndroid Build Coastguard Worker }
115*9880d681SAndroid Build Coastguard Worker }
116*9880d681SAndroid Build Coastguard Worker };
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Worker typedef InstIterator<SymbolTableList<BasicBlock>, Function::iterator,
119*9880d681SAndroid Build Coastguard Worker BasicBlock::iterator, Instruction> inst_iterator;
120*9880d681SAndroid Build Coastguard Worker typedef InstIterator<const SymbolTableList<BasicBlock>,
121*9880d681SAndroid Build Coastguard Worker Function::const_iterator, BasicBlock::const_iterator,
122*9880d681SAndroid Build Coastguard Worker const Instruction> const_inst_iterator;
123*9880d681SAndroid Build Coastguard Worker typedef iterator_range<inst_iterator> inst_range;
124*9880d681SAndroid Build Coastguard Worker typedef iterator_range<const_inst_iterator> const_inst_range;
125*9880d681SAndroid Build Coastguard Worker
inst_begin(Function * F)126*9880d681SAndroid Build Coastguard Worker inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
inst_end(Function * F)127*9880d681SAndroid Build Coastguard Worker inline inst_iterator inst_end(Function *F) { return inst_iterator(*F, true); }
instructions(Function * F)128*9880d681SAndroid Build Coastguard Worker inline inst_range instructions(Function *F) {
129*9880d681SAndroid Build Coastguard Worker return inst_range(inst_begin(F), inst_end(F));
130*9880d681SAndroid Build Coastguard Worker }
inst_begin(const Function * F)131*9880d681SAndroid Build Coastguard Worker inline const_inst_iterator inst_begin(const Function *F) {
132*9880d681SAndroid Build Coastguard Worker return const_inst_iterator(*F);
133*9880d681SAndroid Build Coastguard Worker }
inst_end(const Function * F)134*9880d681SAndroid Build Coastguard Worker inline const_inst_iterator inst_end(const Function *F) {
135*9880d681SAndroid Build Coastguard Worker return const_inst_iterator(*F, true);
136*9880d681SAndroid Build Coastguard Worker }
instructions(const Function * F)137*9880d681SAndroid Build Coastguard Worker inline const_inst_range instructions(const Function *F) {
138*9880d681SAndroid Build Coastguard Worker return const_inst_range(inst_begin(F), inst_end(F));
139*9880d681SAndroid Build Coastguard Worker }
inst_begin(Function & F)140*9880d681SAndroid Build Coastguard Worker inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); }
inst_end(Function & F)141*9880d681SAndroid Build Coastguard Worker inline inst_iterator inst_end(Function &F) { return inst_iterator(F, true); }
instructions(Function & F)142*9880d681SAndroid Build Coastguard Worker inline inst_range instructions(Function &F) {
143*9880d681SAndroid Build Coastguard Worker return inst_range(inst_begin(F), inst_end(F));
144*9880d681SAndroid Build Coastguard Worker }
inst_begin(const Function & F)145*9880d681SAndroid Build Coastguard Worker inline const_inst_iterator inst_begin(const Function &F) {
146*9880d681SAndroid Build Coastguard Worker return const_inst_iterator(F);
147*9880d681SAndroid Build Coastguard Worker }
inst_end(const Function & F)148*9880d681SAndroid Build Coastguard Worker inline const_inst_iterator inst_end(const Function &F) {
149*9880d681SAndroid Build Coastguard Worker return const_inst_iterator(F, true);
150*9880d681SAndroid Build Coastguard Worker }
instructions(const Function & F)151*9880d681SAndroid Build Coastguard Worker inline const_inst_range instructions(const Function &F) {
152*9880d681SAndroid Build Coastguard Worker return const_inst_range(inst_begin(F), inst_end(F));
153*9880d681SAndroid Build Coastguard Worker }
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard Worker } // End llvm namespace
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Worker #endif
158