1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

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
This commit is contained in:
Peter Collingbourne 2016-12-02 03:05:41 +00:00
parent 8198963706
commit 1329d17185
11 changed files with 34 additions and 39 deletions

View File

@ -3278,7 +3278,7 @@ Important Derived Types
* ``unsigned getBitWidth() const``: Get the bit width of an integer type. * ``unsigned getBitWidth() const``: Get the bit width of an integer type.
``SequentialType`` ``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 * ``const Type * getElementType() const``: Returns the type of each
of the elements in the sequential type. of the elements in the sequential type.
@ -3291,7 +3291,7 @@ Important Derived Types
in the array. in the array.
``PointerType`` ``PointerType``
Subclass of SequentialType for pointer types. Subclass of Type for pointer types.
``VectorType`` ``VectorType``
Subclass of SequentialType for vector types. A vector type is similar to an Subclass of SequentialType for vector types. A vector type is similar to an

View File

@ -153,7 +153,7 @@ unsigned Type::getFunctionNumParams() const {
return cast<FunctionType>(this)->getNumParams(); return cast<FunctionType>(this)->getNumParams();
} }
/// Common super class of ArrayType, StructType, PointerType and VectorType. /// Common super class of ArrayType, StructType and VectorType.
class CompositeType : public Type { class CompositeType : public Type {
protected: protected:
explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) {} explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) {}
@ -169,7 +169,6 @@ public:
static inline bool classof(const Type *T) { static inline bool classof(const Type *T) {
return T->getTypeID() == ArrayTyID || return T->getTypeID() == ArrayTyID ||
T->getTypeID() == StructTyID || T->getTypeID() == StructTyID ||
T->getTypeID() == PointerTyID ||
T->getTypeID() == VectorTyID; T->getTypeID() == VectorTyID;
} }
}; };
@ -306,12 +305,12 @@ Type *Type::getStructElementType(unsigned N) const {
return cast<StructType>(this)->getElementType(N); return cast<StructType>(this)->getElementType(N);
} }
/// This is the superclass of the array, pointer and vector type classes. /// This is the superclass of the array and vector type classes. Both of these
/// All of these represent "arrays" in memory. The array type represents a /// represent "arrays" in memory. The array type represents a specifically sized
/// specifically sized array, pointer types are unsized/unknown size arrays, /// array, and the vector type represents a specifically sized array that allows
/// vector types represent specifically sized arrays that allow for use of SIMD /// for use of SIMD instructions. SequentialType holds the common features of
/// instructions. SequentialType holds the common features of all, which stem /// both, which stem from the fact that both lay their components out in memory
/// from the fact that all three lay their components out in memory identically. /// identically.
class SequentialType : public CompositeType { class SequentialType : public CompositeType {
Type *ContainedType; ///< Storage for the single contained type. Type *ContainedType; ///< Storage for the single contained type.
SequentialType(const SequentialType &) = delete; SequentialType(const SequentialType &) = delete;
@ -329,9 +328,7 @@ public:
/// Methods for support type inquiry through isa, cast, and dyn_cast. /// Methods for support type inquiry through isa, cast, and dyn_cast.
static inline bool classof(const Type *T) { static inline bool classof(const Type *T) {
return T->getTypeID() == ArrayTyID || return T->getTypeID() == ArrayTyID || T->getTypeID() == VectorTyID;
T->getTypeID() == PointerTyID ||
T->getTypeID() == VectorTyID;
} }
}; };
@ -441,11 +438,13 @@ unsigned Type::getVectorNumElements() const {
} }
/// Class to represent pointers. /// Class to represent pointers.
class PointerType : public SequentialType { class PointerType : public Type {
PointerType(const PointerType &) = delete; PointerType(const PointerType &) = delete;
const PointerType &operator=(const PointerType &) = delete; const PointerType &operator=(const PointerType &) = delete;
explicit PointerType(Type *ElType, unsigned AddrSpace); explicit PointerType(Type *ElType, unsigned AddrSpace);
Type *PointeeTy;
public: public:
/// This constructs a pointer to an object of the specified type in a numbered /// This constructs a pointer to an object of the specified type in a numbered
/// address space. /// address space.
@ -457,6 +456,8 @@ public:
return PointerType::get(ElementType, 0); return PointerType::get(ElementType, 0);
} }
Type *getElementType() const { return PointeeTy; }
/// Return true if the specified type is valid as a element type. /// Return true if the specified type is valid as a element type.
static bool isValidElementType(Type *ElemTy); static bool isValidElementType(Type *ElemTy);

View File

@ -898,11 +898,6 @@ public:
/// Transparently provide more efficient getOperand methods. /// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
// getType - Overload to return most specific sequential type.
SequentialType *getType() const {
return cast<SequentialType>(Instruction::getType());
}
Type *getSourceElementType() const { return SourceElementType; } Type *getSourceElementType() const { return SourceElementType; }
void setSourceElementType(Type *Ty) { SourceElementType = Ty; } void setSourceElementType(Type *Ty) { SourceElementType = Ty; }

View File

@ -110,7 +110,7 @@ protected:
Type * const *ContainedTys; Type * const *ContainedTys;
static bool isSequentialType(TypeID TyID) { static bool isSequentialType(TypeID TyID) {
return TyID == ArrayTyID || TyID == PointerTyID || TyID == VectorTyID; return TyID == ArrayTyID || TyID == VectorTyID;
} }
public: public:

View File

@ -3057,9 +3057,9 @@ ScalarEvolution::getGEPExpr(GEPOperator *GEP,
: SCEV::FlagAnyWrap; : SCEV::FlagAnyWrap;
const SCEV *TotalOffset = getZero(IntPtrTy); 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. // its element type.
Type *CurTy = PointerType::getUnqual(GEP->getSourceElementType()); Type *CurTy = ArrayType::get(GEP->getSourceElementType(), 0);
for (const SCEV *IndexExpr : IndexExprs) { for (const SCEV *IndexExpr : IndexExprs) {
// Compute the (potentially symbolic) offset in bytes for this index. // Compute the (potentially symbolic) offset in bytes for this index.
if (StructType *STy = dyn_cast<StructType>(CurTy)) { if (StructType *STy = dyn_cast<StructType>(CurTy)) {

View File

@ -120,7 +120,6 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) {
IdxList.push_back(Zero); IdxList.push_back(Zero);
} else if (SequentialType *STy = } else if (SequentialType *STy =
dyn_cast<SequentialType>(ElTy)) { dyn_cast<SequentialType>(ElTy)) {
if (ElTy->isPointerTy()) break; // Can't index into pointers!
ElTy = STy->getElementType(); ElTy = STy->getElementType();
IdxList.push_back(Zero); IdxList.push_back(Zero);
} else { } else {
@ -2206,11 +2205,6 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
continue; continue;
} }
auto *STy = cast<SequentialType>(Ty); auto *STy = cast<SequentialType>(Ty);
if (isa<PointerType>(STy)) {
// We don't know if it's in range or not.
Unknown = true;
continue;
}
if (isa<VectorType>(STy)) { if (isa<VectorType>(STy)) {
// There can be awkward padding in after a non-power of two vector. // There can be awkward padding in after a non-power of two vector.
Unknown = true; Unknown = true;
@ -2222,7 +2216,7 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
CI)) CI))
// It's in range, skip to the next index. // It's in range, skip to the next index.
continue; continue;
if (!isa<SequentialType>(Prev)) { if (isa<StructType>(Prev)) {
// It's out of range, but the prior dimension is a struct // It's out of range, but the prior dimension is a struct
// so we can't do anything about it. // so we can't do anything about it.
Unknown = true; Unknown = true;

View File

@ -578,8 +578,11 @@ LLVMTypeRef LLVMVectorType(LLVMTypeRef ElementType, unsigned ElementCount) {
return wrap(VectorType::get(unwrap(ElementType), ElementCount)); return wrap(VectorType::get(unwrap(ElementType), ElementCount));
} }
LLVMTypeRef LLVMGetElementType(LLVMTypeRef Ty) { LLVMTypeRef LLVMGetElementType(LLVMTypeRef WrappedTy) {
return wrap(unwrap<SequentialType>(Ty)->getElementType()); auto *Ty = unwrap<Type>(WrappedTy);
if (auto *PTy = dyn_cast<PointerType>(Ty))
return wrap(PTy->getElementType());
return wrap(cast<SequentialType>(Ty)->getElementType());
} }
unsigned LLVMGetArrayLength(LLVMTypeRef ArrayTy) { unsigned LLVMGetArrayLength(LLVMTypeRef ArrayTy) {

View File

@ -673,7 +673,9 @@ PointerType *PointerType::get(Type *EltTy, unsigned AddressSpace) {
PointerType::PointerType(Type *E, unsigned AddrSpace) PointerType::PointerType(Type *E, unsigned AddrSpace)
: SequentialType(PointerTyID, E) { : Type(E->getContext(), PointerTyID), PointeeTy(E) {
ContainedTys = &PointeeTy;
NumContainedTys = 1;
setSubclassData(AddrSpace); setSubclassData(AddrSpace);
} }

View File

@ -178,6 +178,8 @@ namespace {
Type *next_type(Type *Ty, Value *Idx) { Type *next_type(Type *Ty, Value *Idx) {
if (auto *PTy = dyn_cast<PointerType>(Ty))
return PTy->getElementType();
// Advance the type. // Advance the type.
if (!Ty->isStructTy()) { if (!Ty->isStructTy()) {
Type *NexTy = cast<SequentialType>(Ty)->getElementType(); Type *NexTy = cast<SequentialType>(Ty)->getElementType();

View File

@ -176,8 +176,7 @@ static bool isDenselyPacked(Type *type, const DataLayout &DL) {
// For homogenous sequential types, check for padding within members. // For homogenous sequential types, check for padding within members.
if (SequentialType *seqTy = dyn_cast<SequentialType>(type)) if (SequentialType *seqTy = dyn_cast<SequentialType>(type))
return isa<PointerType>(seqTy) || return isDenselyPacked(seqTy->getElementType(), DL);
isDenselyPacked(seqTy->getElementType(), DL);
// Check for padding within and between elements of a struct. // Check for padding within and between elements of a struct.
StructType *StructTy = cast<StructType>(type); StructType *StructTy = cast<StructType>(type);
@ -835,7 +834,10 @@ DoPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
Type::getInt64Ty(F->getContext())); Type::getInt64Ty(F->getContext()));
Ops.push_back(ConstantInt::get(IdxTy, II)); Ops.push_back(ConstantInt::get(IdxTy, II));
// Keep track of the type we're currently indexing. // Keep track of the type we're currently indexing.
ElTy = cast<CompositeType>(ElTy)->getTypeAtIndex(II); if (auto *ElPTy = dyn_cast<PointerType>(ElTy))
ElTy = ElPTy->getElementType();
else
ElTy = cast<CompositeType>(ElTy)->getTypeAtIndex(II);
} }
// And create a GEP to extract those indices. // And create a GEP to extract those indices.
V = GetElementPtrInst::Create(ArgIndex.first, V, Ops, V = GetElementPtrInst::Create(ArgIndex.first, V, Ops,

View File

@ -3219,10 +3219,6 @@ static Type *getTypePartition(const DataLayout &DL, Type *Ty, uint64_t Offset,
return nullptr; return nullptr;
if (SequentialType *SeqTy = dyn_cast<SequentialType>(Ty)) { if (SequentialType *SeqTy = dyn_cast<SequentialType>(Ty)) {
// We can't partition pointers...
if (SeqTy->isPointerTy())
return nullptr;
Type *ElementTy = SeqTy->getElementType(); Type *ElementTy = SeqTy->getElementType();
uint64_t ElementSize = DL.getTypeAllocSize(ElementTy); uint64_t ElementSize = DL.getTypeAllocSize(ElementTy);
uint64_t NumSkippedElements = Offset / ElementSize; uint64_t NumSkippedElements = Offset / ElementSize;