summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/IR/Constants.h73
-rw-r--r--llvm/include/llvm/IR/Value.def4
-rw-r--r--llvm/include/llvm/IR/Value.h8
-rw-r--r--llvm/lib/Analysis/CFLAliasAnalysis.cpp7
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp3
-rw-r--r--llvm/lib/IR/Constants.cpp58
-rw-r--r--llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp3
-rw-r--r--llvm/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp3
-rw-r--r--llvm/lib/Transforms/Utils/Evaluator.cpp3
9 files changed, 77 insertions, 85 deletions
diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h
index 6a7a1d0e5b4..a4a5a44ed37 100644
--- a/llvm/include/llvm/IR/Constants.h
+++ b/llvm/include/llvm/IR/Constants.h
@@ -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
///
diff --git a/llvm/include/llvm/IR/Value.def b/llvm/include/llvm/IR/Value.def
index eb47738810f..c5f605ca2f1 100644
--- a/llvm/include/llvm/IR/Value.def
+++ b/llvm/include/llvm/IR/Value.def
@@ -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
diff --git a/llvm/include/llvm/IR/Value.h b/llvm/include/llvm/IR/Value.h
index eed805c5ec3..a632309a63e 100644
--- a/llvm/include/llvm/IR/Value.h
+++ b/llvm/include/llvm/IR/Value.h
@@ -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;
diff --git a/llvm/lib/Analysis/CFLAliasAnalysis.cpp b/llvm/lib/Analysis/CFLAliasAnalysis.cpp
index 6e6df987628..7d5ccac2155 100644
--- a/llvm/lib/Analysis/CFLAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/CFLAliasAnalysis.cpp
@@ -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;
}
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 5e0b80ebd1d..99046d993a8 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -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));
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 34a3540bf27..f030e2edffb 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -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;
}
+ConstantAggregate::ConstantAggregate(CompositeType *T, ValueTy VT,
+ ArrayRef<Constant *> V)
+ : Constant(T, VT, OperandTraits<ConstantAggregate>::op_end(this) - V.size(),
+ V.size()) {
+ 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)
- : Constant(T, ConstantArrayVal,
- OperandTraits<ConstantArray>::op_end(this) - V.size(),
- V.size()) {
+ : ConstantAggregate(T, ConstantArrayVal, V) {
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());
+ "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.
diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
index c084b48fdc4..fe816ebb68e 100644
--- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
@@ -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)
diff --git a/llvm/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp b/llvm/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp
index 5ace765f260..af418f0e3da 100644
--- a/llvm/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp
@@ -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.
diff --git a/llvm/lib/Transforms/Utils/Evaluator.cpp b/llvm/lib/Transforms/Utils/Evaluator.cpp
index 46e1dcc58dd..47cf5ff5b80 100644
--- a/llvm/lib/Transforms/Utils/Evaluator.cpp
+++ b/llvm/lib/Transforms/Utils/Evaluator.cpp
@@ -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;
OpenPOWER on IntegriCloud