1193323Sed//===- llvm/Support/InstIterator.h - Classes for inst iteration -*- C++ -*-===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file contains definitions of two iterators for iterating over the
11193323Sed// instructions in a function.  This is effectively a wrapper around a two level
12193323Sed// iterator that can probably be genericized later.
13193323Sed//
14193323Sed// Note that this iterator gets invalidated any time that basic blocks or
15193323Sed// instructions are moved around.
16193323Sed//
17193323Sed//===----------------------------------------------------------------------===//
18193323Sed
19193323Sed#ifndef LLVM_SUPPORT_INSTITERATOR_H
20193323Sed#define LLVM_SUPPORT_INSTITERATOR_H
21193323Sed
22249423Sdim#include "llvm/IR/BasicBlock.h"
23249423Sdim#include "llvm/IR/Function.h"
24193323Sed
25193323Sednamespace llvm {
26193323Sed
27193323Sed// This class implements inst_begin() & inst_end() for
28193323Sed// inst_iterator and const_inst_iterator's.
29193323Sed//
30193323Sedtemplate <class _BB_t, class _BB_i_t, class _BI_t, class _II_t>
31193323Sedclass InstIterator {
32193323Sed  typedef _BB_t   BBty;
33193323Sed  typedef _BB_i_t BBIty;
34193323Sed  typedef _BI_t   BIty;
35193323Sed  typedef _II_t   IIty;
36193323Sed  _BB_t  *BBs;      // BasicBlocksType
37193323Sed  _BB_i_t BB;       // BasicBlocksType::iterator
38193323Sed  _BI_t   BI;       // BasicBlock::iterator
39193323Sedpublic:
40193323Sed  typedef std::bidirectional_iterator_tag iterator_category;
41193323Sed  typedef IIty                            value_type;
42193323Sed  typedef signed                        difference_type;
43193323Sed  typedef IIty*                           pointer;
44193323Sed  typedef IIty&                           reference;
45193323Sed
46193323Sed  // Default constructor
47193323Sed  InstIterator() {}
48193323Sed
49193323Sed  // Copy constructor...
50193323Sed  template<typename A, typename B, typename C, typename D>
51193323Sed  InstIterator(const InstIterator<A,B,C,D> &II)
52193323Sed    : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
53193323Sed
54193323Sed  template<typename A, typename B, typename C, typename D>
55193323Sed  InstIterator(InstIterator<A,B,C,D> &II)
56193323Sed    : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
57193323Sed
58193323Sed  template<class M> InstIterator(M &m)
59193323Sed    : BBs(&m.getBasicBlockList()), BB(BBs->begin()) {    // begin ctor
60193323Sed    if (BB != BBs->end()) {
61193323Sed      BI = BB->begin();
62193323Sed      advanceToNextBB();
63193323Sed    }
64193323Sed  }
65193323Sed
66193323Sed  template<class M> InstIterator(M &m, bool)
67193323Sed    : BBs(&m.getBasicBlockList()), BB(BBs->end()) {    // end ctor
68193323Sed  }
69193323Sed
70193323Sed  // Accessors to get at the underlying iterators...
71193323Sed  inline BBIty &getBasicBlockIterator()  { return BB; }
72193323Sed  inline BIty  &getInstructionIterator() { return BI; }
73193323Sed
74193323Sed  inline reference operator*()  const { return *BI; }
75193323Sed  inline pointer operator->() const { return &operator*(); }
76193323Sed
77193323Sed  inline bool operator==(const InstIterator &y) const {
78193323Sed    return BB == y.BB && (BB == BBs->end() || BI == y.BI);
79193323Sed  }
80193323Sed  inline bool operator!=(const InstIterator& y) const {
81193323Sed    return !operator==(y);
82193323Sed  }
83193323Sed
84193323Sed  InstIterator& operator++() {
85193323Sed    ++BI;
86193323Sed    advanceToNextBB();
87193323Sed    return *this;
88193323Sed  }
89193323Sed  inline InstIterator operator++(int) {
90193323Sed    InstIterator tmp = *this; ++*this; return tmp;
91193323Sed  }
92193323Sed
93193323Sed  InstIterator& operator--() {
94193323Sed    while (BB == BBs->end() || BI == BB->begin()) {
95193323Sed      --BB;
96193323Sed      BI = BB->end();
97193323Sed    }
98193323Sed    --BI;
99193323Sed    return *this;
100193323Sed  }
101193323Sed  inline InstIterator  operator--(int) {
102193323Sed    InstIterator tmp = *this; --*this; return tmp;
103193323Sed  }
104193323Sed
105193323Sed  inline bool atEnd() const { return BB == BBs->end(); }
106193323Sed
107193323Sedprivate:
108193323Sed  inline void advanceToNextBB() {
109193323Sed    // The only way that the II could be broken is if it is now pointing to
110193323Sed    // the end() of the current BasicBlock and there are successor BBs.
111193323Sed    while (BI == BB->end()) {
112193323Sed      ++BB;
113193323Sed      if (BB == BBs->end()) break;
114193323Sed      BI = BB->begin();
115193323Sed    }
116193323Sed  }
117193323Sed};
118193323Sed
119193323Sed
120193323Sedtypedef InstIterator<iplist<BasicBlock>,
121193323Sed                     Function::iterator, BasicBlock::iterator,
122193323Sed                     Instruction> inst_iterator;
123193323Sedtypedef InstIterator<const iplist<BasicBlock>,
124193323Sed                     Function::const_iterator,
125193323Sed                     BasicBlock::const_iterator,
126193323Sed                     const Instruction> const_inst_iterator;
127193323Sed
128193323Sedinline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
129193323Sedinline inst_iterator inst_end(Function *F)   { return inst_iterator(*F, true); }
130193323Sedinline const_inst_iterator inst_begin(const Function *F) {
131193323Sed  return const_inst_iterator(*F);
132193323Sed}
133193323Sedinline const_inst_iterator inst_end(const Function *F) {
134193323Sed  return const_inst_iterator(*F, true);
135193323Sed}
136193323Sedinline inst_iterator inst_begin(Function &F) { return inst_iterator(F); }
137193323Sedinline inst_iterator inst_end(Function &F)   { return inst_iterator(F, true); }
138193323Sedinline const_inst_iterator inst_begin(const Function &F) {
139193323Sed  return const_inst_iterator(F);
140193323Sed}
141193323Sedinline const_inst_iterator inst_end(const Function &F) {
142193323Sed  return const_inst_iterator(F, true);
143193323Sed}
144193323Sed
145193323Sed} // End llvm namespace
146193323Sed
147193323Sed#endif
148