1e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//==- llvm/Analysis/ConstantsScanner.h - Iterate over constants -*- C++ -*-===//
2e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//
3e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//                     The LLVM Compiler Infrastructure
4e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//
5e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao// This file is distributed under the University of Illinois Open Source
6e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao// License. See LICENSE.TXT for details.
7e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//
8e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//===----------------------------------------------------------------------===//
9e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//
10e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao// This class implements an iterator to walk through the constants referenced by
11e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao// a method.  This is used by the Bitcode & Assembly writers to build constant
12e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao// pools.
13e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//
14e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//===----------------------------------------------------------------------===//
15e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
16e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#ifndef LLVM_ANALYSIS_CONSTANTSSCANNER_H
17e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#define LLVM_ANALYSIS_CONSTANTSSCANNER_H
18e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/InstIterator.h"
20e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
21e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaonamespace llvm {
22e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
23e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaoclass Constant;
24e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
25e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaoclass constant_iterator : public std::iterator<std::forward_iterator_tag,
26e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                               const Constant, ptrdiff_t> {
27e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const_inst_iterator InstI;                // Method instruction iterator
28e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  unsigned OpIdx;                           // Operand index
29e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
30e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  typedef constant_iterator _Self;
31e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
32e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  inline bool isAtConstant() const {
33e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    assert(!InstI.atEnd() && OpIdx < InstI->getNumOperands() &&
34e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao           "isAtConstant called with invalid arguments!");
35e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return isa<Constant>(InstI->getOperand(OpIdx));
36e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
37e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
38e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaopublic:
39e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  inline constant_iterator(const Function *F) : InstI(inst_begin(F)), OpIdx(0) {
40e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // Advance to first constant... if we are not already at constant or end
41e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (InstI != inst_end(F) &&                            // InstI is valid?
42e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        (InstI->getNumOperands() == 0 || !isAtConstant())) // Not at constant?
43e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      operator++();
44e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
45e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
46e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  inline constant_iterator(const Function *F, bool)   // end ctor
47e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    : InstI(inst_end(F)), OpIdx(0) {
48e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
49e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
50e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  inline bool operator==(const _Self& x) const { return OpIdx == x.OpIdx &&
51e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                                        InstI == x.InstI; }
52e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  inline bool operator!=(const _Self& x) const { return !operator==(x); }
53e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
54e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  inline pointer operator*() const {
55e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    assert(isAtConstant() && "Dereferenced an iterator at the end!");
56e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return cast<Constant>(InstI->getOperand(OpIdx));
57e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
58e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  inline pointer operator->() const { return operator*(); }
59e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
60e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  inline _Self& operator++() {   // Preincrement implementation
61e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    ++OpIdx;
62e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    do {
63e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      unsigned NumOperands = InstI->getNumOperands();
64e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      while (OpIdx < NumOperands && !isAtConstant()) {
65e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        ++OpIdx;
66e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      }
67e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
68e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      if (OpIdx < NumOperands) return *this;  // Found a constant!
69e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      ++InstI;
70e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      OpIdx = 0;
71e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    } while (!InstI.atEnd());
72e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
73e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return *this;  // At the end of the method
74e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
75e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
76e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  inline _Self operator++(int) { // Postincrement
77e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    _Self tmp = *this; ++*this; return tmp;
78e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
79e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
80e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  inline bool atEnd() const { return InstI.atEnd(); }
81e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao};
82e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
83e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaoinline constant_iterator constant_begin(const Function *F) {
84e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  return constant_iterator(F);
85e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
86e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
87e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaoinline constant_iterator constant_end(const Function *F) {
88e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  return constant_iterator(F, true);
89e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
90e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
91e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao} // End llvm namespace
92e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
93e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#endif
94