* ``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.
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
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 {
protected:
explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) {}
static inline bool classof(const Type *T) {
return T->getTypeID() == ArrayTyID ||
T->getTypeID() == StructTyID ||
- T->getTypeID() == PointerTyID ||
T->getTypeID() == VectorTyID;
}
};
return cast<StructType>(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;
/// 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;
}
};
}
/// 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.
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);
/// Transparently provide more efficient getOperand methods.
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; }
void setSourceElementType(Type *Ty) { SourceElementType = Ty; }
Type * const *ContainedTys;
static bool isSequentialType(TypeID TyID) {
- return TyID == ArrayTyID || TyID == PointerTyID || TyID == VectorTyID;
+ return TyID == ArrayTyID || TyID == VectorTyID;
}
public:
: 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<StructType>(CurTy)) {
IdxList.push_back(Zero);
} else if (SequentialType *STy =
dyn_cast<SequentialType>(ElTy)) {
- if (ElTy->isPointerTy()) break; // Can't index into pointers!
ElTy = STy->getElementType();
IdxList.push_back(Zero);
} else {
continue;
}
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)) {
// There can be awkward padding in after a non-power of two vector.
Unknown = true;
CI))
// It's in range, skip to the next index.
continue;
- if (!isa<SequentialType>(Prev)) {
+ if (isa<StructType>(Prev)) {
// It's out of range, but the prior dimension is a struct
// so we can't do anything about it.
Unknown = true;
return wrap(VectorType::get(unwrap(ElementType), ElementCount));
}
-LLVMTypeRef LLVMGetElementType(LLVMTypeRef Ty) {
- return wrap(unwrap<SequentialType>(Ty)->getElementType());
+LLVMTypeRef LLVMGetElementType(LLVMTypeRef WrappedTy) {
+ 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) {
PointerType::PointerType(Type *E, unsigned AddrSpace)
- : SequentialType(PointerTyID, E) {
+ : Type(E->getContext(), PointerTyID), PointeeTy(E) {
+ ContainedTys = &PointeeTy;
+ NumContainedTys = 1;
setSubclassData(AddrSpace);
}
Type *next_type(Type *Ty, Value *Idx) {
+ if (auto *PTy = dyn_cast<PointerType>(Ty))
+ return PTy->getElementType();
// Advance the type.
if (!Ty->isStructTy()) {
Type *NexTy = cast<SequentialType>(Ty)->getElementType();
// For homogenous sequential types, check for padding within members.
if (SequentialType *seqTy = dyn_cast<SequentialType>(type))
- return isa<PointerType>(seqTy) ||
- isDenselyPacked(seqTy->getElementType(), DL);
+ return isDenselyPacked(seqTy->getElementType(), DL);
// Check for padding within and between elements of a struct.
StructType *StructTy = cast<StructType>(type);
Type::getInt64Ty(F->getContext()));
Ops.push_back(ConstantInt::get(IdxTy, II));
// 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.
V = GetElementPtrInst::Create(ArgIndex.first, V, Ops,
return nullptr;
if (SequentialType *SeqTy = dyn_cast<SequentialType>(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;