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,12 +305,12 @@ 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. SequentialType(const SequentialType &) = delete; @@ -330,7 +329,6 @@ /// 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; } }; @@ -441,11 +439,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 +457,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/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 @@ -3057,9 +3057,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 { @@ -2205,11 +2204,6 @@ 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; @@ -2221,7 +2215,7 @@ 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/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 @@ -673,7 +673,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/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/Scalar/SROA.cpp =================================================================== --- llvm/lib/Transforms/Scalar/SROA.cpp +++ llvm/lib/Transforms/Scalar/SROA.cpp @@ -3213,10 +3213,6 @@ 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;