Index: llvm/docs/ProgrammersManual.rst =================================================================== --- llvm/docs/ProgrammersManual.rst +++ llvm/docs/ProgrammersManual.rst @@ -3278,7 +3278,7 @@ * ``unsigned getBitWidth() const``: Get the bit width of an integer type. ``SequentialType`` - This is subclassed by ArrayType, PointerType and VectorType. + This is subclassed by ArrayType and VectorType. * ``const Type * getElementType() const``: Returns the type of each of the elements in the sequential type. @@ -3291,7 +3291,7 @@ in the array. ``PointerType`` - Subclass of SequentialType for pointer types. + Subclass of Type for pointer types. ``VectorType`` Subclass of SequentialType for vector types. A vector type is similar to an Index: llvm/include/llvm/IR/DerivedTypes.h =================================================================== --- llvm/include/llvm/IR/DerivedTypes.h +++ llvm/include/llvm/IR/DerivedTypes.h @@ -153,7 +153,7 @@ return cast(this)->getNumParams(); } -/// Common super class of ArrayType, StructType, PointerType and VectorType. +/// Common super class of ArrayType, StructType and VectorType. class CompositeType : public Type { protected: explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) {} @@ -169,7 +169,6 @@ static inline bool classof(const Type *T) { return T->getTypeID() == ArrayTyID || T->getTypeID() == StructTyID || - T->getTypeID() == PointerTyID || T->getTypeID() == VectorTyID; } }; @@ -306,39 +305,39 @@ return cast(this)->getElementType(N); } -/// This is the superclass of the array, pointer and vector type classes. -/// All of these represent "arrays" in memory. The array type represents a -/// specifically sized array, pointer types are unsized/unknown size arrays, -/// vector types represent specifically sized arrays that allow for use of SIMD -/// instructions. SequentialType holds the common features of all, which stem -/// from the fact that all three lay their components out in memory identically. +/// This is the superclass of the array and vector type classes. Both of these +/// represent "arrays" in memory. The array type represents a specifically sized +/// array, and the vector type represents a specifically sized array that allows +/// for use of SIMD instructions. SequentialType holds the common features of +/// both, which stem from the fact that both lay their components out in memory +/// identically. class SequentialType : public CompositeType { Type *ContainedType; ///< Storage for the single contained type. + uint64_t NumElements; SequentialType(const SequentialType &) = delete; const SequentialType &operator=(const SequentialType &) = delete; protected: - SequentialType(TypeID TID, Type *ElType) - : CompositeType(ElType->getContext(), TID), ContainedType(ElType) { + SequentialType(TypeID TID, Type *ElType, uint64_t NumElements) + : CompositeType(ElType->getContext(), TID), ContainedType(ElType), + NumElements(NumElements) { ContainedTys = &ContainedType; NumContainedTys = 1; } public: - Type *getElementType() const { return getSequentialElementType(); } + uint64_t getNumElements() const { return NumElements; } + Type *getElementType() const { return ContainedType; } /// Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const Type *T) { return T->getTypeID() == ArrayTyID || - T->getTypeID() == PointerTyID || T->getTypeID() == VectorTyID; } }; /// Class to represent array types. class ArrayType : public SequentialType { - uint64_t NumElements; - ArrayType(const ArrayType &) = delete; const ArrayType &operator=(const ArrayType &) = delete; ArrayType(Type *ElType, uint64_t NumEl); @@ -350,8 +349,6 @@ /// Return true if the specified type is valid as a element type. static bool isValidElementType(Type *ElemTy); - uint64_t getNumElements() const { return NumElements; } - /// Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const Type *T) { return T->getTypeID() == ArrayTyID; @@ -364,8 +361,6 @@ /// Class to represent vector types. class VectorType : public SequentialType { - unsigned NumElements; - VectorType(const VectorType &) = delete; const VectorType &operator=(const VectorType &) = delete; VectorType(Type *ElType, unsigned NumEl); @@ -421,13 +416,10 @@ /// Return true if the specified type is valid as a element type. static bool isValidElementType(Type *ElemTy); - /// Return the number of elements in the Vector type. - unsigned getNumElements() const { return NumElements; } - /// Return the number of bits in the Vector type. /// Returns zero when the vector is a vector of pointers. unsigned getBitWidth() const { - return NumElements * getElementType()->getPrimitiveSizeInBits(); + return getNumElements() * getElementType()->getPrimitiveSizeInBits(); } /// Methods for support type inquiry through isa, cast, and dyn_cast. @@ -441,11 +433,13 @@ } /// Class to represent pointers. -class PointerType : public SequentialType { +class PointerType : public Type { PointerType(const PointerType &) = delete; const PointerType &operator=(const PointerType &) = delete; explicit PointerType(Type *ElType, unsigned AddrSpace); + Type *PointeeTy; + public: /// This constructs a pointer to an object of the specified type in a numbered /// address space. @@ -457,6 +451,10 @@ return PointerType::get(ElementType, 0); } + Type *getElementType() const { + return PointeeTy; + } + /// Return true if the specified type is valid as a element type. static bool isValidElementType(Type *ElemTy); Index: llvm/include/llvm/IR/GetElementPtrTypeIterator.h =================================================================== --- llvm/include/llvm/IR/GetElementPtrTypeIterator.h +++ llvm/include/llvm/IR/GetElementPtrTypeIterator.h @@ -88,12 +88,9 @@ generic_gep_type_iterator& operator++() { // Preincrement Type *Ty = getIndexedType(); - if (auto *ATy = dyn_cast(Ty)) { - CurTy = ATy->getElementType(); - ArrayBound = ATy->getNumElements(); - } else if (auto *VTy = dyn_cast(Ty)) { - CurTy = VTy->getElementType(); - ArrayBound = VTy->getNumElements(); + if (auto *STy = dyn_cast(Ty)) { + CurTy = STy->getElementType(); + ArrayBound = STy->getNumElements(); } else CurTy = dyn_cast(Ty); ++OpIt; Index: llvm/include/llvm/IR/Instructions.h =================================================================== --- llvm/include/llvm/IR/Instructions.h +++ llvm/include/llvm/IR/Instructions.h @@ -898,11 +898,6 @@ /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - // getType - Overload to return most specific sequential type. - SequentialType *getType() const { - return cast(Instruction::getType()); - } - Type *getSourceElementType() const { return SourceElementType; } void setSourceElementType(Type *Ty) { SourceElementType = Ty; } Index: llvm/include/llvm/IR/Type.h =================================================================== --- llvm/include/llvm/IR/Type.h +++ llvm/include/llvm/IR/Type.h @@ -110,7 +110,7 @@ Type * const *ContainedTys; static bool isSequentialType(TypeID TyID) { - return TyID == ArrayTyID || TyID == PointerTyID || TyID == VectorTyID; + return TyID == ArrayTyID || TyID == VectorTyID; } public: Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -3030,9 +3030,9 @@ : SCEV::FlagAnyWrap; const SCEV *TotalOffset = getZero(IntPtrTy); - // The address space is unimportant. The first thing we do on CurTy is getting + // The array size is unimportant. The first thing we do on CurTy is getting // its element type. - Type *CurTy = PointerType::getUnqual(GEP->getSourceElementType()); + Type *CurTy = ArrayType::get(GEP->getSourceElementType(), 0); for (const SCEV *IndexExpr : IndexExprs) { // Compute the (potentially symbolic) offset in bytes for this index. if (StructType *STy = dyn_cast(CurTy)) { Index: llvm/lib/IR/ConstantFold.cpp =================================================================== --- llvm/lib/IR/ConstantFold.cpp +++ llvm/lib/IR/ConstantFold.cpp @@ -120,7 +120,6 @@ IdxList.push_back(Zero); } else if (SequentialType *STy = dyn_cast(ElTy)) { - if (ElTy->isPointerTy()) break; // Can't index into pointers! ElTy = STy->getElementType(); IdxList.push_back(Zero); } else { @@ -892,10 +891,8 @@ unsigned NumElts; if (StructType *ST = dyn_cast(Agg->getType())) NumElts = ST->getNumElements(); - else if (ArrayType *AT = dyn_cast(Agg->getType())) - NumElts = AT->getNumElements(); else - NumElts = Agg->getType()->getVectorNumElements(); + NumElts = cast(Agg->getType())->getNumElements(); SmallVector Result; for (unsigned i = 0; i != NumElts; ++i) { @@ -2205,23 +2202,15 @@ continue; } auto *STy = cast(Ty); - if (isa(STy)) { - // We don't know if it's in range or not. - Unknown = true; - continue; - } if (isa(STy)) { // There can be awkward padding in after a non-power of two vector. Unknown = true; continue; } - if (isIndexInRangeOfArrayType(isa(STy) - ? cast(STy)->getNumElements() - : cast(STy)->getNumElements(), - CI)) + if (isIndexInRangeOfArrayType(STy->getNumElements(), CI)) // It's in range, skip to the next index. continue; - if (!isa(Prev)) { + if (isa(Prev)) { // It's out of range, but the prior dimension is a struct // so we can't do anything about it. Unknown = true; Index: llvm/lib/IR/Constants.cpp =================================================================== --- llvm/lib/IR/Constants.cpp +++ llvm/lib/IR/Constants.cpp @@ -794,10 +794,8 @@ unsigned UndefValue::getNumElements() const { Type *Ty = getType(); - if (auto *AT = dyn_cast(Ty)) - return AT->getNumElements(); - if (auto *VT = dyn_cast(Ty)) - return VT->getNumElements(); + if (auto *ST = dyn_cast(Ty)) + return ST->getNumElements(); return Ty->getStructNumElements(); } Index: llvm/lib/IR/Core.cpp =================================================================== --- llvm/lib/IR/Core.cpp +++ llvm/lib/IR/Core.cpp @@ -578,8 +578,11 @@ return wrap(VectorType::get(unwrap(ElementType), ElementCount)); } -LLVMTypeRef LLVMGetElementType(LLVMTypeRef Ty) { - return wrap(unwrap(Ty)->getElementType()); +LLVMTypeRef LLVMGetElementType(LLVMTypeRef WrappedTy) { + auto *Ty = unwrap(WrappedTy); + if (auto *PTy = dyn_cast(Ty)) + return wrap(PTy->getElementType()); + return wrap(cast(Ty)->getElementType()); } unsigned LLVMGetArrayLength(LLVMTypeRef ArrayTy) { Index: llvm/lib/IR/Type.cpp =================================================================== --- llvm/lib/IR/Type.cpp +++ llvm/lib/IR/Type.cpp @@ -601,9 +601,7 @@ //===----------------------------------------------------------------------===// ArrayType::ArrayType(Type *ElType, uint64_t NumEl) - : SequentialType(ArrayTyID, ElType) { - NumElements = NumEl; -} + : SequentialType(ArrayTyID, ElType, NumEl) {} ArrayType *ArrayType::get(Type *ElementType, uint64_t NumElements) { assert(isValidElementType(ElementType) && "Invalid type for array element!"); @@ -628,9 +626,7 @@ //===----------------------------------------------------------------------===// VectorType::VectorType(Type *ElType, unsigned NumEl) - : SequentialType(VectorTyID, ElType) { - NumElements = NumEl; -} + : SequentialType(VectorTyID, ElType, NumEl) {} VectorType *VectorType::get(Type *ElementType, unsigned NumElements) { assert(NumElements > 0 && "#Elements of a VectorType must be greater than 0"); @@ -673,7 +669,9 @@ PointerType::PointerType(Type *E, unsigned AddrSpace) - : SequentialType(PointerTyID, E) { + : Type(E->getContext(), PointerTyID), PointeeTy(E) { + ContainedTys = &PointeeTy; + NumContainedTys = 1; setSubclassData(AddrSpace); } Index: llvm/lib/Linker/IRMover.cpp =================================================================== --- llvm/lib/Linker/IRMover.cpp +++ llvm/lib/Linker/IRMover.cpp @@ -169,11 +169,9 @@ if (DSTy->isLiteral() != SSTy->isLiteral() || DSTy->isPacked() != SSTy->isPacked()) return false; - } else if (ArrayType *DATy = dyn_cast(DstTy)) { - if (DATy->getNumElements() != cast(SrcTy)->getNumElements()) - return false; - } else if (VectorType *DVTy = dyn_cast(DstTy)) { - if (DVTy->getNumElements() != cast(SrcTy)->getNumElements()) + } else if (auto *DSeqTy = dyn_cast(DstTy)) { + if (DSeqTy->getNumElements() != + cast(SrcTy)->getNumElements()) return false; } Index: llvm/lib/Target/Hexagon/HexagonCommonGEP.cpp =================================================================== --- llvm/lib/Target/Hexagon/HexagonCommonGEP.cpp +++ llvm/lib/Target/Hexagon/HexagonCommonGEP.cpp @@ -178,6 +178,8 @@ Type *next_type(Type *Ty, Value *Idx) { + if (auto *PTy = dyn_cast(Ty)) + return PTy->getElementType(); // Advance the type. if (!Ty->isStructTy()) { Type *NexTy = cast(Ty)->getElementType(); Index: llvm/lib/Transforms/IPO/ArgumentPromotion.cpp =================================================================== --- llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -176,8 +176,7 @@ // For homogenous sequential types, check for padding within members. if (SequentialType *seqTy = dyn_cast(type)) - return isa(seqTy) || - isDenselyPacked(seqTy->getElementType(), DL); + return isDenselyPacked(seqTy->getElementType(), DL); // Check for padding within and between elements of a struct. StructType *StructTy = cast(type); @@ -835,7 +834,10 @@ Type::getInt64Ty(F->getContext())); Ops.push_back(ConstantInt::get(IdxTy, II)); // Keep track of the type we're currently indexing. - ElTy = cast(ElTy)->getTypeAtIndex(II); + if (auto *ElPTy = dyn_cast(ElTy)) + ElTy = ElPTy->getElementType(); + else + ElTy = cast(ElTy)->getTypeAtIndex(II); } // And create a GEP to extract those indices. V = GetElementPtrInst::Create(ArgIndex.first, V, Ops, Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp =================================================================== --- llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -465,12 +465,7 @@ NGV->setAlignment(NewAlign); } } else if (SequentialType *STy = dyn_cast(Ty)) { - unsigned NumElements = 0; - if (ArrayType *ATy = dyn_cast(STy)) - NumElements = ATy->getNumElements(); - else - NumElements = cast(STy)->getNumElements(); - + unsigned NumElements = STy->getNumElements(); if (NumElements > 16 && GV->hasNUsesOrMore(16)) return nullptr; // It's not worth it. NewGlobals.reserve(NumElements); @@ -2117,12 +2112,7 @@ ConstantInt *CI = cast(Addr->getOperand(OpNo)); SequentialType *InitTy = cast(Init->getType()); - - uint64_t NumElts; - if (ArrayType *ATy = dyn_cast(InitTy)) - NumElts = ATy->getNumElements(); - else - NumElts = InitTy->getVectorNumElements(); + uint64_t NumElts = InitTy->getNumElements(); // Break up the array into elements. for (uint64_t i = 0, e = NumElts; i != e; ++i) Index: llvm/lib/Transforms/Scalar/SROA.cpp =================================================================== --- llvm/lib/Transforms/Scalar/SROA.cpp +++ llvm/lib/Transforms/Scalar/SROA.cpp @@ -3213,20 +3213,11 @@ return nullptr; if (SequentialType *SeqTy = dyn_cast(Ty)) { - // We can't partition pointers... - if (SeqTy->isPointerTy()) - return nullptr; - Type *ElementTy = SeqTy->getElementType(); uint64_t ElementSize = DL.getTypeAllocSize(ElementTy); uint64_t NumSkippedElements = Offset / ElementSize; - if (ArrayType *ArrTy = dyn_cast(SeqTy)) { - if (NumSkippedElements >= ArrTy->getNumElements()) - return nullptr; - } else if (VectorType *VecTy = dyn_cast(SeqTy)) { - if (NumSkippedElements >= VecTy->getNumElements()) - return nullptr; - } + if (NumSkippedElements >= SeqTy->getNumElements()) + return nullptr; Offset -= NumSkippedElements * ElementSize; // First check if we need to recurse. Index: llvm/lib/Transforms/Utils/FunctionComparator.cpp =================================================================== --- llvm/lib/Transforms/Utils/FunctionComparator.cpp +++ llvm/lib/Transforms/Utils/FunctionComparator.cpp @@ -387,12 +387,6 @@ case Type::IntegerTyID: return cmpNumbers(cast(TyL)->getBitWidth(), cast(TyR)->getBitWidth()); - case Type::VectorTyID: { - VectorType *VTyL = cast(TyL), *VTyR = cast(TyR); - if (int Res = cmpNumbers(VTyL->getNumElements(), VTyR->getNumElements())) - return Res; - return cmpTypes(VTyL->getElementType(), VTyR->getElementType()); - } // TyL == TyR would have returned true earlier, because types are uniqued. case Type::VoidTyID: case Type::FloatTyID: @@ -445,12 +439,13 @@ return 0; } - case Type::ArrayTyID: { - ArrayType *ATyL = cast(TyL); - ArrayType *ATyR = cast(TyR); - if (ATyL->getNumElements() != ATyR->getNumElements()) - return cmpNumbers(ATyL->getNumElements(), ATyR->getNumElements()); - return cmpTypes(ATyL->getElementType(), ATyR->getElementType()); + case Type::ArrayTyID: + case Type::VectorTyID: { + auto *STyL = cast(TyL); + auto *STyR = cast(TyR); + if (STyL->getNumElements() != STyR->getNumElements()) + return cmpNumbers(STyL->getNumElements(), STyR->getNumElements()); + return cmpTypes(STyL->getElementType(), STyR->getElementType()); } } }