forked from OSchip/llvm-project
IR: Add ConstantData, for operand-less Constants
Add a common parent `ConstantData` to the constants that have no operands. These are guaranteed to represent abstract data that is in no way tied to a specific Module. This is a good cleanup on its own. It also makes it simpler to disallow RAUW (and factor away use-lists) on these constants in the future. (I have some experimental patches that make RAUW illegal on ConstantData, and they seem to catch a bunch of bugs...) llvm-svn: 261464
This commit is contained in:
parent
78f46bea08
commit
b6452798a5
|
@ -40,26 +40,47 @@ class SequentialType;
|
||||||
struct ConstantExprKeyType;
|
struct ConstantExprKeyType;
|
||||||
template <class ConstantClass> struct ConstantAggrKeyType;
|
template <class ConstantClass> struct ConstantAggrKeyType;
|
||||||
|
|
||||||
|
/// Base class for constants with no operands.
|
||||||
|
///
|
||||||
|
/// These constants have no operands; they represent their data directly.
|
||||||
|
/// Since they can be in use by unrelated modules (and are never based on
|
||||||
|
/// GlobalValues), it never makes sensee to RAUW them.
|
||||||
|
class ConstantData : public Constant {
|
||||||
|
void anchor() override;
|
||||||
|
void *operator new(size_t, unsigned) = delete;
|
||||||
|
ConstantData() = delete;
|
||||||
|
ConstantData(const ConstantData &) = delete;
|
||||||
|
|
||||||
|
friend class Constant;
|
||||||
|
Value *handleOperandChangeImpl(Value *From, Value *To) {
|
||||||
|
llvm_unreachable("Constant data does not have operands!");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit ConstantData(Type *Ty, ValueTy VT) : Constant(Ty, VT, nullptr, 0) {}
|
||||||
|
void *operator new(size_t s) { return User::operator new(s, 0); }
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Methods to support type inquiry through isa, cast, and dyn_cast.
|
||||||
|
static bool classof(const Value *V) {
|
||||||
|
return V->getValueID() >= ConstantDataFirstVal &&
|
||||||
|
V->getValueID() <= ConstantDataLastVal;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
/// This is the shared class of boolean and integer constants. This class
|
/// This is the shared class of boolean and integer constants. This class
|
||||||
/// represents both boolean and integral constants.
|
/// represents both boolean and integral constants.
|
||||||
/// @brief Class for constant integers.
|
/// @brief Class for constant integers.
|
||||||
class ConstantInt : public Constant {
|
class ConstantInt : public ConstantData {
|
||||||
void anchor() override;
|
void anchor() override;
|
||||||
void *operator new(size_t, unsigned) = delete;
|
|
||||||
ConstantInt(const ConstantInt &) = delete;
|
ConstantInt(const ConstantInt &) = delete;
|
||||||
ConstantInt(IntegerType *Ty, const APInt& V);
|
ConstantInt(IntegerType *Ty, const APInt& V);
|
||||||
APInt Val;
|
APInt Val;
|
||||||
|
|
||||||
friend class Constant;
|
friend class Constant;
|
||||||
void destroyConstantImpl();
|
void destroyConstantImpl();
|
||||||
Value *handleOperandChangeImpl(Value *From, Value *To);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// allocate space for exactly zero operands
|
|
||||||
void *operator new(size_t s) {
|
|
||||||
return User::operator new(s, 0);
|
|
||||||
}
|
|
||||||
public:
|
public:
|
||||||
static ConstantInt *getTrue(LLVMContext &Context);
|
static ConstantInt *getTrue(LLVMContext &Context);
|
||||||
static ConstantInt *getFalse(LLVMContext &Context);
|
static ConstantInt *getFalse(LLVMContext &Context);
|
||||||
|
@ -230,24 +251,17 @@ public:
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
/// ConstantFP - Floating Point Values [float, double]
|
/// ConstantFP - Floating Point Values [float, double]
|
||||||
///
|
///
|
||||||
class ConstantFP : public Constant {
|
class ConstantFP : public ConstantData {
|
||||||
APFloat Val;
|
APFloat Val;
|
||||||
void anchor() override;
|
void anchor() override;
|
||||||
void *operator new(size_t, unsigned) = delete;
|
|
||||||
ConstantFP(const ConstantFP &) = delete;
|
ConstantFP(const ConstantFP &) = delete;
|
||||||
friend class LLVMContextImpl;
|
|
||||||
|
|
||||||
friend class Constant;
|
friend class Constant;
|
||||||
void destroyConstantImpl();
|
void destroyConstantImpl();
|
||||||
Value *handleOperandChangeImpl(Value *From, Value *To);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ConstantFP(Type *Ty, const APFloat& V);
|
ConstantFP(Type *Ty, const APFloat& V);
|
||||||
protected:
|
|
||||||
// allocate space for exactly zero operands
|
|
||||||
void *operator new(size_t s) {
|
|
||||||
return User::operator new(s, 0);
|
|
||||||
}
|
|
||||||
public:
|
public:
|
||||||
/// Floating point negation must be implemented with f(x) = -0.0 - x. This
|
/// Floating point negation must be implemented with f(x) = -0.0 - x. This
|
||||||
/// method returns the negative zero constant for floating point or vector
|
/// method returns the negative zero constant for floating point or vector
|
||||||
|
@ -304,22 +318,16 @@ public:
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
/// All zero aggregate value
|
/// All zero aggregate value
|
||||||
///
|
///
|
||||||
class ConstantAggregateZero : public Constant {
|
class ConstantAggregateZero : public ConstantData {
|
||||||
void *operator new(size_t, unsigned) = delete;
|
|
||||||
ConstantAggregateZero(const ConstantAggregateZero &) = delete;
|
ConstantAggregateZero(const ConstantAggregateZero &) = delete;
|
||||||
|
|
||||||
friend class Constant;
|
friend class Constant;
|
||||||
void destroyConstantImpl();
|
void destroyConstantImpl();
|
||||||
Value *handleOperandChangeImpl(Value *From, Value *To);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit ConstantAggregateZero(Type *ty)
|
explicit ConstantAggregateZero(Type *Ty)
|
||||||
: Constant(ty, ConstantAggregateZeroVal, nullptr, 0) {}
|
: ConstantData(Ty, ConstantAggregateZeroVal) {}
|
||||||
protected:
|
|
||||||
// allocate space for exactly zero operands
|
|
||||||
void *operator new(size_t s) {
|
|
||||||
return User::operator new(s, 0);
|
|
||||||
}
|
|
||||||
public:
|
public:
|
||||||
static ConstantAggregateZero *get(Type *Ty);
|
static ConstantAggregateZero *get(Type *Ty);
|
||||||
|
|
||||||
|
@ -503,24 +511,16 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantVector, Constant)
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
/// A constant pointer value that points to null
|
/// A constant pointer value that points to null
|
||||||
///
|
///
|
||||||
class ConstantPointerNull : public Constant {
|
class ConstantPointerNull : public ConstantData {
|
||||||
void *operator new(size_t, unsigned) = delete;
|
|
||||||
ConstantPointerNull(const ConstantPointerNull &) = delete;
|
ConstantPointerNull(const ConstantPointerNull &) = delete;
|
||||||
|
|
||||||
friend class Constant;
|
friend class Constant;
|
||||||
void destroyConstantImpl();
|
void destroyConstantImpl();
|
||||||
Value *handleOperandChangeImpl(Value *From, Value *To);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit ConstantPointerNull(PointerType *T)
|
explicit ConstantPointerNull(PointerType *T)
|
||||||
: Constant(T,
|
: ConstantData(T, Value::ConstantPointerNullVal) {}
|
||||||
Value::ConstantPointerNullVal, nullptr, 0) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// allocate space for exactly zero operands
|
|
||||||
void *operator new(size_t s) {
|
|
||||||
return User::operator new(s, 0);
|
|
||||||
}
|
|
||||||
public:
|
public:
|
||||||
/// Static factory methods - Return objects of the specified value
|
/// Static factory methods - Return objects of the specified value
|
||||||
static ConstantPointerNull *get(PointerType *T);
|
static ConstantPointerNull *get(PointerType *T);
|
||||||
|
@ -546,7 +546,7 @@ public:
|
||||||
///
|
///
|
||||||
/// This is the common base class of ConstantDataArray and ConstantDataVector.
|
/// This is the common base class of ConstantDataArray and ConstantDataVector.
|
||||||
///
|
///
|
||||||
class ConstantDataSequential : public Constant {
|
class ConstantDataSequential : public ConstantData {
|
||||||
friend class LLVMContextImpl;
|
friend class LLVMContextImpl;
|
||||||
/// A pointer to the bytes underlying this constant (which is owned by the
|
/// A pointer to the bytes underlying this constant (which is owned by the
|
||||||
/// uniquing StringMap).
|
/// uniquing StringMap).
|
||||||
|
@ -557,27 +557,19 @@ class ConstantDataSequential : public Constant {
|
||||||
/// element array of i8, or a 1-element array of i32. They'll both end up in
|
/// element array of i8, or a 1-element array of i32. They'll both end up in
|
||||||
/// the same StringMap bucket, linked up.
|
/// the same StringMap bucket, linked up.
|
||||||
ConstantDataSequential *Next;
|
ConstantDataSequential *Next;
|
||||||
void *operator new(size_t, unsigned) = delete;
|
|
||||||
ConstantDataSequential(const ConstantDataSequential &) = delete;
|
ConstantDataSequential(const ConstantDataSequential &) = delete;
|
||||||
|
|
||||||
friend class Constant;
|
friend class Constant;
|
||||||
void destroyConstantImpl();
|
void destroyConstantImpl();
|
||||||
Value *handleOperandChangeImpl(Value *From, Value *To);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit ConstantDataSequential(Type *ty, ValueTy VT, const char *Data)
|
explicit ConstantDataSequential(Type *ty, ValueTy VT, const char *Data)
|
||||||
: Constant(ty, VT, nullptr, 0), DataElements(Data), Next(nullptr) {}
|
: ConstantData(ty, VT), DataElements(Data), Next(nullptr) {}
|
||||||
~ConstantDataSequential() override { delete Next; }
|
~ConstantDataSequential() override { delete Next; }
|
||||||
|
|
||||||
static Constant *getImpl(StringRef Bytes, Type *Ty);
|
static Constant *getImpl(StringRef Bytes, Type *Ty);
|
||||||
|
|
||||||
protected:
|
|
||||||
// Allocate space for exactly zero operands.
|
|
||||||
void *operator new(size_t s) {
|
|
||||||
return User::operator new(s, 0);
|
|
||||||
}
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Return true if a ConstantDataSequential can be formed with a vector or
|
/// Return true if a ConstantDataSequential can be formed with a vector or
|
||||||
/// array of the specified element type.
|
/// array of the specified element type.
|
||||||
/// ConstantDataArray only works with normal float and int types that are
|
/// ConstantDataArray only works with normal float and int types that are
|
||||||
|
@ -780,19 +772,15 @@ public:
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
/// A constant token which is empty
|
/// A constant token which is empty
|
||||||
///
|
///
|
||||||
class ConstantTokenNone : public Constant {
|
class ConstantTokenNone : public ConstantData {
|
||||||
void *operator new(size_t, unsigned) = delete;
|
|
||||||
ConstantTokenNone(const ConstantTokenNone &) = delete;
|
ConstantTokenNone(const ConstantTokenNone &) = delete;
|
||||||
|
|
||||||
friend class Constant;
|
friend class Constant;
|
||||||
void destroyConstantImpl();
|
void destroyConstantImpl();
|
||||||
Value *handleOperandChangeImpl(Value *From, Value *To);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit ConstantTokenNone(LLVMContext &Context)
|
explicit ConstantTokenNone(LLVMContext &Context)
|
||||||
: Constant(Type::getTokenTy(Context), ConstantTokenNoneVal, nullptr, 0) {}
|
: ConstantData(Type::getTokenTy(Context), ConstantTokenNoneVal) {}
|
||||||
// allocate space for exactly zero operands
|
|
||||||
void *operator new(size_t s) { return User::operator new(s, 0); }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Return the ConstantTokenNone.
|
/// Return the ConstantTokenNone.
|
||||||
|
@ -1223,21 +1211,15 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantExpr, Constant)
|
||||||
/// can appear to have different bit patterns at each use. See
|
/// can appear to have different bit patterns at each use. See
|
||||||
/// LangRef.html#undefvalues for details.
|
/// LangRef.html#undefvalues for details.
|
||||||
///
|
///
|
||||||
class UndefValue : public Constant {
|
class UndefValue : public ConstantData {
|
||||||
void *operator new(size_t, unsigned) = delete;
|
|
||||||
UndefValue(const UndefValue &) = delete;
|
UndefValue(const UndefValue &) = delete;
|
||||||
|
|
||||||
friend class Constant;
|
friend class Constant;
|
||||||
void destroyConstantImpl();
|
void destroyConstantImpl();
|
||||||
Value *handleOperandChangeImpl(Value *From, Value *To);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit UndefValue(Type *T) : Constant(T, UndefValueVal, nullptr, 0) {}
|
explicit UndefValue(Type *T) : ConstantData(T, UndefValueVal) {}
|
||||||
protected:
|
|
||||||
// allocate space for exactly zero operands
|
|
||||||
void *operator new(size_t s) {
|
|
||||||
return User::operator new(s, 0);
|
|
||||||
}
|
|
||||||
public:
|
public:
|
||||||
/// Static factory methods - Return an 'undef' object of the specified type.
|
/// Static factory methods - Return an 'undef' object of the specified type.
|
||||||
static UndefValue *get(Type *T);
|
static UndefValue *get(Type *T);
|
||||||
|
|
|
@ -61,17 +61,19 @@ HANDLE_VALUE(MemoryPhi)
|
||||||
HANDLE_GLOBAL_VALUE(Function)
|
HANDLE_GLOBAL_VALUE(Function)
|
||||||
HANDLE_GLOBAL_VALUE(GlobalAlias)
|
HANDLE_GLOBAL_VALUE(GlobalAlias)
|
||||||
HANDLE_GLOBAL_VALUE(GlobalVariable)
|
HANDLE_GLOBAL_VALUE(GlobalVariable)
|
||||||
HANDLE_CONSTANT(UndefValue)
|
|
||||||
HANDLE_CONSTANT(BlockAddress)
|
HANDLE_CONSTANT(BlockAddress)
|
||||||
HANDLE_CONSTANT(ConstantExpr)
|
HANDLE_CONSTANT(ConstantExpr)
|
||||||
|
HANDLE_CONSTANT(ConstantArray)
|
||||||
|
HANDLE_CONSTANT(ConstantStruct)
|
||||||
|
HANDLE_CONSTANT(ConstantVector)
|
||||||
|
|
||||||
|
// ConstantData.
|
||||||
|
HANDLE_CONSTANT(UndefValue)
|
||||||
HANDLE_CONSTANT(ConstantAggregateZero)
|
HANDLE_CONSTANT(ConstantAggregateZero)
|
||||||
HANDLE_CONSTANT(ConstantDataArray)
|
HANDLE_CONSTANT(ConstantDataArray)
|
||||||
HANDLE_CONSTANT(ConstantDataVector)
|
HANDLE_CONSTANT(ConstantDataVector)
|
||||||
HANDLE_CONSTANT(ConstantInt)
|
HANDLE_CONSTANT(ConstantInt)
|
||||||
HANDLE_CONSTANT(ConstantFP)
|
HANDLE_CONSTANT(ConstantFP)
|
||||||
HANDLE_CONSTANT(ConstantArray)
|
|
||||||
HANDLE_CONSTANT(ConstantStruct)
|
|
||||||
HANDLE_CONSTANT(ConstantVector)
|
|
||||||
HANDLE_CONSTANT(ConstantPointerNull)
|
HANDLE_CONSTANT(ConstantPointerNull)
|
||||||
HANDLE_CONSTANT(ConstantTokenNone)
|
HANDLE_CONSTANT(ConstantTokenNone)
|
||||||
|
|
||||||
|
@ -84,6 +86,8 @@ HANDLE_INSTRUCTION(Instruction)
|
||||||
|
|
||||||
HANDLE_CONSTANT_MARKER(ConstantFirstVal, Function)
|
HANDLE_CONSTANT_MARKER(ConstantFirstVal, Function)
|
||||||
HANDLE_CONSTANT_MARKER(ConstantLastVal, ConstantTokenNone)
|
HANDLE_CONSTANT_MARKER(ConstantLastVal, ConstantTokenNone)
|
||||||
|
HANDLE_CONSTANT_MARKER(ConstantDataFirstVal, UndefValue)
|
||||||
|
HANDLE_CONSTANT_MARKER(ConstantDataLastVal, ConstantTokenNone)
|
||||||
|
|
||||||
#undef HANDLE_GLOBAL_VALUE
|
#undef HANDLE_GLOBAL_VALUE
|
||||||
#undef HANDLE_CONSTANT
|
#undef HANDLE_CONSTANT
|
||||||
|
|
|
@ -27,6 +27,7 @@ class Argument;
|
||||||
class AssemblyAnnotationWriter;
|
class AssemblyAnnotationWriter;
|
||||||
class BasicBlock;
|
class BasicBlock;
|
||||||
class Constant;
|
class Constant;
|
||||||
|
class ConstantData;
|
||||||
class DataLayout;
|
class DataLayout;
|
||||||
class Function;
|
class Function;
|
||||||
class GlobalAlias;
|
class GlobalAlias;
|
||||||
|
@ -685,6 +686,13 @@ template <> struct isa_impl<Constant, Value> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <> struct isa_impl<ConstantData, Value> {
|
||||||
|
static inline bool doit(const Value &Val) {
|
||||||
|
return Val.getValueID() >= Value::ConstantDataFirstVal &&
|
||||||
|
Val.getValueID() <= Value::ConstantDataLastVal;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <> struct isa_impl<Argument, Value> {
|
template <> struct isa_impl<Argument, Value> {
|
||||||
static inline bool doit (const Value &Val) {
|
static inline bool doit (const Value &Val) {
|
||||||
return Val.getValueID() == Value::ArgumentVal;
|
return Val.getValueID() == Value::ArgumentVal;
|
||||||
|
|
|
@ -42,6 +42,8 @@ using namespace llvm;
|
||||||
|
|
||||||
void Constant::anchor() { }
|
void Constant::anchor() { }
|
||||||
|
|
||||||
|
void ConstantData::anchor() {}
|
||||||
|
|
||||||
bool Constant::isNegativeZeroValue() const {
|
bool Constant::isNegativeZeroValue() const {
|
||||||
// Floating point values have an explicit -0.0 value.
|
// Floating point values have an explicit -0.0 value.
|
||||||
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
|
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
|
||||||
|
@ -521,8 +523,8 @@ void Constant::removeDeadConstantUsers() const {
|
||||||
|
|
||||||
void ConstantInt::anchor() { }
|
void ConstantInt::anchor() { }
|
||||||
|
|
||||||
ConstantInt::ConstantInt(IntegerType *Ty, const APInt& V)
|
ConstantInt::ConstantInt(IntegerType *Ty, const APInt &V)
|
||||||
: Constant(Ty, ConstantIntVal, nullptr, 0), Val(V) {
|
: ConstantData(Ty, ConstantIntVal), Val(V) {
|
||||||
assert(V.getBitWidth() == Ty->getBitWidth() && "Invalid constant for type");
|
assert(V.getBitWidth() == Ty->getBitWidth() && "Invalid constant for type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,8 +750,8 @@ Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) {
|
||||||
return C;
|
return C;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstantFP::ConstantFP(Type *Ty, const APFloat& V)
|
ConstantFP::ConstantFP(Type *Ty, const APFloat &V)
|
||||||
: Constant(Ty, ConstantFPVal, nullptr, 0), Val(V) {
|
: ConstantData(Ty, ConstantFPVal), Val(V) {
|
||||||
assert(&V.getSemantics() == TypeToFloatSemantics(Ty) &&
|
assert(&V.getSemantics() == TypeToFloatSemantics(Ty) &&
|
||||||
"FP type Mismatch");
|
"FP type Mismatch");
|
||||||
}
|
}
|
||||||
|
@ -2816,34 +2818,6 @@ void Constant::handleOperandChange(Value *From, Value *To) {
|
||||||
destroyConstant();
|
destroyConstant();
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *ConstantInt::handleOperandChangeImpl(Value *From, Value *To) {
|
|
||||||
llvm_unreachable("Unsupported class for handleOperandChange()!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *ConstantFP::handleOperandChangeImpl(Value *From, Value *To) {
|
|
||||||
llvm_unreachable("Unsupported class for handleOperandChange()!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *ConstantTokenNone::handleOperandChangeImpl(Value *From, Value *To) {
|
|
||||||
llvm_unreachable("Unsupported class for handleOperandChange()!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *UndefValue::handleOperandChangeImpl(Value *From, Value *To) {
|
|
||||||
llvm_unreachable("Unsupported class for handleOperandChange()!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *ConstantPointerNull::handleOperandChangeImpl(Value *From, Value *To) {
|
|
||||||
llvm_unreachable("Unsupported class for handleOperandChange()!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *ConstantAggregateZero::handleOperandChangeImpl(Value *From, Value *To) {
|
|
||||||
llvm_unreachable("Unsupported class for handleOperandChange()!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *ConstantDataSequential::handleOperandChangeImpl(Value *From, Value *To) {
|
|
||||||
llvm_unreachable("Unsupported class for handleOperandChange()!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *ConstantArray::handleOperandChangeImpl(Value *From, Value *To) {
|
Value *ConstantArray::handleOperandChangeImpl(Value *From, Value *To) {
|
||||||
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
|
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
|
||||||
Constant *ToC = cast<Constant>(To);
|
Constant *ToC = cast<Constant>(To);
|
||||||
|
|
Loading…
Reference in New Issue