#ifndef LLVM_INSTRUCTIONS_H
#define LLVM_INSTRUCTIONS_H
+#include <iterator>
+
#include "llvm/InstrTypes.h"
+#include "llvm/DerivedTypes.h"
namespace llvm {
class ConstantInt;
class PointerType;
class VectorType;
+class ConstantRange;
+class APInt;
+class ParamAttrsList;
//===----------------------------------------------------------------------===//
// AllocationInst Class
FreeInst(Value *Ptr, BasicBlock *InsertAfter);
virtual FreeInst *clone() const;
+
+ // Accessor methods for consistency with other memory operations
+ Value *getPointerOperand() { return getOperand(0); }
+ const Value *getPointerOperand() const { return getOperand(0); }
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const FreeInst *) { return true; }
/// SubclassData field in Value to store whether or not the load is volatile.
///
class LoadInst : public UnaryInstruction {
+
LoadInst(const LoadInst &LI)
: UnaryInstruction(LI.getType(), Load, LI.getOperand(0)) {
setVolatile(LI.isVolatile());
+ setAlignment(LI.getAlignment());
#ifndef NDEBUG
AssertOK();
public:
LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBefore);
LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAtEnd);
- LoadInst(Value *Ptr, const std::string &Name, bool isVolatile = false,
+ LoadInst(Value *Ptr, const std::string &Name, bool isVolatile = false,
+ Instruction *InsertBefore = 0);
+ LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, unsigned Align,
Instruction *InsertBefore = 0);
LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
BasicBlock *InsertAtEnd);
+ LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, unsigned Align,
+ BasicBlock *InsertAtEnd);
LoadInst(Value *Ptr, const char *Name, Instruction *InsertBefore);
LoadInst(Value *Ptr, const char *Name, BasicBlock *InsertAtEnd);
- explicit LoadInst(Value *Ptr, const char *Name = 0, bool isVolatile = false,
+ explicit LoadInst(Value *Ptr, const char *Name = 0, bool isVolatile = false,
Instruction *InsertBefore = 0);
LoadInst(Value *Ptr, const char *Name, bool isVolatile,
BasicBlock *InsertAtEnd);
/// isVolatile - Return true if this is a load from a volatile memory
/// location.
///
- bool isVolatile() const { return SubclassData; }
+ bool isVolatile() const { return SubclassData & 1; }
/// setVolatile - Specify whether this is a volatile load or not.
///
- void setVolatile(bool V) { SubclassData = V; }
+ void setVolatile(bool V) {
+ SubclassData = (SubclassData & ~1) | (V ? 1 : 0);
+ }
virtual LoadInst *clone() const;
+ /// getAlignment - Return the alignment of the access that is being performed
+ ///
+ unsigned getAlignment() const {
+ return (1 << (SubclassData>>1)) >> 1;
+ }
+
+ void setAlignment(unsigned Align);
+
Value *getPointerOperand() { return getOperand(0); }
const Value *getPointerOperand() const { return getOperand(0); }
static unsigned getPointerOperandIndex() { return 0U; }
///
class StoreInst : public Instruction {
Use Ops[2];
+
StoreInst(const StoreInst &SI) : Instruction(SI.getType(), Store, Ops, 2) {
Ops[0].init(SI.Ops[0], this);
Ops[1].init(SI.Ops[1], this);
setVolatile(SI.isVolatile());
+ setAlignment(SI.getAlignment());
+
#ifndef NDEBUG
AssertOK();
#endif
StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd);
StoreInst(Value *Val, Value *Ptr, bool isVolatile = false,
Instruction *InsertBefore = 0);
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile,
+ unsigned Align, Instruction *InsertBefore = 0);
StoreInst(Value *Val, Value *Ptr, bool isVolatile, BasicBlock *InsertAtEnd);
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile,
+ unsigned Align, BasicBlock *InsertAtEnd);
/// isVolatile - Return true if this is a load from a volatile memory
/// location.
///
- bool isVolatile() const { return SubclassData; }
+ bool isVolatile() const { return SubclassData & 1; }
/// setVolatile - Specify whether this is a volatile load or not.
///
- void setVolatile(bool V) { SubclassData = V; }
+ void setVolatile(bool V) {
+ SubclassData = (SubclassData & ~1) | (V ? 1 : 0);
+ }
/// Transparently provide more efficient getOperand methods.
Value *getOperand(unsigned i) const {
}
unsigned getNumOperands() const { return 2; }
-
+ /// getAlignment - Return the alignment of the access that is being performed
+ ///
+ unsigned getAlignment() const {
+ return (1 << (SubclassData>>1)) >> 1;
+ }
+
+ void setAlignment(unsigned Align);
+
virtual StoreInst *clone() const;
Value *getPointerOperand() { return getOperand(1); }
// GetElementPtrInst Class
//===----------------------------------------------------------------------===//
+// checkType - Simple wrapper function to give a better assertion failure
+// message on bad indexes for a gep instruction.
+//
+static inline const Type *checkType(const Type *Ty) {
+ assert(Ty && "Invalid GetElementPtrInst indices for type!");
+ return Ty;
+}
+
/// GetElementPtrInst - an instruction for type-safe pointer arithmetic to
/// access elements of arrays and structs
///
OL[i].init(GEPIOL[i], this);
}
void init(Value *Ptr, Value* const *Idx, unsigned NumIdx);
- void init(Value *Ptr, Value *Idx0, Value *Idx1);
void init(Value *Ptr, Value *Idx);
+
+ template<typename InputIterator>
+ void init(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd,
+ const std::string &Name,
+ // This argument ensures that we have an iterator we can
+ // do arithmetic on in constant time
+ std::random_access_iterator_tag) {
+ typename std::iterator_traits<InputIterator>::difference_type NumIdx =
+ std::distance(IdxBegin, IdxEnd);
+
+ if (NumIdx > 0) {
+ // This requires that the itoerator points to contiguous memory.
+ init(Ptr, &*IdxBegin, NumIdx);
+ }
+ else {
+ init(Ptr, 0, NumIdx);
+ }
+
+ setName(Name);
+ }
+
+ /// getIndexedType - Returns the type of the element that would be loaded with
+ /// a load instruction with the specified parameters.
+ ///
+ /// A null type is returned if the indices are invalid for the specified
+ /// pointer type.
+ ///
+ static const Type *getIndexedType(const Type *Ptr,
+ Value* const *Idx, unsigned NumIdx,
+ bool AllowStructLeaf = false);
+
+ template<typename InputIterator>
+ static const Type *getIndexedType(const Type *Ptr,
+ InputIterator IdxBegin,
+ InputIterator IdxEnd,
+ bool AllowStructLeaf,
+ // This argument ensures that we
+ // have an iterator we can do
+ // arithmetic on in constant time
+ std::random_access_iterator_tag) {
+ typename std::iterator_traits<InputIterator>::difference_type NumIdx =
+ std::distance(IdxBegin, IdxEnd);
+
+ if (NumIdx > 0) {
+ // This requires that the iterator points to contiguous memory.
+ return(getIndexedType(Ptr, (Value *const *)&*IdxBegin, NumIdx,
+ AllowStructLeaf));
+ }
+ else {
+ return(getIndexedType(Ptr, (Value *const*)0, NumIdx, AllowStructLeaf));
+ }
+ }
+
public:
/// Constructors - Create a getelementptr instruction with a base pointer an
/// list of indices. The first ctor can optionally insert before an existing
/// instruction, the second appends the new instruction to the specified
/// BasicBlock.
- GetElementPtrInst(Value *Ptr, Value* const *Idx, unsigned NumIdx,
- const std::string &Name = "", Instruction *InsertBefore =0);
- GetElementPtrInst(Value *Ptr, Value* const *Idx, unsigned NumIdx,
- const std::string &Name, BasicBlock *InsertAtEnd);
-
+ template<typename InputIterator>
+ GetElementPtrInst(Value *Ptr, InputIterator IdxBegin,
+ InputIterator IdxEnd,
+ const std::string &Name = "",
+ Instruction *InsertBefore =0)
+ : Instruction(PointerType::get(
+ checkType(getIndexedType(Ptr->getType(),
+ IdxBegin, IdxEnd, true))),
+ GetElementPtr, 0, 0, InsertBefore) {
+ init(Ptr, IdxBegin, IdxEnd, Name,
+ typename std::iterator_traits<InputIterator>::iterator_category());
+ }
+ template<typename InputIterator>
+ GetElementPtrInst(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd,
+ const std::string &Name, BasicBlock *InsertAtEnd)
+ : Instruction(PointerType::get(
+ checkType(getIndexedType(Ptr->getType(),
+ IdxBegin, IdxEnd, true))),
+ GetElementPtr, 0, 0, InsertAtEnd) {
+ init(Ptr, IdxBegin, IdxEnd, Name,
+ typename std::iterator_traits<InputIterator>::iterator_category());
+ }
+
/// Constructors - These two constructors are convenience methods because one
/// and two index getelementptr instructions are so common.
GetElementPtrInst(Value *Ptr, Value *Idx,
const std::string &Name = "", Instruction *InsertBefore =0);
GetElementPtrInst(Value *Ptr, Value *Idx,
const std::string &Name, BasicBlock *InsertAtEnd);
- GetElementPtrInst(Value *Ptr, Value *Idx0, Value *Idx1,
- const std::string &Name = "", Instruction *InsertBefore =0);
- GetElementPtrInst(Value *Ptr, Value *Idx0, Value *Idx1,
- const std::string &Name, BasicBlock *InsertAtEnd);
~GetElementPtrInst();
virtual GetElementPtrInst *clone() const;
/// A null type is returned if the indices are invalid for the specified
/// pointer type.
///
+ template<typename InputIterator>
static const Type *getIndexedType(const Type *Ptr,
- Value* const *Idx, unsigned NumIdx,
- bool AllowStructLeaf = false);
-
- static const Type *getIndexedType(const Type *Ptr, Value *Idx0, Value *Idx1,
- bool AllowStructLeaf = false);
+ InputIterator IdxBegin,
+ InputIterator IdxEnd,
+ bool AllowStructLeaf = false) {
+ return(getIndexedType(Ptr, IdxBegin, IdxEnd, AllowStructLeaf,
+ typename std::iterator_traits<InputIterator>::
+ iterator_category()));
+ }
static const Type *getIndexedType(const Type *Ptr, Value *Idx);
inline op_iterator idx_begin() { return op_begin()+1; }
inline bool hasIndices() const {
return getNumOperands() > 1;
}
+
+ /// hasAllZeroIndices - Return true if all of the indices of this GEP are
+ /// zeros. If so, the result pointer and the first operand have the same
+ /// value, just potentially different types.
+ bool hasAllZeroIndices() const;
+
+ /// hasAllConstantIndices - Return true if all of the indices of this GEP are
+ /// constant integers. If so, the result pointer and the first operand have
+ /// a constant offset between them.
+ bool hasAllConstantIndices() const;
+
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const GetElementPtrInst *) { return true; }
/// @returns true if the predicate of this ICmpInst is signed, false otherwise
/// @brief Determine if this instruction's predicate is signed.
- bool isSignedPredicate() { return isSignedPredicate(getPredicate()); }
+ bool isSignedPredicate() const { return isSignedPredicate(getPredicate()); }
/// @returns true if the predicate provided is signed, false otherwise
/// @brief Determine if the predicate is signed.
static bool isSignedPredicate(Predicate pred);
+ /// Initialize a set of values that all satisfy the predicate with C.
+ /// @brief Make a ConstantRange for a relation with a constant value.
+ static ConstantRange makeConstantRange(Predicate pred, const APInt &C);
+
/// Exchange the two operands to this instruction in such a way that it does
/// not modify the semantics of the instruction. The predicate value may be
/// changed to retain the same result if the predicate is order dependent
std::swap(Ops[0], Ops[1]);
}
+ virtual ICmpInst *clone() const;
+
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const ICmpInst *) { return true; }
static inline bool classof(const Instruction *I) {
std::swap(Ops[0], Ops[1]);
}
+ virtual FCmpInst *clone() const;
+
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const FCmpInst *) { return true; }
static inline bool classof(const Instruction *I) {
//===----------------------------------------------------------------------===//
// CallInst Class
//===----------------------------------------------------------------------===//
-
/// CallInst - This class represents a function call, abstracting a target
/// machine's calling convention. This class uses low bit of the SubClassData
/// field to indicate whether or not this is a tail call. The rest of the bits
/// hold the calling convention of the call.
///
+
class CallInst : public Instruction {
+ ParamAttrsList *ParamAttrs; ///< parameter attributes for call
CallInst(const CallInst &CI);
void init(Value *Func, Value* const *Params, unsigned NumParams);
void init(Value *Func, Value *Actual1, Value *Actual2);
void init(Value *Func, Value *Actual);
void init(Value *Func);
+ template<typename InputIterator>
+ void init(Value *Func, InputIterator ArgBegin, InputIterator ArgEnd,
+ const std::string &Name,
+ // This argument ensures that we have an iterator we can
+ // do arithmetic on in constant time
+ std::random_access_iterator_tag) {
+ unsigned NumArgs = (unsigned)std::distance(ArgBegin, ArgEnd);
+
+ // This requires that the iterator points to contiguous memory.
+ init(Func, NumArgs ? &*ArgBegin : 0, NumArgs);
+ setName(Name);
+ }
+
public:
- CallInst(Value *F, Value* const *Args, unsigned NumArgs,
- const std::string &Name = "", Instruction *InsertBefore = 0);
- CallInst(Value *F, Value *const *Args, unsigned NumArgs,
- const std::string &Name, BasicBlock *InsertAtEnd);
-
- // Alternate CallInst ctors w/ two actuals, w/ one actual and no
- // actuals, respectively.
- CallInst(Value *F, Value *Actual1, Value *Actual2,
- const std::string& Name = "", Instruction *InsertBefore = 0);
- CallInst(Value *F, Value *Actual1, Value *Actual2,
- const std::string& Name, BasicBlock *InsertAtEnd);
+ /// Construct a CallInst given a range of arguments. InputIterator
+ /// must be a random-access iterator pointing to contiguous storage
+ /// (e.g. a std::vector<>::iterator). Checks are made for
+ /// random-accessness but not for contiguous storage as that would
+ /// incur runtime overhead.
+ /// @brief Construct a CallInst from a range of arguments
+ template<typename InputIterator>
+ CallInst(Value *Func, InputIterator ArgBegin, InputIterator ArgEnd,
+ const std::string &Name = "", Instruction *InsertBefore = 0)
+ : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+ ->getElementType())->getReturnType(),
+ Instruction::Call, 0, 0, InsertBefore) {
+ init(Func, ArgBegin, ArgEnd, Name,
+ typename std::iterator_traits<InputIterator>::iterator_category());
+ }
+
+ /// Construct a CallInst given a range of arguments. InputIterator
+ /// must be a random-access iterator pointing to contiguous storage
+ /// (e.g. a std::vector<>::iterator). Checks are made for
+ /// random-accessness but not for contiguous storage as that would
+ /// incur runtime overhead.
+ /// @brief Construct a CallInst from a range of arguments
+ template<typename InputIterator>
+ CallInst(Value *Func, InputIterator ArgBegin, InputIterator ArgEnd,
+ const std::string &Name, BasicBlock *InsertAtEnd)
+ : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+ ->getElementType())->getReturnType(),
+ Instruction::Call, 0, 0, InsertAtEnd) {
+ init(Func, ArgBegin, ArgEnd, Name,
+ typename std::iterator_traits<InputIterator>::iterator_category());
+ }
+
CallInst(Value *F, Value *Actual, const std::string& Name = "",
Instruction *InsertBefore = 0);
CallInst(Value *F, Value *Actual, const std::string& Name,
SubclassData = (SubclassData & 1) | (CC << 1);
}
+ /// Obtains a pointer to the ParamAttrsList object which holds the
+ /// parameter attributes information, if any.
+ /// @returns 0 if no attributes have been set.
+ /// @brief Get the parameter attributes.
+ ParamAttrsList *getParamAttrs() const { return ParamAttrs; }
+
+ /// Sets the parameter attributes for this CallInst. To construct a
+ /// ParamAttrsList, see ParameterAttributes.h
+ /// @brief Set the parameter attributes.
+ void setParamAttrs(ParamAttrsList *attrs);
+
/// getCalledFunction - Return the function being called by this instruction
/// if it is a direct call. If it is a call through a function pointer,
/// return null.
Function *getCalledFunction() const {
- return static_cast<Function*>(dyn_cast<Function>(getOperand(0)));
+ return dyn_cast<Function>(getOperand(0));
}
/// getCalledValue - Get a pointer to the function that is invoked by this
BasicBlock *getSuccessor(unsigned i) const {
assert(i < getNumSuccessors() && "Successor # out of range for Branch!");
- return (i == 0) ? cast<BasicBlock>(getOperand(0)) :
- cast<BasicBlock>(getOperand(1));
+ return cast<BasicBlock>(getOperand(i));
}
void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
/// calling convention of the call.
///
class InvokeInst : public TerminatorInst {
+ ParamAttrsList *ParamAttrs;
InvokeInst(const InvokeInst &BI);
void init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
Value* const *Args, unsigned NumArgs);
+
+ template<typename InputIterator>
+ void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
+ InputIterator ArgBegin, InputIterator ArgEnd,
+ const std::string &Name,
+ // This argument ensures that we have an iterator we can
+ // do arithmetic on in constant time
+ std::random_access_iterator_tag) {
+ unsigned NumArgs = (unsigned)std::distance(ArgBegin, ArgEnd);
+
+ // This requires that the iterator points to contiguous memory.
+ init(Func, IfNormal, IfException, NumArgs ? &*ArgBegin : 0, NumArgs);
+ setName(Name);
+ }
+
public:
- InvokeInst(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
- Value* const* Args, unsigned NumArgs, const std::string &Name = "",
- Instruction *InsertBefore = 0);
- InvokeInst(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
- Value* const* Args, unsigned NumArgs, const std::string &Name,
- BasicBlock *InsertAtEnd);
+ /// Construct an InvokeInst given a range of arguments.
+ /// InputIterator must be a random-access iterator pointing to
+ /// contiguous storage (e.g. a std::vector<>::iterator). Checks are
+ /// made for random-accessness but not for contiguous storage as
+ /// that would incur runtime overhead.
+ ///
+ /// @brief Construct an InvokeInst from a range of arguments
+ template<typename InputIterator>
+ InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
+ InputIterator ArgBegin, InputIterator ArgEnd,
+ const std::string &Name = "", Instruction *InsertBefore = 0)
+ : TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType())
+ ->getElementType())->getReturnType(),
+ Instruction::Invoke, 0, 0, InsertBefore) {
+ init(Func, IfNormal, IfException, ArgBegin, ArgEnd, Name,
+ typename std::iterator_traits<InputIterator>::iterator_category());
+ }
+
+ /// Construct an InvokeInst given a range of arguments.
+ /// InputIterator must be a random-access iterator pointing to
+ /// contiguous storage (e.g. a std::vector<>::iterator). Checks are
+ /// made for random-accessness but not for contiguous storage as
+ /// that would incur runtime overhead.
+ ///
+ /// @brief Construct an InvokeInst from a range of arguments
+ template<typename InputIterator>
+ InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
+ InputIterator ArgBegin, InputIterator ArgEnd,
+ const std::string &Name, BasicBlock *InsertAtEnd)
+ : TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType())
+ ->getElementType())->getReturnType(),
+ Instruction::Invoke, 0, 0, InsertAtEnd) {
+ init(Func, IfNormal, IfException, ArgBegin, ArgEnd, Name,
+ typename std::iterator_traits<InputIterator>::iterator_category());
+ }
+
~InvokeInst();
virtual InvokeInst *clone() const;
SubclassData = CC;
}
+ /// Obtains a pointer to the ParamAttrsList object which holds the
+ /// parameter attributes information, if any.
+ /// @returns 0 if no attributes have been set.
+ /// @brief Get the parameter attributes.
+ ParamAttrsList *getParamAttrs() const { return ParamAttrs; }
+
+ /// Sets the parameter attributes for this InvokeInst. To construct a
+ /// ParamAttrsList, see ParameterAttributes.h
+ /// @brief Set the parameter attributes.
+ void setParamAttrs(ParamAttrsList *attrs);
+
/// getCalledFunction - Return the function called, or null if this is an
/// indirect function invocation.
///