diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/IR/Constants.h | 73 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Value.def | 4 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Value.h | 8 | ||||
-rw-r--r-- | llvm/lib/Analysis/CFLAliasAnalysis.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/IR/Constants.cpp | 58 | ||||
-rw-r--r-- | llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/Evaluator.cpp | 3 |
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; |