#ifndef LLVM_INSTRUCTIONS_H
#define LLVM_INSTRUCTIONS_H
+#include <iterator>
+
#include "llvm/InstrTypes.h"
+#include "llvm/DerivedTypes.h"
namespace llvm {
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; }
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);
/// setVolatile - Specify whether this is a volatile load or not.
///
void setVolatile(bool V) {
- SubclassData = (SubclassData & ~1) | ((V) ? 1 : 0);
+ SubclassData = (SubclassData & ~1) | V;
}
virtual LoadInst *clone() const;
/// getAlignment - Return the alignment of the access that is being performed
///
unsigned getAlignment() const {
- signed Log2AlignVal = ((SubclassData>>1)-1);
- return ((Log2AlignVal < 0) ? 0 : 1<<Log2AlignVal);
+ return (1 << (SubclassData>>1)) >> 1;
}
void setAlignment(unsigned Align);
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
/// setVolatile - Specify whether this is a volatile load or not.
///
void setVolatile(bool V) {
- SubclassData = (SubclassData & ~1) | ((V) ? 1 : 0);
+ SubclassData = (SubclassData & ~1) | V;
}
/// Transparently provide more efficient getOperand methods.
/// getAlignment - Return the alignment of the access that is being performed
///
unsigned getAlignment() const {
- signed Log2AlignVal = ((SubclassData>>1)-1);
- return ((Log2AlignVal < 0) ? 0 : 1<<Log2AlignVal);
+ return (1 << (SubclassData>>1)) >> 1;
}
void setAlignment(unsigned Align);
// 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; }
/// 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.
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 *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,
/// 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) {
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;