#include "llvm/OperandTraits.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/SmallVector.h"
-#include <vector>
+#include "llvm/ADT/ArrayRef.h"
namespace llvm {
public:
static ConstantInt *getTrue(LLVMContext &Context);
static ConstantInt *getFalse(LLVMContext &Context);
+ static Constant *getTrue(const Type *Ty);
+ static Constant *getFalse(const Type *Ty);
/// If Ty is a vector type, return a Constant with a splat of the given
/// value. Otherwise return a ConstantInt for the given value.
/// Return a ConstantInt constructed from the string strStart with the given
/// radix.
- static ConstantInt *get(const IntegerType *Ty, const StringRef &Str,
+ static ConstantInt *get(const IntegerType *Ty, StringRef Str,
uint8_t radix);
/// If Ty is a vector type, return a Constant with a splat of the given
/// only be used for simple constant values like 2.0/1.0 etc, that are
/// known-valid both as host double and as the target format.
static Constant *get(const Type* Ty, double V);
- static Constant *get(const Type* Ty, const StringRef &Str);
+ static Constant *get(const Type* Ty, StringRef Str);
static ConstantFP *get(LLVMContext &Context, const APFloat &V);
static ConstantFP *getNegativeZero(const Type* Ty);
static ConstantFP *getInfinity(const Type *Ty, bool Negative = false);
inline const APFloat& getValueAPF() const { return Val; }
/// isNullValue - Return true if this is the value that would be returned by
- /// getNullValue. Don't depend on == for doubles to tell us it's zero, it
- /// considers -0.0 to be null as well as 0.0. :(
+ /// getNullValue. For ConstantFP, this is +0.0, but not -0.0. To handle the
+ /// two the same, use isZero().
virtual bool isNullValue() const;
/// isNegativeZeroValue - Return true if the value is what would be returned
return Val.isZero() && Val.isNegative();
}
+ /// isZero - Return true if the value is positive or negative zero.
+ bool isZero() const { return Val.isZero(); }
+
+ /// isNaN - Return true if the value is a NaN.
+ bool isNaN() const { return Val.isNaN(); }
+
/// isExactlyValue - We don't rely on operator== working on double values, as
/// it returns true for things that are clearly not equal, like -0.0 and 0.0.
/// As such, this method can be used to do an exact bit-for-bit comparison of
ConstantArray(const ArrayType *T, const std::vector<Constant*> &Val);
public:
// ConstantArray accessors
- static Constant *get(const ArrayType *T, const std::vector<Constant*> &V);
- static Constant *get(const ArrayType *T, Constant *const *Vals,
- unsigned NumVals);
+ static Constant *get(const ArrayType *T, ArrayRef<Constant*> V);
/// This method constructs a ConstantArray and initializes it with a text
/// string. The default behavior (AddNull==true) causes a null terminator to
/// of the array by one (you've been warned). However, in some situations
/// this is not desired so if AddNull==false then the string is copied without
/// null termination.
- static Constant *get(LLVMContext &Context, const StringRef &Initializer,
+ static Constant *get(LLVMContext &Context, StringRef Initializer,
bool AddNull = true);
/// Transparently provide more efficient getOperand methods.
///
std::string getAsString() const;
+ /// getAsCString - If this array is isCString(), then this method converts the
+ /// array (without the trailing null byte) to an std::string and returns it.
+ /// Otherwise, it asserts out.
+ ///
+ std::string getAsCString() const;
+
/// isNullValue - Return true if this is the value that would be returned by
/// getNullValue. This always returns false because zero arrays are always
/// created as ConstantAggregateZero objects.
};
template <>
-struct OperandTraits<ConstantArray> : public VariadicOperandTraits<> {
+struct OperandTraits<ConstantArray> :
+ public VariadicOperandTraits<ConstantArray> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantArray, Constant)
ConstantStruct(const StructType *T, const std::vector<Constant*> &Val);
public:
// ConstantStruct accessors
- static Constant *get(const StructType *T, const std::vector<Constant*> &V);
- static Constant *get(LLVMContext &Context,
- const std::vector<Constant*> &V, bool Packed);
- static Constant *get(LLVMContext &Context,
- Constant *const *Vals, unsigned NumVals, bool Packed);
-
+ static Constant *get(const StructType *T, ArrayRef<Constant*> V);
+ static Constant *get(const StructType *T, ...) END_WITH_NULL;
+
+ /// getAnon - Return an anonymous struct that has the specified
+ /// elements. If the struct is possibly empty, then you must specify a
+ /// context.
+ static Constant *getAnon(ArrayRef<Constant*> V, bool Packed = false) {
+ return get(getTypeForElements(V, Packed), V);
+ }
+ static Constant *getAnon(LLVMContext &Ctx,
+ ArrayRef<Constant*> V, bool Packed = false) {
+ return get(getTypeForElements(Ctx, V, Packed), V);
+ }
+
+ /// getTypeForElements - Return an anonymous struct type to use for a constant
+ /// with the specified set of elements. The list must not be empty.
+ static StructType *getTypeForElements(ArrayRef<Constant*> V,
+ bool Packed = false);
+ /// getTypeForElements - This version of the method allows an empty list.
+ static StructType *getTypeForElements(LLVMContext &Ctx,
+ ArrayRef<Constant*> V,
+ bool Packed = false);
+
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
};
template <>
-struct OperandTraits<ConstantStruct> : public VariadicOperandTraits<> {
+struct OperandTraits<ConstantStruct> :
+ public VariadicOperandTraits<ConstantStruct> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantStruct, Constant)
+
//===----------------------------------------------------------------------===//
/// ConstantVector - Constant Vector Declarations
///
ConstantVector(const VectorType *T, const std::vector<Constant*> &Val);
public:
// ConstantVector accessors
- static Constant *get(const VectorType *T, const std::vector<Constant*> &V);
- static Constant *get(const std::vector<Constant*> &V);
- static Constant *get(Constant *const *Vals, unsigned NumVals);
+ static Constant *get(ArrayRef<Constant*> V);
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
/// getSplatValue - If this is a splat constant, meaning that all of the
/// elements have the same value, return that value. Otherwise return NULL.
- Constant *getSplatValue();
+ Constant *getSplatValue() const;
virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
};
template <>
-struct OperandTraits<ConstantVector> : public VariadicOperandTraits<> {
+struct OperandTraits<ConstantVector> :
+ public VariadicOperandTraits<ConstantVector> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantVector, Constant)
};
template <>
-struct OperandTraits<BlockAddress> : public FixedNumOperandTraits<2> {
+struct OperandTraits<BlockAddress> :
+ public FixedNumOperandTraits<BlockAddress, 2> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(BlockAddress, Value)
+
//===----------------------------------------------------------------------===//
/// ConstantExpr - a constant value that is initialized with an expression using
/// other constant values.
ConstantExpr(const Type *ty, unsigned Opcode, Use *Ops, unsigned NumOps)
: Constant(ty, ConstantExprVal, Ops, NumOps) {
// Operation type (an Instruction opcode) is stored as the SubclassData.
- SubclassData = Opcode;
- }
-
- // These private methods are used by the type resolution code to create
- // ConstantExprs in intermediate forms.
- static Constant *getTy(const Type *Ty, unsigned Opcode,
- Constant *C1, Constant *C2,
- unsigned Flags = 0);
- static Constant *getCompareTy(unsigned short pred, Constant *C1,
- Constant *C2);
- static Constant *getSelectTy(const Type *Ty,
- Constant *C1, Constant *C2, Constant *C3);
- static Constant *getGetElementPtrTy(const Type *Ty, Constant *C,
- Value* const *Idxs, unsigned NumIdxs);
- static Constant *getInBoundsGetElementPtrTy(const Type *Ty, Constant *C,
- Value* const *Idxs,
- unsigned NumIdxs);
- static Constant *getExtractElementTy(const Type *Ty, Constant *Val,
- Constant *Idx);
- static Constant *getInsertElementTy(const Type *Ty, Constant *Val,
- Constant *Elt, Constant *Idx);
- static Constant *getShuffleVectorTy(const Type *Ty, Constant *V1,
- Constant *V2, Constant *Mask);
- static Constant *getExtractValueTy(const Type *Ty, Constant *Agg,
- const unsigned *Idxs, unsigned NumIdxs);
- static Constant *getInsertValueTy(const Type *Ty, Constant *Agg,
- Constant *Val,
- const unsigned *Idxs, unsigned NumIdxs);
+ setValueSubclassData(Opcode);
+ }
public:
// Static methods to construct a ConstantExpr of different kinds. Note that
// ConstantExpr class, because they will attempt to fold the constant
// expression into something simpler if possible.
- /// Cast constant expr
- ///
-
/// getAlignOf constant expr - computes the alignment of a type in a target
- /// independent way (Note: the return type is an i32; Note: assumes that i8
- /// is byte aligned).
- static Constant *getAlignOf(const Type* Ty);
-
- /// getSizeOf constant expr - computes the size of a type in a target
/// independent way (Note: the return type is an i64).
+ static Constant *getAlignOf(const Type *Ty);
+
+ /// getSizeOf constant expr - computes the (alloc) size of a type (in
+ /// address-units, not bits) in a target independent way (Note: the return
+ /// type is an i64).
///
- static Constant *getSizeOf(const Type* Ty);
+ static Constant *getSizeOf(const Type *Ty);
- /// getOffsetOf constant expr - computes the offset of a field in a target
- /// independent way (Note: the return type is an i64).
+ /// getOffsetOf constant expr - computes the offset of a struct field in a
+ /// target independent way (Note: the return type is an i64).
+ ///
+ static Constant *getOffsetOf(const StructType *STy, unsigned FieldNo);
+
+ /// getOffsetOf constant expr - This is a generalized form of getOffsetOf,
+ /// which supports any aggregate type, and any Constant index.
///
- static Constant *getOffsetOf(const StructType* Ty, unsigned FieldNo);
+ static Constant *getOffsetOf(const Type *Ty, Constant *FieldNo);
- static Constant *getNeg(Constant *C);
+ static Constant *getNeg(Constant *C, bool HasNUW = false, bool HasNSW =false);
static Constant *getFNeg(Constant *C);
static Constant *getNot(Constant *C);
- static Constant *getAdd(Constant *C1, Constant *C2);
+ static Constant *getAdd(Constant *C1, Constant *C2,
+ bool HasNUW = false, bool HasNSW = false);
static Constant *getFAdd(Constant *C1, Constant *C2);
- static Constant *getSub(Constant *C1, Constant *C2);
+ static Constant *getSub(Constant *C1, Constant *C2,
+ bool HasNUW = false, bool HasNSW = false);
static Constant *getFSub(Constant *C1, Constant *C2);
- static Constant *getMul(Constant *C1, Constant *C2);
+ static Constant *getMul(Constant *C1, Constant *C2,
+ bool HasNUW = false, bool HasNSW = false);
static Constant *getFMul(Constant *C1, Constant *C2);
- static Constant *getUDiv(Constant *C1, Constant *C2);
- static Constant *getSDiv(Constant *C1, Constant *C2);
+ static Constant *getUDiv(Constant *C1, Constant *C2, bool isExact = false);
+ static Constant *getSDiv(Constant *C1, Constant *C2, bool isExact = false);
static Constant *getFDiv(Constant *C1, Constant *C2);
static Constant *getURem(Constant *C1, Constant *C2);
static Constant *getSRem(Constant *C1, Constant *C2);
static Constant *getAnd(Constant *C1, Constant *C2);
static Constant *getOr(Constant *C1, Constant *C2);
static Constant *getXor(Constant *C1, Constant *C2);
- static Constant *getShl(Constant *C1, Constant *C2);
- static Constant *getLShr(Constant *C1, Constant *C2);
- static Constant *getAShr(Constant *C1, Constant *C2);
+ static Constant *getShl(Constant *C1, Constant *C2,
+ bool HasNUW = false, bool HasNSW = false);
+ static Constant *getLShr(Constant *C1, Constant *C2, bool isExact = false);
+ static Constant *getAShr(Constant *C1, Constant *C2, bool isExact = false);
static Constant *getTrunc (Constant *C, const Type *Ty);
static Constant *getSExt (Constant *C, const Type *Ty);
static Constant *getZExt (Constant *C, const Type *Ty);
static Constant *getIntToPtr(Constant *C, const Type *Ty);
static Constant *getBitCast (Constant *C, const Type *Ty);
- static Constant *getNSWAdd(Constant *C1, Constant *C2);
- static Constant *getNSWSub(Constant *C1, Constant *C2);
- static Constant *getExactSDiv(Constant *C1, Constant *C2);
+ static Constant *getNSWNeg(Constant *C) { return getNeg(C, false, true); }
+ static Constant *getNUWNeg(Constant *C) { return getNeg(C, true, false); }
+ static Constant *getNSWAdd(Constant *C1, Constant *C2) {
+ return getAdd(C1, C2, false, true);
+ }
+ static Constant *getNUWAdd(Constant *C1, Constant *C2) {
+ return getAdd(C1, C2, true, false);
+ }
+ static Constant *getNSWSub(Constant *C1, Constant *C2) {
+ return getSub(C1, C2, false, true);
+ }
+ static Constant *getNUWSub(Constant *C1, Constant *C2) {
+ return getSub(C1, C2, true, false);
+ }
+ static Constant *getNSWMul(Constant *C1, Constant *C2) {
+ return getMul(C1, C2, false, true);
+ }
+ static Constant *getNUWMul(Constant *C1, Constant *C2) {
+ return getMul(C1, C2, true, false);
+ }
+ static Constant *getNSWShl(Constant *C1, Constant *C2) {
+ return getShl(C1, C2, false, true);
+ }
+ static Constant *getNUWShl(Constant *C1, Constant *C2) {
+ return getShl(C1, C2, true, false);
+ }
+ static Constant *getExactSDiv(Constant *C1, Constant *C2) {
+ return getSDiv(C1, C2, true);
+ }
+ static Constant *getExactUDiv(Constant *C1, Constant *C2) {
+ return getUDiv(C1, C2, true);
+ }
+ static Constant *getExactAShr(Constant *C1, Constant *C2) {
+ return getAShr(C1, C2, true);
+ }
+ static Constant *getExactLShr(Constant *C1, Constant *C2) {
+ return getLShr(C1, C2, true);
+ }
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
/// Select constant expr
///
- static Constant *getSelect(Constant *C, Constant *V1, Constant *V2) {
- return getSelectTy(V1->getType(), C, V1, V2);
- }
+ static Constant *getSelect(Constant *C, Constant *V1, Constant *V2);
/// get - Return a binary or shift operator constant expression,
/// folding if possible.
static Constant *getICmp(unsigned short pred, Constant *LHS, Constant *RHS);
static Constant *getFCmp(unsigned short pred, Constant *LHS, Constant *RHS);
- /// Getelementptr form. std::vector<Value*> is only accepted for convenience:
+ /// Getelementptr form. Value* is only accepted for convenience;
/// all elements must be Constant's.
///
static Constant *getGetElementPtr(Constant *C,
- Constant *const *IdxList, unsigned NumIdx);
+ Constant *const *IdxList, unsigned NumIdx,
+ bool InBounds = false) {
+ return getGetElementPtr(C, (Value**)IdxList, NumIdx, InBounds);
+ }
static Constant *getGetElementPtr(Constant *C,
- Value* const *IdxList, unsigned NumIdx);
+ Value *const *IdxList, unsigned NumIdx,
+ bool InBounds = false);
/// Create an "inbounds" getelementptr. See the documentation for the
/// "inbounds" flag in LangRef.html for details.
static Constant *getInBoundsGetElementPtr(Constant *C,
Constant *const *IdxList,
- unsigned NumIdx);
+ unsigned NumIdx) {
+ return getGetElementPtr(C, IdxList, NumIdx, true);
+ }
static Constant *getInBoundsGetElementPtr(Constant *C,
Value* const *IdxList,
- unsigned NumIdx);
+ unsigned NumIdx) {
+ return getGetElementPtr(C, IdxList, NumIdx, true);
+ }
static Constant *getExtractElement(Constant *Vec, Constant *Idx);
static Constant *getInsertElement(Constant *Vec, Constant *Elt,Constant *Idx);
static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask);
- static Constant *getExtractValue(Constant *Agg,
- const unsigned *IdxList, unsigned NumIdx);
+ static Constant *getExtractValue(Constant *Agg, ArrayRef<unsigned> Idxs);
static Constant *getInsertValue(Constant *Agg, Constant *Val,
- const unsigned *IdxList, unsigned NumIdx);
+ ArrayRef<unsigned> Idxs);
/// isNullValue - Return true if this is the value that would be returned by
/// getNullValue.
virtual bool isNullValue() const { return false; }
/// getOpcode - Return the opcode at the root of this constant expression
- unsigned getOpcode() const { return SubclassData; }
+ unsigned getOpcode() const { return getSubclassDataFromValue(); }
/// getPredicate - Return the ICMP or FCMP predicate value. Assert if this is
/// not an ICMP or FCMP constant expression.
/// getIndices - Assert that this is an insertvalue or exactvalue
/// expression and return the list of indices.
- const SmallVector<unsigned, 4> &getIndices() const;
+ ArrayRef<unsigned> getIndices() const;
/// getOpcodeName - Return a string representation for an opcode.
const char *getOpcodeName() const;
Constant *getWithOperandReplaced(unsigned OpNo, Constant *Op) const;
/// getWithOperands - This returns the current constant expression with the
- /// operands replaced with the specified values. The specified operands must
- /// match count and type with the existing ones.
- Constant *getWithOperands(const std::vector<Constant*> &Ops) const {
- return getWithOperands(&Ops[0], (unsigned)Ops.size());
+ /// operands replaced with the specified values. The specified array must
+ /// have the same number of operands as our current one.
+ Constant *getWithOperands(ArrayRef<Constant*> Ops) const {
+ return getWithOperands(Ops, getType());
}
- Constant *getWithOperands(Constant *const *Ops, unsigned NumOps) const;
-
+
+ /// getWithOperands - This returns the current constant expression with the
+ /// operands replaced with the specified values and with the specified result
+ /// type. The specified array must have the same number of operands as our
+ /// current one.
+ Constant *getWithOperands(ArrayRef<Constant*> Ops, const Type *Ty) const;
+
virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
static inline bool classof(const Value *V) {
return V->getValueID() == ConstantExprVal;
}
+
+private:
+ // Shadow Value::setValueSubclassData with a private forwarding method so that
+ // subclasses cannot accidentally use it.
+ void setValueSubclassData(unsigned short D) {
+ Value::setValueSubclassData(D);
+ }
};
template <>
-struct OperandTraits<ConstantExpr> : public VariadicOperandTraits<1> {
+struct OperandTraits<ConstantExpr> :
+ public VariadicOperandTraits<ConstantExpr, 1> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantExpr, Constant)
/// UndefValue - 'undef' values are things that do not have specified contents.
/// These are used for a variety of purposes, including global variable
/// initializers and operands to instructions. 'undef' values can occur with
-/// any type.
+/// any first-class type.
+///
+/// Undef values aren't exactly constants; if they have multiple uses, they
+/// can appear to have different bit patterns at each use. See
+/// LangRef.html#undefvalues for details.
///
class UndefValue : public Constant {
friend struct ConstantCreator<UndefValue, Type, char>;
return V->getValueID() == UndefValueVal;
}
};
+
} // End llvm namespace
#endif