/// which represent the different flavors of constant values that live in LLVM.
/// Note that Constants are immutable (once created they never change) and are
/// fully shared by structural equivalence. This means that two structurally
-/// equivalent constants will always have the same address. Constant's are
+/// equivalent constants will always have the same address. Constants are
/// created on demand as needed and never deleted: thus clients don't have to
/// worry about the lifetime of the objects.
//
class VectorType;
class SequentialType;
-template<class ConstantClass, class TypeClass, class ValType>
-struct ConstantCreator;
-template<class ConstantClass, class TypeClass>
-struct ConstantArrayCreator;
-template<class ConstantClass, class TypeClass>
-struct ConvertConstantType;
+struct ConstantExprKeyType;
+template <class ConstantClass> struct ConstantAggrKeyType;
//===----------------------------------------------------------------------===//
/// This is the shared class of boolean and integer constants. This class
/// @brief Class for constant integers.
class ConstantInt : public Constant {
void anchor() override;
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- ConstantInt(const ConstantInt &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ ConstantInt(const ConstantInt &) = delete;
ConstantInt(IntegerType *Ty, const APInt& V);
APInt Val;
+
+ friend class Constant;
+ void destroyConstantImpl();
+ Value *handleOperandChangeImpl(Value *From, Value *To, Use *U);
+
protected:
// allocate space for exactly zero operands
void *operator new(size_t s) {
class ConstantFP : public Constant {
APFloat Val;
void anchor() override;
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- ConstantFP(const ConstantFP &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ ConstantFP(const ConstantFP &) = delete;
friend class LLVMContextImpl;
+
+ friend class Constant;
+ void destroyConstantImpl();
+ Value *handleOperandChangeImpl(Value *From, Value *To, Use *U);
+
protected:
ConstantFP(Type *Ty, const APFloat& V);
protected:
static Constant *get(Type* Ty, double V);
static Constant *get(Type* Ty, StringRef Str);
static ConstantFP *get(LLVMContext &Context, const APFloat &V);
+ static Constant *getNaN(Type *Ty, bool Negative = false, unsigned type = 0);
static Constant *getNegativeZero(Type *Ty);
static Constant *getInfinity(Type *Ty, bool Negative = false);
/// isNegative - Return true if the sign bit is set.
bool isNegative() const { return Val.isNegative(); }
+ /// isInfinity - Return true if the value is infinity
+ bool isInfinity() const { return Val.isInfinity(); }
+
/// isNaN - Return true if the value is a NaN.
bool isNaN() const { return Val.isNaN(); }
/// ConstantAggregateZero - All zero aggregate value
///
class ConstantAggregateZero : public Constant {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- ConstantAggregateZero(const ConstantAggregateZero &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ ConstantAggregateZero(const ConstantAggregateZero &) = delete;
+
+ friend class Constant;
+ void destroyConstantImpl();
+ Value *handleOperandChangeImpl(Value *From, Value *To, Use *U);
+
protected:
explicit ConstantAggregateZero(Type *ty)
: Constant(ty, ConstantAggregateZeroVal, nullptr, 0) {}
public:
static ConstantAggregateZero *get(Type *Ty);
- void destroyConstant() override;
-
/// getSequentialElement - If this CAZ has array or vector type, return a zero
/// with the right element type.
Constant *getSequentialElement() const;
/// index.
Constant *getElementValue(unsigned Idx) const;
+ /// \brief Return the number of elements in the array, vector, or struct.
+ unsigned getNumElements() const;
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
///
static bool classof(const Value *V) {
/// ConstantArray - Constant Array Declarations
///
class ConstantArray : public Constant {
- friend struct ConstantArrayCreator<ConstantArray, ArrayType>;
- ConstantArray(const ConstantArray &) LLVM_DELETED_FUNCTION;
+ friend struct ConstantAggrKeyType<ConstantArray>;
+ ConstantArray(const ConstantArray &) = delete;
+
+ friend class Constant;
+ void destroyConstantImpl();
+ Value *handleOperandChangeImpl(Value *From, Value *To, Use *U);
+
protected:
ConstantArray(ArrayType *T, ArrayRef<Constant *> Val);
public:
// ConstantArray accessors
static Constant *get(ArrayType *T, ArrayRef<Constant*> V);
+private:
+ static Constant *getImpl(ArrayType *T, ArrayRef<Constant *> V);
+
+public:
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
return cast<ArrayType>(Value::getType());
}
- void destroyConstant() override;
- void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
return V->getValueID() == ConstantArrayVal;
// ConstantStruct - Constant Struct Declarations
//
class ConstantStruct : public Constant {
- friend struct ConstantArrayCreator<ConstantStruct, StructType>;
- ConstantStruct(const ConstantStruct &) LLVM_DELETED_FUNCTION;
+ friend struct ConstantAggrKeyType<ConstantStruct>;
+ ConstantStruct(const ConstantStruct &) = delete;
+
+ friend class Constant;
+ void destroyConstantImpl();
+ Value *handleOperandChangeImpl(Value *From, Value *To, Use *U);
+
protected:
ConstantStruct(StructType *T, ArrayRef<Constant *> Val);
public:
// ConstantStruct accessors
static Constant *get(StructType *T, ArrayRef<Constant*> V);
- static Constant *get(StructType *T, ...) END_WITH_NULL;
+ static Constant *get(StructType *T, ...) LLVM_END_WITH_NULL;
/// getAnon - Return an anonymous struct that has the specified
/// elements. If the struct is possibly empty, then you must specify a
return cast<StructType>(Value::getType());
}
- void destroyConstant() override;
- void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
return V->getValueID() == ConstantStructVal;
/// ConstantVector - Constant Vector Declarations
///
class ConstantVector : public Constant {
- friend struct ConstantArrayCreator<ConstantVector, VectorType>;
- ConstantVector(const ConstantVector &) LLVM_DELETED_FUNCTION;
+ friend struct ConstantAggrKeyType<ConstantVector>;
+ ConstantVector(const ConstantVector &) = delete;
+
+ friend class Constant;
+ void destroyConstantImpl();
+ Value *handleOperandChangeImpl(Value *From, Value *To, Use *U);
+
protected:
ConstantVector(VectorType *T, ArrayRef<Constant *> Val);
public:
// ConstantVector accessors
static Constant *get(ArrayRef<Constant*> V);
+private:
+ static Constant *getImpl(ArrayRef<Constant *> V);
+
+public:
/// getSplat - Return a ConstantVector with the specified constant in each
/// element.
static Constant *getSplat(unsigned NumElts, Constant *Elt);
/// elements have the same value, return that value. Otherwise return NULL.
Constant *getSplatValue() const;
- void destroyConstant() override;
- void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
return V->getValueID() == ConstantVectorVal;
/// ConstantPointerNull - a constant pointer value that points to null
///
class ConstantPointerNull : public Constant {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- ConstantPointerNull(const ConstantPointerNull &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ ConstantPointerNull(const ConstantPointerNull &) = delete;
+
+ friend class Constant;
+ void destroyConstantImpl();
+ Value *handleOperandChangeImpl(Value *From, Value *To, Use *U);
+
protected:
explicit ConstantPointerNull(PointerType *T)
: Constant(T,
/// get() - Static factory methods - Return objects of the specified value
static ConstantPointerNull *get(PointerType *T);
- void destroyConstant() override;
-
/// getType - Specialize the getType() method to always return an PointerType,
/// which reduces the amount of casting needed in parts of the compiler.
///
/// element array of i8, or a 1-element array of i32. They'll both end up in
/// the same StringMap bucket, linked up.
ConstantDataSequential *Next;
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- ConstantDataSequential(const ConstantDataSequential &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ ConstantDataSequential(const ConstantDataSequential &) = delete;
+
+ friend class Constant;
+ void destroyConstantImpl();
+ Value *handleOperandChangeImpl(Value *From, Value *To, Use *U);
+
protected:
explicit ConstantDataSequential(Type *ty, ValueTy VT, const char *Data)
: Constant(ty, VT, nullptr, 0), DataElements(Data), Next(nullptr) {}
- ~ConstantDataSequential() { delete Next; }
+ ~ConstantDataSequential() override { delete Next; }
static Constant *getImpl(StringRef Bytes, Type *Ty);
/// formed with a vector or array of the specified element type.
/// ConstantDataArray only works with normal float and int types that are
/// stored densely in memory, not with things like i42 or x86_f80.
- static bool isElementTypeCompatible(const Type *Ty);
+ static bool isElementTypeCompatible(Type *Ty);
/// getElementAsInteger - If this is a sequential container of integers (of
/// any size), return the specified element in the low bits of a uint64_t.
/// host endianness of the data elements.
StringRef getRawDataValues() const;
- void destroyConstant() override;
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
///
static bool classof(const Value *V) {
/// operands because it stores all of the elements of the constant as densely
/// packed data, instead of as Value*'s.
class ConstantDataArray : public ConstantDataSequential {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- ConstantDataArray(const ConstantDataArray &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ ConstantDataArray(const ConstantDataArray &) = delete;
void anchor() override;
friend class ConstantDataSequential;
explicit ConstantDataArray(Type *ty, const char *Data)
static Constant *get(LLVMContext &Context, ArrayRef<float> Elts);
static Constant *get(LLVMContext &Context, ArrayRef<double> Elts);
+ /// getFP() constructors - Return a constant with array type with an element
+ /// count and element type of float with precision matching the number of
+ /// bits in the ArrayRef passed in. (i.e. half for 16bits, float for 32bits,
+ /// double for 64bits) Note that this can return a ConstantAggregateZero
+ /// object.
+ static Constant *getFP(LLVMContext &Context, ArrayRef<uint16_t> Elts);
+ static Constant *getFP(LLVMContext &Context, ArrayRef<uint32_t> Elts);
+ static Constant *getFP(LLVMContext &Context, ArrayRef<uint64_t> Elts);
+
/// getString - This method constructs a CDS and initializes it with a text
/// string. The default behavior (AddNull==true) causes a null terminator to
/// be placed at the end of the array (increasing the length of the string by
/// operands because it stores all of the elements of the constant as densely
/// packed data, instead of as Value*'s.
class ConstantDataVector : public ConstantDataSequential {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- ConstantDataVector(const ConstantDataVector &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ ConstantDataVector(const ConstantDataVector &) = delete;
void anchor() override;
friend class ConstantDataSequential;
explicit ConstantDataVector(Type *ty, const char *Data)
static Constant *get(LLVMContext &Context, ArrayRef<float> Elts);
static Constant *get(LLVMContext &Context, ArrayRef<double> Elts);
+ /// getFP() constructors - Return a constant with vector type with an element
+ /// count and element type of float with the precision matching the number of
+ /// bits in the ArrayRef passed in. (i.e. half for 16bits, float for 32bits,
+ /// double for 64bits) Note that this can return a ConstantAggregateZero
+ /// object.
+ static Constant *getFP(LLVMContext &Context, ArrayRef<uint16_t> Elts);
+ static Constant *getFP(LLVMContext &Context, ArrayRef<uint32_t> Elts);
+ static Constant *getFP(LLVMContext &Context, ArrayRef<uint64_t> Elts);
+
/// getSplat - Return a ConstantVector with the specified constant in each
/// element. The specified constant has to be a of a compatible type (i8/i16/
/// i32/i64/float/double) and must be a ConstantFP or ConstantInt.
}
};
+//===----------------------------------------------------------------------===//
+/// ConstantTokenNone - a constant token which is empty
+///
+class ConstantTokenNone : public Constant {
+ void *operator new(size_t, unsigned) = delete;
+ ConstantTokenNone(const ConstantTokenNone &) = delete;
+
+ friend class Constant;
+ void destroyConstantImpl();
+ Value *handleOperandChangeImpl(Value *From, Value *To, Use *U);
+protected:
+ explicit ConstantTokenNone(LLVMContext &Context)
+ : Constant(Type::getTokenTy(Context), ConstantTokenNoneVal, nullptr, 0) {}
+ // allocate space for exactly zero operands
+ void *operator new(size_t s) { return User::operator new(s, 0); }
+
+public:
+ /// Return the ConstantTokenNone.
+ static ConstantTokenNone *get(LLVMContext &Context);
+
+ /// @brief Methods to support type inquiry through isa, cast, and dyn_cast.
+ static bool classof(const Value *V) {
+ return V->getValueID() == ConstantTokenNoneVal;
+ }
+};
/// BlockAddress - The address of a basic block.
///
class BlockAddress : public Constant {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
void *operator new(size_t s) { return User::operator new(s, 2); }
BlockAddress(Function *F, BasicBlock *BB);
+
+ friend class Constant;
+ void destroyConstantImpl();
+ Value *handleOperandChangeImpl(Value *From, Value *To, Use *U);
+
public:
/// get - Return a BlockAddress for the specified function and basic block.
static BlockAddress *get(Function *F, BasicBlock *BB);
Function *getFunction() const { return (Function*)Op<0>().get(); }
BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); }
- void destroyConstant() override;
- void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Value *V) {
return V->getValueID() == BlockAddressVal;
/// constant expressions. The Opcode field for the ConstantExpr class is
/// maintained in the Value::SubclassData field.
class ConstantExpr : public Constant {
- friend struct ConstantCreator<ConstantExpr,Type,
- std::pair<unsigned, std::vector<Constant*> > >;
- friend struct ConvertConstantType<ConstantExpr, Type>;
+ friend struct ConstantExprKeyType;
+
+ friend class Constant;
+ void destroyConstantImpl();
+ Value *handleOperandChangeImpl(Value *From, Value *To, Use *U);
protected:
ConstantExpr(Type *ty, unsigned Opcode, Use *Ops, unsigned NumOps)
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, Type *Ty);
- static Constant *getSExt (Constant *C, Type *Ty);
- static Constant *getZExt (Constant *C, Type *Ty);
- static Constant *getFPTrunc (Constant *C, Type *Ty);
- static Constant *getFPExtend(Constant *C, Type *Ty);
- static Constant *getUIToFP (Constant *C, Type *Ty);
- static Constant *getSIToFP (Constant *C, Type *Ty);
- static Constant *getFPToUI (Constant *C, Type *Ty);
- static Constant *getFPToSI (Constant *C, Type *Ty);
- static Constant *getPtrToInt(Constant *C, Type *Ty);
- static Constant *getIntToPtr(Constant *C, Type *Ty);
- static Constant *getBitCast (Constant *C, Type *Ty);
- static Constant *getAddrSpaceCast(Constant *C, Type *Ty);
+ static Constant *getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced = false);
+ static Constant *getSExt(Constant *C, Type *Ty, bool OnlyIfReduced = false);
+ static Constant *getZExt(Constant *C, Type *Ty, bool OnlyIfReduced = false);
+ static Constant *getFPTrunc(Constant *C, Type *Ty,
+ bool OnlyIfReduced = false);
+ static Constant *getFPExtend(Constant *C, Type *Ty,
+ bool OnlyIfReduced = false);
+ static Constant *getUIToFP(Constant *C, Type *Ty, bool OnlyIfReduced = false);
+ static Constant *getSIToFP(Constant *C, Type *Ty, bool OnlyIfReduced = false);
+ static Constant *getFPToUI(Constant *C, Type *Ty, bool OnlyIfReduced = false);
+ static Constant *getFPToSI(Constant *C, Type *Ty, bool OnlyIfReduced = false);
+ static Constant *getPtrToInt(Constant *C, Type *Ty,
+ bool OnlyIfReduced = false);
+ static Constant *getIntToPtr(Constant *C, Type *Ty,
+ bool OnlyIfReduced = false);
+ static Constant *getBitCast(Constant *C, Type *Ty,
+ bool OnlyIfReduced = false);
+ static Constant *getAddrSpaceCast(Constant *C, Type *Ty,
+ bool OnlyIfReduced = false);
static Constant *getNSWNeg(Constant *C) { return getNeg(C, false, true); }
static Constant *getNUWNeg(Constant *C) { return getNeg(C, true, false); }
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
- // @brief Convenience function for getting one of the casting operations
- // using a CastOps opcode.
- static Constant *getCast(
- unsigned ops, ///< The opcode for the conversion
- Constant *C, ///< The constant to be converted
- Type *Ty ///< The type to which the constant is converted
- );
+ /// \brief Convenience function for getting a Cast operation.
+ ///
+ /// \param ops The opcode for the conversion
+ /// \param C The constant to be converted
+ /// \param Ty The type to which the constant is converted
+ /// \param OnlyIfReduced see \a getWithOperands() docs.
+ static Constant *getCast(unsigned ops, Constant *C, Type *Ty,
+ bool OnlyIfReduced = false);
// @brief Create a ZExt or BitCast cast constant expression
static Constant *getZExtOrBitCast(
/// Select constant expr
///
- static Constant *getSelect(Constant *C, Constant *V1, Constant *V2);
+ /// \param OnlyIfReducedTy see \a getWithOperands() docs.
+ static Constant *getSelect(Constant *C, Constant *V1, Constant *V2,
+ Type *OnlyIfReducedTy = nullptr);
/// get - Return a binary or shift operator constant expression,
/// folding if possible.
///
+ /// \param OnlyIfReducedTy see \a getWithOperands() docs.
static Constant *get(unsigned Opcode, Constant *C1, Constant *C2,
- unsigned Flags = 0);
+ unsigned Flags = 0, Type *OnlyIfReducedTy = nullptr);
- /// @brief Return an ICmp or FCmp comparison operator constant expression.
- static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2);
+ /// \brief Return an ICmp or FCmp comparison operator constant expression.
+ ///
+ /// \param OnlyIfReduced see \a getWithOperands() docs.
+ static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2,
+ bool OnlyIfReduced = false);
/// get* - Return some common constants without having to
/// specify the full Instruction::OPCODE identifier.
///
- static Constant *getICmp(unsigned short pred, Constant *LHS, Constant *RHS);
- static Constant *getFCmp(unsigned short pred, Constant *LHS, Constant *RHS);
+ static Constant *getICmp(unsigned short pred, Constant *LHS, Constant *RHS,
+ bool OnlyIfReduced = false);
+ static Constant *getFCmp(unsigned short pred, Constant *LHS, Constant *RHS,
+ bool OnlyIfReduced = false);
/// Getelementptr form. Value* is only accepted for convenience;
- /// all elements must be Constant's.
+ /// all elements must be Constants.
///
- static Constant *getGetElementPtr(Constant *C,
+ /// \param OnlyIfReducedTy see \a getWithOperands() docs.
+ static Constant *getGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList,
- bool InBounds = false) {
- return getGetElementPtr(C, makeArrayRef((Value * const *)IdxList.data(),
- IdxList.size()),
- InBounds);
- }
- static Constant *getGetElementPtr(Constant *C,
- Constant *Idx,
- bool InBounds = false) {
+ bool InBounds = false,
+ Type *OnlyIfReducedTy = nullptr) {
+ return getGetElementPtr(
+ Ty, C, makeArrayRef((Value * const *)IdxList.data(), IdxList.size()),
+ InBounds, OnlyIfReducedTy);
+ }
+ static Constant *getGetElementPtr(Type *Ty, Constant *C, Constant *Idx,
+ bool InBounds = false,
+ Type *OnlyIfReducedTy = nullptr) {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
- return getGetElementPtr(C, cast<Value>(Idx), InBounds);
+ return getGetElementPtr(Ty, C, cast<Value>(Idx), InBounds, OnlyIfReducedTy);
}
- static Constant *getGetElementPtr(Constant *C,
+ static Constant *getGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList,
- bool InBounds = false);
+ bool InBounds = false,
+ Type *OnlyIfReducedTy = nullptr);
/// Create an "inbounds" getelementptr. See the documentation for the
/// "inbounds" flag in LangRef.html for details.
- static Constant *getInBoundsGetElementPtr(Constant *C,
+ static Constant *getInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) {
- return getGetElementPtr(C, IdxList, true);
+ return getGetElementPtr(Ty, C, IdxList, true);
}
- static Constant *getInBoundsGetElementPtr(Constant *C,
+ static Constant *getInBoundsGetElementPtr(Type *Ty, Constant *C,
Constant *Idx) {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
- return getGetElementPtr(C, Idx, true);
+ return getGetElementPtr(Ty, C, Idx, true);
}
- static Constant *getInBoundsGetElementPtr(Constant *C,
+ static Constant *getInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) {
- return getGetElementPtr(C, IdxList, true);
+ return getGetElementPtr(Ty, C, IdxList, 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, ArrayRef<unsigned> Idxs);
+ static Constant *getExtractElement(Constant *Vec, Constant *Idx,
+ Type *OnlyIfReducedTy = nullptr);
+ static Constant *getInsertElement(Constant *Vec, Constant *Elt, Constant *Idx,
+ Type *OnlyIfReducedTy = nullptr);
+ static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask,
+ Type *OnlyIfReducedTy = nullptr);
+ static Constant *getExtractValue(Constant *Agg, ArrayRef<unsigned> Idxs,
+ Type *OnlyIfReducedTy = nullptr);
static Constant *getInsertValue(Constant *Agg, Constant *Val,
- ArrayRef<unsigned> Idxs);
+ ArrayRef<unsigned> Idxs,
+ Type *OnlyIfReducedTy = nullptr);
/// getOpcode - Return the opcode at the root of this constant expression
unsigned getOpcode() const { return getSubclassDataFromValue(); }
return getWithOperands(Ops, getType());
}
- /// 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, Type *Ty) const;
-
- /// getAsInstruction - Returns an Instruction which implements the same operation
- /// as this ConstantExpr. The instruction is not linked to any basic block.
+ /// \brief Get the current expression with the operands replaced.
+ ///
+ /// Return the current constant expression with the operands replaced with \c
+ /// Ops and the type with \c Ty. The new operands must have the same number
+ /// as the current ones.
+ ///
+ /// If \c OnlyIfReduced is \c true, nullptr will be returned unless something
+ /// gets constant-folded, the type changes, or the expression is otherwise
+ /// canonicalized. This parameter should almost always be \c false.
+ Constant *getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
+ bool OnlyIfReduced = false,
+ Type *SrcTy = nullptr) const;
+
+ /// getAsInstruction - Returns an Instruction which implements the same
+ /// operation as this ConstantExpr. The instruction is not linked to any basic
+ /// block.
///
/// A better approach to this could be to have a constructor for Instruction
/// which would take a ConstantExpr parameter, but that would have spread
/// would make it harder to remove ConstantExprs altogether.
Instruction *getAsInstruction();
- void destroyConstant() override;
- void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Value *V) {
return V->getValueID() == ConstantExprVal;
/// LangRef.html#undefvalues for details.
///
class UndefValue : public Constant {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- UndefValue(const UndefValue &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ UndefValue(const UndefValue &) = delete;
+
+ friend class Constant;
+ void destroyConstantImpl();
+ Value *handleOperandChangeImpl(Value *From, Value *To, Use *U);
+
protected:
explicit UndefValue(Type *T) : Constant(T, UndefValueVal, nullptr, 0) {}
protected:
/// index.
UndefValue *getElementValue(unsigned Idx) const;
- void destroyConstant() override;
+ /// \brief Return the number of elements in the array, vector, or struct.
+ unsigned getNumElements() const;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {