From 1329d1718597139606f5a5d800b2bc00ee664213 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Fri, 2 Dec 2016 03:05:41 +0000 Subject: [PATCH] IR: Change PointerType to derive from Type rather than SequentialType. As proposed on llvm-dev: http://lists.llvm.org/pipermail/llvm-dev/2016-October/106640.html This is for a couple of reasons: - Values of type PointerType are unlike the other SequentialTypes (arrays and vectors) in that they do not hold values of the element type. By moving PointerType we can unify certain aspects of how the other SequentialTypes are handled. - PointerType will have no place in the SequentialType hierarchy once pointee types are removed, so this is a necessary step towards removing pointee types. Differential Revision: https://reviews.llvm.org/D26595 llvm-svn: 288462 --- docs/ProgrammersManual.rst | 4 ++-- include/llvm/IR/DerivedTypes.h | 25 ++++++++++++------------ include/llvm/IR/Instructions.h | 5 ----- include/llvm/IR/Type.h | 2 +- lib/Analysis/ScalarEvolution.cpp | 4 ++-- lib/IR/ConstantFold.cpp | 8 +------- lib/IR/Core.cpp | 7 +++++-- lib/IR/Type.cpp | 4 +++- lib/Target/Hexagon/HexagonCommonGEP.cpp | 2 ++ lib/Transforms/IPO/ArgumentPromotion.cpp | 8 +++++--- lib/Transforms/Scalar/SROA.cpp | 4 ---- 11 files changed, 34 insertions(+), 39 deletions(-) diff --git a/docs/ProgrammersManual.rst b/docs/ProgrammersManual.rst index b3013394831..9375b625518 100644 --- a/docs/ProgrammersManual.rst +++ b/docs/ProgrammersManual.rst @@ -3278,7 +3278,7 @@ Important Derived Types * ``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 @@ Important Derived Types 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 diff --git a/include/llvm/IR/DerivedTypes.h b/include/llvm/IR/DerivedTypes.h index 7459d06f56d..79820db051a 100644 --- a/include/llvm/IR/DerivedTypes.h +++ b/include/llvm/IR/DerivedTypes.h @@ -153,7 +153,7 @@ unsigned Type::getFunctionNumParams() const { 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 @@ public: static inline bool classof(const Type *T) { return T->getTypeID() == ArrayTyID || T->getTypeID() == StructTyID || - T->getTypeID() == PointerTyID || T->getTypeID() == VectorTyID; } }; @@ -306,12 +305,12 @@ Type *Type::getStructElementType(unsigned N) const { 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; @@ -329,9 +328,7 @@ public: /// 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; + return T->getTypeID() == ArrayTyID || T->getTypeID() == VectorTyID; } }; @@ -441,11 +438,13 @@ unsigned Type::getVectorNumElements() const { } /// 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 +456,8 @@ public: 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); diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index b84a269138c..19ca4e44f2a 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -898,11 +898,6 @@ public: /// 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; } diff --git a/include/llvm/IR/Type.h b/include/llvm/IR/Type.h index 4e2ef5301f5..84dc418af15 100644 --- a/include/llvm/IR/Type.h +++ b/include/llvm/IR/Type.h @@ -110,7 +110,7 @@ protected: Type * const *ContainedTys; static bool isSequentialType(TypeID TyID) { - return TyID == ArrayTyID || TyID == PointerTyID || TyID == VectorTyID; + return TyID == ArrayTyID || TyID == VectorTyID; } public: diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 041d4d4a47e..7962222a210 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -3057,9 +3057,9 @@ ScalarEvolution::getGEPExpr(GEPOperator *GEP, : 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)) { diff --git a/lib/IR/ConstantFold.cpp b/lib/IR/ConstantFold.cpp index 60f6fbb6f65..6360b4503a4 100644 --- a/lib/IR/ConstantFold.cpp +++ b/lib/IR/ConstantFold.cpp @@ -120,7 +120,6 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) { 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 { @@ -2206,11 +2205,6 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C, 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; @@ -2222,7 +2216,7 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C, 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; diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp index a969e08cabc..7f1d5d249e2 100644 --- a/lib/IR/Core.cpp +++ b/lib/IR/Core.cpp @@ -578,8 +578,11 @@ LLVMTypeRef LLVMVectorType(LLVMTypeRef ElementType, unsigned ElementCount) { 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) { diff --git a/lib/IR/Type.cpp b/lib/IR/Type.cpp index 84956c2c9e5..291d993ee37 100644 --- a/lib/IR/Type.cpp +++ b/lib/IR/Type.cpp @@ -673,7 +673,9 @@ PointerType *PointerType::get(Type *EltTy, unsigned AddressSpace) { PointerType::PointerType(Type *E, unsigned AddrSpace) - : SequentialType(PointerTyID, E) { + : Type(E->getContext(), PointerTyID), PointeeTy(E) { + ContainedTys = &PointeeTy; + NumContainedTys = 1; setSubclassData(AddrSpace); } diff --git a/lib/Target/Hexagon/HexagonCommonGEP.cpp b/lib/Target/Hexagon/HexagonCommonGEP.cpp index 6ed34d95f9b..9336e0fd50b 100644 --- a/lib/Target/Hexagon/HexagonCommonGEP.cpp +++ b/lib/Target/Hexagon/HexagonCommonGEP.cpp @@ -178,6 +178,8 @@ namespace { 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(); diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp index 47bf107e66e..65b7bad3b1e 100644 --- a/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -176,8 +176,7 @@ static bool isDenselyPacked(Type *type, const DataLayout &DL) { // 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 @@ DoPromotion(Function *F, SmallPtrSetImpl &ArgsToPromote, 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, diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp index 66de397676e..258e77e9260 100644 --- a/lib/Transforms/Scalar/SROA.cpp +++ b/lib/Transforms/Scalar/SROA.cpp @@ -3219,10 +3219,6 @@ static Type *getTypePartition(const DataLayout &DL, Type *Ty, uint64_t Offset, 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;