X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FInstructions.h;h=2d721bb4147ac56bf2a775dce3c3e4a895e9666b;hp=677378382d04cefb131c4076dc33353baa03f56e;hb=afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5;hpb=cd406fe1236a1e0a7f210676768ddd3f69e23166 diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 677378382d0..2d721bb4147 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -20,6 +20,7 @@ #include "llvm/InstrTypes.h" #include "llvm/DerivedTypes.h" +#include "llvm/ParameterAttributes.h" namespace llvm { @@ -256,7 +257,7 @@ public: /// setVolatile - Specify whether this is a volatile load or not. /// void setVolatile(bool V) { - SubclassData = (SubclassData & ~1) | V; + SubclassData = (SubclassData & ~1) | (V ? 1 : 0); } virtual LoadInst *clone() const; @@ -324,7 +325,7 @@ public: /// setVolatile - Specify whether this is a volatile load or not. /// void setVolatile(bool V) { - SubclassData = (SubclassData & ~1) | V; + SubclassData = (SubclassData & ~1) | (V ? 1 : 0); } /// Transparently provide more efficient getOperand methods. @@ -367,6 +368,14 @@ public: // 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 /// @@ -380,28 +389,94 @@ class GetElementPtrInst : public Instruction { 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 + 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::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 + 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::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 + 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::iterator_category()); + } + template + 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::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; @@ -417,12 +492,15 @@ public: /// A null type is returned if the indices are invalid for the specified /// pointer type. /// + template 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:: + iterator_category())); + } static const Type *getIndexedType(const Type *Ptr, Value *Idx); inline op_iterator idx_begin() { return op_begin()+1; } @@ -563,27 +641,37 @@ public: /// @brief Return the signed version of the predicate. static Predicate getSignedPredicate(Predicate pred); - /// This also tests for commutativity. If isEquality() returns true then - /// the predicate is also commutative. - /// @returns true if the predicate of this instruction is EQ or NE. - /// @brief Determine if this is an equality predicate. + /// isEquality - Return true if this predicate is either EQ or NE. This also + /// tests for commutativity. + static bool isEquality(Predicate P) { + return P == ICMP_EQ || P == ICMP_NE; + } + + /// isEquality - Return true if this predicate is either EQ or NE. This also + /// tests for commutativity. bool isEquality() const { - return SubclassData == ICMP_EQ || SubclassData == ICMP_NE; + return isEquality(getPredicate()); } /// @returns true if the predicate of this ICmpInst is commutative /// @brief Determine if this relation is commutative. bool isCommutative() const { return isEquality(); } - /// @returns true if the predicate is relational (not EQ or NE). - /// @brief Determine if this a relational predicate. + /// isRelational - Return true if the predicate is relational (not EQ or NE). + /// bool isRelational() const { return !isEquality(); } + /// isRelational - Return true if the predicate is relational (not EQ or NE). + /// + static bool isRelational(Predicate P) { + return !isEquality(P); + } + /// @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. @@ -749,7 +837,7 @@ public: /// class CallInst : public Instruction { - ParamAttrsList *ParamAttrs; ///< parameter attributes for call + const 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); @@ -762,17 +850,10 @@ class CallInst : public Instruction { // 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::difference_type NumArgs = - std::distance(ArgBegin, ArgEnd); - - if (NumArgs > 0) { - // This requires that the iterator points to contiguous memory. - init(Func, &*ArgBegin, NumArgs); - } - else { - init(Func, 0, NumArgs); - } + unsigned NumArgs = (unsigned)std::distance(ArgBegin, ArgEnd); + // This requires that the iterator points to contiguous memory. + init(Func, NumArgs ? &*ArgBegin : 0, NumArgs); setName(Name); } @@ -836,18 +917,42 @@ public: /// parameter attributes information, if any. /// @returns 0 if no attributes have been set. /// @brief Get the parameter attributes. - ParamAttrsList *getParamAttrs() const { return ParamAttrs; } + const 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); + void setParamAttrs(const ParamAttrsList *attrs); + + /// @brief Determine whether the call or the callee has the given attribute. + bool paramHasAttr(uint16_t i, ParameterAttributes attr) const; + + /// @brief Determine if the call does not access memory. + bool doesNotAccessMemory() const { + return paramHasAttr(0, ParamAttr::ReadNone); + } + + /// @brief Determine if the call does not access or only reads memory. + bool onlyReadsMemory() const { + return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly); + } + + /// @brief Determine if the call cannot unwind. + bool isNoUnwind() const { + return paramHasAttr(0, ParamAttr::NoUnwind); + } + + /// @brief Determine if the call returns a structure. + bool isStructReturn() const { + // Be friendly and also check the callee. + return paramHasAttr(1, ParamAttr::StructRet); + } /// 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(dyn_cast(getOperand(0))); + return dyn_cast(getOperand(0)); } /// getCalledValue - Get a pointer to the function that is invoked by this @@ -1540,17 +1645,62 @@ private: /// calling convention of the call. /// class InvokeInst : public TerminatorInst { - ParamAttrsList *ParamAttrs; + const ParamAttrsList *ParamAttrs; InvokeInst(const InvokeInst &BI); void init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, Value* const *Args, unsigned NumArgs); + + template + 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 + InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, + InputIterator ArgBegin, InputIterator ArgEnd, + const std::string &Name = "", Instruction *InsertBefore = 0) + : TerminatorInst(cast(cast(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Invoke, 0, 0, InsertBefore) { + init(Func, IfNormal, IfException, ArgBegin, ArgEnd, Name, + typename std::iterator_traits::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 + InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, + InputIterator ArgBegin, InputIterator ArgEnd, + const std::string &Name, BasicBlock *InsertAtEnd) + : TerminatorInst(cast(cast(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Invoke, 0, 0, InsertAtEnd) { + init(Func, IfNormal, IfException, ArgBegin, ArgEnd, Name, + typename std::iterator_traits::iterator_category()); + } + ~InvokeInst(); virtual InvokeInst *clone() const; @@ -1566,12 +1716,36 @@ public: /// parameter attributes information, if any. /// @returns 0 if no attributes have been set. /// @brief Get the parameter attributes. - ParamAttrsList *getParamAttrs() const { return ParamAttrs; } + const 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); + void setParamAttrs(const ParamAttrsList *attrs); + + /// @brief Determine whether the call or the callee has the given attribute. + bool paramHasAttr(uint16_t i, ParameterAttributes attr) const; + + /// @brief Determine if the call does not access memory. + bool doesNotAccessMemory() const { + return paramHasAttr(0, ParamAttr::ReadNone); + } + + /// @brief Determine if the call does not access or only reads memory. + bool onlyReadsMemory() const { + return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly); + } + + /// @brief Determine if the call cannot unwind. + bool isNoUnwind() const { + return paramHasAttr(0, ParamAttr::NoUnwind); + } + + /// @brief Determine if the call returns a structure. + bool isStructReturn() const { + // Be friendly and also check the callee. + return paramHasAttr(1, ParamAttr::StructRet); + } /// getCalledFunction - Return the function called, or null if this is an /// indirect function invocation.