mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-27 21:50:40 +00:00
IR: Introduce ConstantAggregate, NFC
Add a common parent class for ConstantArray, ConstantVector, and ConstantStruct called ConstantAggregate. These are the aggregate subclasses of Constant that take operands. This is mainly a cleanup, adding common `isa` target and removing duplicated code. However, it also simplifies caching which constants point transitively at `GlobalValue` (a possible future direction). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@265466 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3444a406d3
commit
d7773c0d39
@ -353,14 +353,43 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// Base class for aggregate constants (with operands).
|
||||
///
|
||||
/// These constants are aggregates of other constants, which are stored as
|
||||
/// operands.
|
||||
///
|
||||
/// Subclasses are \a ConstantStruct, \a ConstantArray, and \a
|
||||
/// ConstantVector.
|
||||
///
|
||||
/// \note Some subclasses of \a ConstantData are semantically aggregates --
|
||||
/// such as \a ConstantDataArray -- but are not subclasses of this because they
|
||||
/// use operands.
|
||||
class ConstantAggregate : public Constant {
|
||||
protected:
|
||||
ConstantAggregate(CompositeType *T, ValueTy VT, ArrayRef<Constant *> V);
|
||||
|
||||
public:
|
||||
/// Transparently provide more efficient getOperand methods.
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static bool classof(const Value *V) {
|
||||
return V->getValueID() >= ConstantAggregateFirstVal &&
|
||||
V->getValueID() <= ConstantAggregateLastVal;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OperandTraits<ConstantAggregate>
|
||||
: public VariadicOperandTraits<ConstantAggregate> {};
|
||||
|
||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantAggregate, Constant)
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// ConstantArray - Constant Array Declarations
|
||||
///
|
||||
class ConstantArray final : public Constant {
|
||||
class ConstantArray final : public ConstantAggregate {
|
||||
friend struct ConstantAggrKeyType<ConstantArray>;
|
||||
ConstantArray(const ConstantArray &) = delete;
|
||||
|
||||
friend class Constant;
|
||||
void destroyConstantImpl();
|
||||
Value *handleOperandChangeImpl(Value *From, Value *To);
|
||||
@ -375,9 +404,6 @@ private:
|
||||
static Constant *getImpl(ArrayType *T, ArrayRef<Constant *> V);
|
||||
|
||||
public:
|
||||
/// Transparently provide more efficient getOperand methods.
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
|
||||
|
||||
/// Specialize the getType() method to always return an ArrayType,
|
||||
/// which reduces the amount of casting needed in parts of the compiler.
|
||||
inline ArrayType *getType() const {
|
||||
@ -390,20 +416,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OperandTraits<ConstantArray> :
|
||||
public VariadicOperandTraits<ConstantArray> {
|
||||
};
|
||||
|
||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantArray, Constant)
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Constant Struct Declarations
|
||||
//
|
||||
class ConstantStruct final : public Constant {
|
||||
class ConstantStruct final : public ConstantAggregate {
|
||||
friend struct ConstantAggrKeyType<ConstantStruct>;
|
||||
ConstantStruct(const ConstantStruct &) = delete;
|
||||
|
||||
friend class Constant;
|
||||
void destroyConstantImpl();
|
||||
Value *handleOperandChangeImpl(Value *From, Value *To);
|
||||
@ -434,9 +451,6 @@ public:
|
||||
ArrayRef<Constant*> V,
|
||||
bool Packed = false);
|
||||
|
||||
/// Transparently provide more efficient getOperand methods.
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
|
||||
|
||||
/// Specialization - reduce amount of casting.
|
||||
inline StructType *getType() const {
|
||||
return cast<StructType>(Value::getType());
|
||||
@ -448,21 +462,12 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OperandTraits<ConstantStruct> :
|
||||
public VariadicOperandTraits<ConstantStruct> {
|
||||
};
|
||||
|
||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantStruct, Constant)
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// Constant Vector Declarations
|
||||
///
|
||||
class ConstantVector final : public Constant {
|
||||
class ConstantVector final : public ConstantAggregate {
|
||||
friend struct ConstantAggrKeyType<ConstantVector>;
|
||||
ConstantVector(const ConstantVector &) = delete;
|
||||
|
||||
friend class Constant;
|
||||
void destroyConstantImpl();
|
||||
Value *handleOperandChangeImpl(Value *From, Value *To);
|
||||
@ -480,9 +485,6 @@ public:
|
||||
/// Return a ConstantVector with the specified constant in each element.
|
||||
static Constant *getSplat(unsigned NumElts, Constant *Elt);
|
||||
|
||||
/// Transparently provide more efficient getOperand methods.
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
|
||||
|
||||
/// Specialize the getType() method to always return a VectorType,
|
||||
/// which reduces the amount of casting needed in parts of the compiler.
|
||||
inline VectorType *getType() const {
|
||||
@ -499,13 +501,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OperandTraits<ConstantVector> :
|
||||
public VariadicOperandTraits<ConstantVector> {
|
||||
};
|
||||
|
||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantVector, Constant)
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// A constant pointer value that points to null
|
||||
///
|
||||
|
@ -63,6 +63,8 @@ HANDLE_GLOBAL_VALUE(GlobalAlias)
|
||||
HANDLE_GLOBAL_VALUE(GlobalVariable)
|
||||
HANDLE_CONSTANT(BlockAddress)
|
||||
HANDLE_CONSTANT(ConstantExpr)
|
||||
|
||||
// ConstantAggregate.
|
||||
HANDLE_CONSTANT(ConstantArray)
|
||||
HANDLE_CONSTANT(ConstantStruct)
|
||||
HANDLE_CONSTANT(ConstantVector)
|
||||
@ -88,6 +90,8 @@ HANDLE_CONSTANT_MARKER(ConstantFirstVal, Function)
|
||||
HANDLE_CONSTANT_MARKER(ConstantLastVal, ConstantTokenNone)
|
||||
HANDLE_CONSTANT_MARKER(ConstantDataFirstVal, UndefValue)
|
||||
HANDLE_CONSTANT_MARKER(ConstantDataLastVal, ConstantTokenNone)
|
||||
HANDLE_CONSTANT_MARKER(ConstantAggregateFirstVal, ConstantArray)
|
||||
HANDLE_CONSTANT_MARKER(ConstantAggregateLastVal, ConstantVector)
|
||||
|
||||
#undef HANDLE_GLOBAL_VALUE
|
||||
#undef HANDLE_CONSTANT
|
||||
|
@ -28,6 +28,7 @@ class AssemblyAnnotationWriter;
|
||||
class BasicBlock;
|
||||
class Constant;
|
||||
class ConstantData;
|
||||
class ConstantAggregate;
|
||||
class DataLayout;
|
||||
class Function;
|
||||
class GlobalAlias;
|
||||
@ -701,6 +702,13 @@ template <> struct isa_impl<ConstantData, Value> {
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct isa_impl<ConstantAggregate, Value> {
|
||||
static inline bool doit(const Value &Val) {
|
||||
return Val.getValueID() >= Value::ConstantAggregateFirstVal &&
|
||||
Val.getValueID() <= Value::ConstantAggregateLastVal;
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct isa_impl<Argument, Value> {
|
||||
static inline bool doit (const Value &Val) {
|
||||
return Val.getValueID() == Value::ArgumentVal;
|
||||
|
@ -894,13 +894,12 @@ static bool canSkipAddingToSets(Value *Val) {
|
||||
// we should filter out the (potentially shared) instance to
|
||||
// i32* null.
|
||||
if (isa<Constant>(Val)) {
|
||||
bool Container = isa<ConstantVector>(Val) || isa<ConstantArray>(Val) ||
|
||||
isa<ConstantStruct>(Val);
|
||||
// TODO: Because all of these things are constant, we can determine whether
|
||||
// the data is *actually* mutable at graph building time. This will probably
|
||||
// come for free/cheap with offset awareness.
|
||||
bool CanStoreMutableData =
|
||||
isa<GlobalValue>(Val) || isa<ConstantExpr>(Val) || Container;
|
||||
bool CanStoreMutableData = isa<GlobalValue>(Val) ||
|
||||
isa<ConstantExpr>(Val) ||
|
||||
isa<ConstantAggregate>(Val);
|
||||
return !CanStoreMutableData;
|
||||
}
|
||||
|
||||
|
@ -1708,8 +1708,7 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
|
||||
Record.push_back(
|
||||
CDS->getElementAsAPFloat(i).bitcastToAPInt().getLimitedValue());
|
||||
}
|
||||
} else if (isa<ConstantArray>(C) || isa<ConstantStruct>(C) ||
|
||||
isa<ConstantVector>(C)) {
|
||||
} else if (isa<ConstantAggregate>(C)) {
|
||||
Code = bitc::CST_CODE_AGGREGATE;
|
||||
for (const Value *Op : C->operands())
|
||||
Record.push_back(VE.getValueID(Op));
|
||||
|
@ -270,14 +270,8 @@ Constant *Constant::getAllOnesValue(Type *Ty) {
|
||||
/// not. This can return null if the element index is a ConstantExpr, or if
|
||||
/// 'this' is a constant expr.
|
||||
Constant *Constant::getAggregateElement(unsigned Elt) const {
|
||||
if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(this))
|
||||
return Elt < CS->getNumOperands() ? CS->getOperand(Elt) : nullptr;
|
||||
|
||||
if (const ConstantArray *CA = dyn_cast<ConstantArray>(this))
|
||||
return Elt < CA->getNumOperands() ? CA->getOperand(Elt) : nullptr;
|
||||
|
||||
if (const ConstantVector *CV = dyn_cast<ConstantVector>(this))
|
||||
return Elt < CV->getNumOperands() ? CV->getOperand(Elt) : nullptr;
|
||||
if (const ConstantAggregate *CC = dyn_cast<ConstantAggregate>(this))
|
||||
return Elt < CC->getNumOperands() ? CC->getOperand(Elt) : nullptr;
|
||||
|
||||
if (const ConstantAggregateZero *CAZ = dyn_cast<ConstantAggregateZero>(this))
|
||||
return Elt < CAZ->getNumElements() ? CAZ->getElementValue(Elt) : nullptr;
|
||||
@ -912,16 +906,25 @@ static Constant *getSequenceIfElementsMatch(Constant *C,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ConstantArray::ConstantArray(ArrayType *T, ArrayRef<Constant *> V)
|
||||
: Constant(T, ConstantArrayVal,
|
||||
OperandTraits<ConstantArray>::op_end(this) - V.size(),
|
||||
ConstantAggregate::ConstantAggregate(CompositeType *T, ValueTy VT,
|
||||
ArrayRef<Constant *> V)
|
||||
: Constant(T, VT, OperandTraits<ConstantAggregate>::op_end(this) - V.size(),
|
||||
V.size()) {
|
||||
assert(V.size() == T->getNumElements() &&
|
||||
"Invalid initializer vector for constant array");
|
||||
for (unsigned i = 0, e = V.size(); i != e; ++i)
|
||||
assert(V[i]->getType() == T->getElementType() &&
|
||||
"Initializer for array element doesn't match array element type!");
|
||||
std::copy(V.begin(), V.end(), op_begin());
|
||||
|
||||
// Check that types match, unless this is an opaque struct.
|
||||
if (auto *ST = dyn_cast<StructType>(T))
|
||||
if (ST->isOpaque())
|
||||
return;
|
||||
for (unsigned I = 0, E = V.size(); I != E; ++I)
|
||||
assert(V[I]->getType() == T->getTypeAtIndex(I) &&
|
||||
"Initializer for composite element doesn't match!");
|
||||
}
|
||||
|
||||
ConstantArray::ConstantArray(ArrayType *T, ArrayRef<Constant *> V)
|
||||
: ConstantAggregate(T, ConstantArrayVal, V) {
|
||||
assert(V.size() == T->getNumElements() &&
|
||||
"Invalid initializer for constant array");
|
||||
}
|
||||
|
||||
Constant *ConstantArray::get(ArrayType *Ty, ArrayRef<Constant*> V) {
|
||||
@ -980,17 +983,10 @@ StructType *ConstantStruct::getTypeForElements(ArrayRef<Constant*> V,
|
||||
return getTypeForElements(V[0]->getContext(), V, Packed);
|
||||
}
|
||||
|
||||
|
||||
ConstantStruct::ConstantStruct(StructType *T, ArrayRef<Constant *> V)
|
||||
: Constant(T, ConstantStructVal,
|
||||
OperandTraits<ConstantStruct>::op_end(this) - V.size(),
|
||||
V.size()) {
|
||||
assert(V.size() == T->getNumElements() &&
|
||||
"Invalid initializer vector for constant structure");
|
||||
for (unsigned i = 0, e = V.size(); i != e; ++i)
|
||||
assert((T->isOpaque() || V[i]->getType() == T->getElementType(i)) &&
|
||||
"Initializer for struct element doesn't match struct element type!");
|
||||
std::copy(V.begin(), V.end(), op_begin());
|
||||
: ConstantAggregate(T, ConstantStructVal, V) {
|
||||
assert((T->isOpaque() || V.size() == T->getNumElements()) &&
|
||||
"Invalid initializer for constant struct");
|
||||
}
|
||||
|
||||
// ConstantStruct accessors.
|
||||
@ -1033,15 +1029,9 @@ Constant *ConstantStruct::get(StructType *T, ...) {
|
||||
}
|
||||
|
||||
ConstantVector::ConstantVector(VectorType *T, ArrayRef<Constant *> V)
|
||||
: Constant(T, ConstantVectorVal,
|
||||
OperandTraits<ConstantVector>::op_end(this) - V.size(),
|
||||
V.size()) {
|
||||
: ConstantAggregate(T, ConstantVectorVal, V) {
|
||||
assert(V.size() == T->getNumElements() &&
|
||||
"Invalid initializer vector for constant vector");
|
||||
for (size_t i = 0, e = V.size(); i != e; i++)
|
||||
assert(V[i]->getType() == T->getElementType() &&
|
||||
"Initializer for vector element doesn't match vector element type!");
|
||||
std::copy(V.begin(), V.end(), op_begin());
|
||||
"Invalid initializer for constant vector");
|
||||
}
|
||||
|
||||
// ConstantVector accessors.
|
||||
|
@ -1910,8 +1910,7 @@ void NVPTXAsmPrinter::bufferLEByte(const Constant *CPV, int Bytes,
|
||||
case Type::ArrayTyID:
|
||||
case Type::VectorTyID:
|
||||
case Type::StructTyID: {
|
||||
if (isa<ConstantArray>(CPV) || isa<ConstantVector>(CPV) ||
|
||||
isa<ConstantStruct>(CPV) || isa<ConstantDataSequential>(CPV)) {
|
||||
if (isa<ConstantAggregate>(CPV) || isa<ConstantDataSequential>(CPV)) {
|
||||
int ElementSize = DL.getTypeAllocSize(CPV->getType());
|
||||
bufferAggregateConstant(CPV, aggBuffer);
|
||||
if (Bytes > ElementSize)
|
||||
|
@ -230,8 +230,7 @@ Value *GenericToNVVM::remapConstant(Module *M, Function *F, Constant *C,
|
||||
if (I != GVMap.end()) {
|
||||
NewValue = getOrInsertCVTA(M, F, I->second, Builder);
|
||||
}
|
||||
} else if (isa<ConstantVector>(C) || isa<ConstantArray>(C) ||
|
||||
isa<ConstantStruct>(C)) {
|
||||
} else if (isa<ConstantAggregate>(C)) {
|
||||
// If any element in the constant vector or aggregate C is or uses a global
|
||||
// variable in GVMap, the constant C needs to be reconstructed, using a set
|
||||
// of instructions.
|
||||
|
@ -56,8 +56,7 @@ isSimpleEnoughValueToCommitHelper(Constant *C,
|
||||
return true;
|
||||
|
||||
// Aggregate values are safe if all their elements are.
|
||||
if (isa<ConstantArray>(C) || isa<ConstantStruct>(C) ||
|
||||
isa<ConstantVector>(C)) {
|
||||
if (isa<ConstantAggregate>(C)) {
|
||||
for (Value *Op : C->operands())
|
||||
if (!isSimpleEnoughValueToCommit(cast<Constant>(Op), SimpleConstants, DL))
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user