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;
|
||||
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
|
||||
/// represents both boolean and integral constants.
|
||||
/// @brief Class for constant integers.
|
||||
class ConstantInt : public Constant {
|
||||
class ConstantInt : public ConstantData {
|
||||
void anchor() override;
|
||||
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);
|
||||
|
||||
protected:
|
||||
// allocate space for exactly zero operands
|
||||
void *operator new(size_t s) {
|
||||
return User::operator new(s, 0);
|
||||
}
|
||||
public:
|
||||
static ConstantInt *getTrue(LLVMContext &Context);
|
||||
static ConstantInt *getFalse(LLVMContext &Context);
|
||||
|
@ -230,24 +251,17 @@ public:
|
|||
//===----------------------------------------------------------------------===//
|
||||
/// ConstantFP - Floating Point Values [float, double]
|
||||
///
|
||||
class ConstantFP : public Constant {
|
||||
class ConstantFP : public ConstantData {
|
||||
APFloat Val;
|
||||
void anchor() override;
|
||||
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);
|
||||
|
||||
protected:
|
||||
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:
|
||||
/// Floating point negation must be implemented with f(x) = -0.0 - x. This
|
||||
/// method returns the negative zero constant for floating point or vector
|
||||
|
@ -304,22 +318,16 @@ public:
|
|||
//===----------------------------------------------------------------------===//
|
||||
/// All zero aggregate value
|
||||
///
|
||||
class ConstantAggregateZero : public Constant {
|
||||
void *operator new(size_t, unsigned) = delete;
|
||||
class ConstantAggregateZero : public ConstantData {
|
||||
ConstantAggregateZero(const ConstantAggregateZero &) = delete;
|
||||
|
||||
friend class Constant;
|
||||
void destroyConstantImpl();
|
||||
Value *handleOperandChangeImpl(Value *From, Value *To);
|
||||
|
||||
protected:
|
||||
explicit ConstantAggregateZero(Type *ty)
|
||||
: Constant(ty, ConstantAggregateZeroVal, nullptr, 0) {}
|
||||
protected:
|
||||
// allocate space for exactly zero operands
|
||||
void *operator new(size_t s) {
|
||||
return User::operator new(s, 0);
|
||||
}
|
||||
explicit ConstantAggregateZero(Type *Ty)
|
||||
: ConstantData(Ty, ConstantAggregateZeroVal) {}
|
||||
|
||||
public:
|
||||
static ConstantAggregateZero *get(Type *Ty);
|
||||
|
||||
|
@ -503,24 +511,16 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantVector, Constant)
|
|||
//===----------------------------------------------------------------------===//
|
||||
/// A constant pointer value that points to null
|
||||
///
|
||||
class ConstantPointerNull : public Constant {
|
||||
void *operator new(size_t, unsigned) = delete;
|
||||
class ConstantPointerNull : public ConstantData {
|
||||
ConstantPointerNull(const ConstantPointerNull &) = delete;
|
||||
|
||||
friend class Constant;
|
||||
void destroyConstantImpl();
|
||||
Value *handleOperandChangeImpl(Value *From, Value *To);
|
||||
|
||||
protected:
|
||||
explicit ConstantPointerNull(PointerType *T)
|
||||
: Constant(T,
|
||||
Value::ConstantPointerNullVal, nullptr, 0) {}
|
||||
: ConstantData(T, Value::ConstantPointerNullVal) {}
|
||||
|
||||
protected:
|
||||
// allocate space for exactly zero operands
|
||||
void *operator new(size_t s) {
|
||||
return User::operator new(s, 0);
|
||||
}
|
||||
public:
|
||||
/// Static factory methods - Return objects of the specified value
|
||||
static ConstantPointerNull *get(PointerType *T);
|
||||
|
@ -546,7 +546,7 @@ public:
|
|||
///
|
||||
/// This is the common base class of ConstantDataArray and ConstantDataVector.
|
||||
///
|
||||
class ConstantDataSequential : public Constant {
|
||||
class ConstantDataSequential : public ConstantData {
|
||||
friend class LLVMContextImpl;
|
||||
/// A pointer to the bytes underlying this constant (which is owned by the
|
||||
/// 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
|
||||
/// the same StringMap bucket, linked up.
|
||||
ConstantDataSequential *Next;
|
||||
void *operator new(size_t, unsigned) = delete;
|
||||
ConstantDataSequential(const ConstantDataSequential &) = delete;
|
||||
|
||||
friend class Constant;
|
||||
void destroyConstantImpl();
|
||||
Value *handleOperandChangeImpl(Value *From, Value *To);
|
||||
|
||||
protected:
|
||||
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; }
|
||||
|
||||
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:
|
||||
|
||||
/// Return true if a ConstantDataSequential can be formed with a vector or
|
||||
/// array of the specified element type.
|
||||
/// ConstantDataArray only works with normal float and int types that are
|
||||
|
@ -780,19 +772,15 @@ public:
|
|||
//===----------------------------------------------------------------------===//
|
||||
/// A constant token which is empty
|
||||
///
|
||||
class ConstantTokenNone : public Constant {
|
||||
void *operator new(size_t, unsigned) = delete;
|
||||
class ConstantTokenNone : public ConstantData {
|
||||
ConstantTokenNone(const ConstantTokenNone &) = delete;
|
||||
|
||||
friend class Constant;
|
||||
void destroyConstantImpl();
|
||||
Value *handleOperandChangeImpl(Value *From, Value *To);
|
||||
|
||||
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); }
|
||||
: ConstantData(Type::getTokenTy(Context), ConstantTokenNoneVal) {}
|
||||
|
||||
public:
|
||||
/// Return the ConstantTokenNone.
|
||||
|
@ -1223,21 +1211,15 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantExpr, Constant)
|
|||
/// can appear to have different bit patterns at each use. See
|
||||
/// LangRef.html#undefvalues for details.
|
||||
///
|
||||
class UndefValue : public Constant {
|
||||
void *operator new(size_t, unsigned) = delete;
|
||||
class UndefValue : public ConstantData {
|
||||
UndefValue(const UndefValue &) = delete;
|
||||
|
||||
friend class Constant;
|
||||
void destroyConstantImpl();
|
||||
Value *handleOperandChangeImpl(Value *From, Value *To);
|
||||
|
||||
protected:
|
||||
explicit UndefValue(Type *T) : Constant(T, UndefValueVal, nullptr, 0) {}
|
||||
protected:
|
||||
// allocate space for exactly zero operands
|
||||
void *operator new(size_t s) {
|
||||
return User::operator new(s, 0);
|
||||
}
|
||||
explicit UndefValue(Type *T) : ConstantData(T, UndefValueVal) {}
|
||||
|
||||
public:
|
||||
/// Static factory methods - Return an 'undef' object of the specified type.
|
||||
static UndefValue *get(Type *T);
|
||||
|
|
|
@ -61,17 +61,19 @@ HANDLE_VALUE(MemoryPhi)
|
|||
HANDLE_GLOBAL_VALUE(Function)
|
||||
HANDLE_GLOBAL_VALUE(GlobalAlias)
|
||||
HANDLE_GLOBAL_VALUE(GlobalVariable)
|
||||
HANDLE_CONSTANT(UndefValue)
|
||||
HANDLE_CONSTANT(BlockAddress)
|
||||
HANDLE_CONSTANT(ConstantExpr)
|
||||
HANDLE_CONSTANT(ConstantArray)
|
||||
HANDLE_CONSTANT(ConstantStruct)
|
||||
HANDLE_CONSTANT(ConstantVector)
|
||||
|
||||
// ConstantData.
|
||||
HANDLE_CONSTANT(UndefValue)
|
||||
HANDLE_CONSTANT(ConstantAggregateZero)
|
||||
HANDLE_CONSTANT(ConstantDataArray)
|
||||
HANDLE_CONSTANT(ConstantDataVector)
|
||||
HANDLE_CONSTANT(ConstantInt)
|
||||
HANDLE_CONSTANT(ConstantFP)
|
||||
HANDLE_CONSTANT(ConstantArray)
|
||||
HANDLE_CONSTANT(ConstantStruct)
|
||||
HANDLE_CONSTANT(ConstantVector)
|
||||
HANDLE_CONSTANT(ConstantPointerNull)
|
||||
HANDLE_CONSTANT(ConstantTokenNone)
|
||||
|
||||
|
@ -84,6 +86,8 @@ HANDLE_INSTRUCTION(Instruction)
|
|||
|
||||
HANDLE_CONSTANT_MARKER(ConstantFirstVal, Function)
|
||||
HANDLE_CONSTANT_MARKER(ConstantLastVal, ConstantTokenNone)
|
||||
HANDLE_CONSTANT_MARKER(ConstantDataFirstVal, UndefValue)
|
||||
HANDLE_CONSTANT_MARKER(ConstantDataLastVal, ConstantTokenNone)
|
||||
|
||||
#undef HANDLE_GLOBAL_VALUE
|
||||
#undef HANDLE_CONSTANT
|
||||
|
|
|
@ -27,6 +27,7 @@ class Argument;
|
|||
class AssemblyAnnotationWriter;
|
||||
class BasicBlock;
|
||||
class Constant;
|
||||
class ConstantData;
|
||||
class DataLayout;
|
||||
class Function;
|
||||
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> {
|
||||
static inline bool doit (const Value &Val) {
|
||||
return Val.getValueID() == Value::ArgumentVal;
|
||||
|
|
|
@ -42,6 +42,8 @@ using namespace llvm;
|
|||
|
||||
void Constant::anchor() { }
|
||||
|
||||
void ConstantData::anchor() {}
|
||||
|
||||
bool Constant::isNegativeZeroValue() const {
|
||||
// Floating point values have an explicit -0.0 value.
|
||||
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
|
||||
|
@ -521,8 +523,8 @@ void Constant::removeDeadConstantUsers() const {
|
|||
|
||||
void ConstantInt::anchor() { }
|
||||
|
||||
ConstantInt::ConstantInt(IntegerType *Ty, const APInt& V)
|
||||
: Constant(Ty, ConstantIntVal, nullptr, 0), Val(V) {
|
||||
ConstantInt::ConstantInt(IntegerType *Ty, const APInt &V)
|
||||
: ConstantData(Ty, ConstantIntVal), Val(V) {
|
||||
assert(V.getBitWidth() == Ty->getBitWidth() && "Invalid constant for type");
|
||||
}
|
||||
|
||||
|
@ -748,8 +750,8 @@ Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) {
|
|||
return C;
|
||||
}
|
||||
|
||||
ConstantFP::ConstantFP(Type *Ty, const APFloat& V)
|
||||
: Constant(Ty, ConstantFPVal, nullptr, 0), Val(V) {
|
||||
ConstantFP::ConstantFP(Type *Ty, const APFloat &V)
|
||||
: ConstantData(Ty, ConstantFPVal), Val(V) {
|
||||
assert(&V.getSemantics() == TypeToFloatSemantics(Ty) &&
|
||||
"FP type Mismatch");
|
||||
}
|
||||
|
@ -2816,34 +2818,6 @@ void Constant::handleOperandChange(Value *From, Value *To) {
|
|||
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) {
|
||||
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
|
||||
Constant *ToC = cast<Constant>(To);
|
||||
|
|
Loading…
Reference in New Issue