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