aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Type.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/Type.cpp')
-rw-r--r--llvm/lib/IR/Type.cpp120
1 files changed, 82 insertions, 38 deletions
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index 8bb8c9d29a62..ba4d0f5dc18d 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -57,10 +57,12 @@ bool Type::isIntegerTy(unsigned Bitwidth) const {
return isIntegerTy() && cast<IntegerType>(this)->getBitWidth() == Bitwidth;
}
-bool Type::isOpaquePointerTy() const {
- if (auto *PTy = dyn_cast<PointerType>(this))
- return PTy->isOpaque();
- return false;
+bool Type::isScalableTy() const {
+ if (const auto *STy = dyn_cast<StructType>(this)) {
+ SmallPtrSet<Type *, 4> Visited;
+ return STy->containsScalableVectorType(&Visited);
+ }
+ return getTypeID() == ScalableVectorTyID || isScalableTargetExtTy();
}
const fltSemantics &Type::getFltSemantics() const {
@@ -80,6 +82,12 @@ bool Type::isIEEE() const {
return APFloat::getZero(getFltSemantics()).isIEEE();
}
+bool Type::isScalableTargetExtTy() const {
+ if (auto *TT = dyn_cast<TargetExtType>(this))
+ return isa<ScalableVectorType>(TT->getLayoutType());
+ return false;
+}
+
Type *Type::getFloatingPointTy(LLVMContext &C, const fltSemantics &S) {
Type *Ty;
if (&S == &APFloat::IEEEhalf())
@@ -306,6 +314,18 @@ PointerType *Type::getInt64PtrTy(LLVMContext &C, unsigned AS) {
return getInt64Ty(C)->getPointerTo(AS);
}
+Type *Type::getWasm_ExternrefTy(LLVMContext &C) {
+ // opaque pointer in addrspace(10)
+ static PointerType *Ty = PointerType::get(C, 10);
+ return Ty;
+}
+
+Type *Type::getWasm_FuncrefTy(LLVMContext &C) {
+ // opaque pointer in addrspace(20)
+ static PointerType *Ty = PointerType::get(C, 20);
+ return Ty;
+}
+
//===----------------------------------------------------------------------===//
// IntegerType Implementation
//===----------------------------------------------------------------------===//
@@ -432,18 +452,51 @@ StructType *StructType::get(LLVMContext &Context, ArrayRef<Type*> ETypes,
return ST;
}
-bool StructType::containsScalableVectorType() const {
+bool StructType::containsScalableVectorType(
+ SmallPtrSetImpl<Type *> *Visited) const {
+ if ((getSubclassData() & SCDB_ContainsScalableVector) != 0)
+ return true;
+
+ if ((getSubclassData() & SCDB_NotContainsScalableVector) != 0)
+ return false;
+
+ if (Visited && !Visited->insert(const_cast<StructType *>(this)).second)
+ return false;
+
for (Type *Ty : elements()) {
- if (isa<ScalableVectorType>(Ty))
+ if (isa<ScalableVectorType>(Ty)) {
+ const_cast<StructType *>(this)->setSubclassData(
+ getSubclassData() | SCDB_ContainsScalableVector);
return true;
- if (auto *STy = dyn_cast<StructType>(Ty))
- if (STy->containsScalableVectorType())
+ }
+ if (auto *STy = dyn_cast<StructType>(Ty)) {
+ if (STy->containsScalableVectorType(Visited)) {
+ const_cast<StructType *>(this)->setSubclassData(
+ getSubclassData() | SCDB_ContainsScalableVector);
return true;
+ }
+ }
}
+ // For structures that are opaque, return false but do not set the
+ // SCDB_NotContainsScalableVector flag since it may gain scalable vector type
+ // when it becomes non-opaque.
+ if (!isOpaque())
+ const_cast<StructType *>(this)->setSubclassData(
+ getSubclassData() | SCDB_NotContainsScalableVector);
return false;
}
+bool StructType::containsHomogeneousScalableVectorTypes() const {
+ Type *FirstTy = getNumElements() > 0 ? elements()[0] : nullptr;
+ if (!FirstTy || !isa<ScalableVectorType>(FirstTy))
+ return false;
+ for (Type *Ty : elements())
+ if (Ty != FirstTy)
+ return false;
+ return true;
+}
+
void StructType::setBody(ArrayRef<Type*> Elements, bool isPacked) {
assert(isOpaque() && "Struct body already set!");
@@ -563,10 +616,19 @@ bool StructType::isSized(SmallPtrSetImpl<Type*> *Visited) const {
// Okay, our struct is sized if all of the elements are, but if one of the
// elements is opaque, the struct isn't sized *yet*, but may become sized in
// the future, so just bail out without caching.
+ // The ONLY special case inside a struct that is considered sized is when the
+ // elements are homogeneous of a scalable vector type.
+ if (containsHomogeneousScalableVectorTypes()) {
+ const_cast<StructType *>(this)->setSubclassData(getSubclassData() |
+ SCDB_IsSized);
+ return true;
+ }
for (Type *Ty : elements()) {
// If the struct contains a scalable vector type, don't consider it sized.
- // This prevents it from being used in loads/stores/allocas/GEPs.
- if (isa<ScalableVectorType>(Ty))
+ // This prevents it from being used in loads/stores/allocas/GEPs. The ONLY
+ // special case right now is a structure of homogenous scalable vector
+ // types and is handled by the if-statement before this for-loop.
+ if (Ty->isScalableTy())
return false;
if (!Ty->isSized(Visited))
return false;
@@ -730,46 +792,24 @@ PointerType *PointerType::get(Type *EltTy, unsigned AddressSpace) {
assert(EltTy && "Can't get a pointer to <null> type!");
assert(isValidElementType(EltTy) && "Invalid type for pointer element!");
- LLVMContextImpl *CImpl = EltTy->getContext().pImpl;
-
// Automatically convert typed pointers to opaque pointers.
- if (CImpl->getOpaquePointers())
- return get(EltTy->getContext(), AddressSpace);
-
- // Since AddressSpace #0 is the common case, we special case it.
- PointerType *&Entry = AddressSpace == 0 ? CImpl->PointerTypes[EltTy]
- : CImpl->ASPointerTypes[std::make_pair(EltTy, AddressSpace)];
-
- if (!Entry)
- Entry = new (CImpl->Alloc) PointerType(EltTy, AddressSpace);
- return Entry;
+ return get(EltTy->getContext(), AddressSpace);
}
PointerType *PointerType::get(LLVMContext &C, unsigned AddressSpace) {
LLVMContextImpl *CImpl = C.pImpl;
- assert(CImpl->getOpaquePointers() &&
- "Can only create opaque pointers in opaque pointer mode");
// Since AddressSpace #0 is the common case, we special case it.
- PointerType *&Entry =
- AddressSpace == 0
- ? CImpl->PointerTypes[nullptr]
- : CImpl->ASPointerTypes[std::make_pair(nullptr, AddressSpace)];
+ PointerType *&Entry = AddressSpace == 0 ? CImpl->AS0PointerType
+ : CImpl->PointerTypes[AddressSpace];
if (!Entry)
Entry = new (CImpl->Alloc) PointerType(C, AddressSpace);
return Entry;
}
-PointerType::PointerType(Type *E, unsigned AddrSpace)
- : Type(E->getContext(), PointerTyID), PointeeTy(E) {
- ContainedTys = &PointeeTy;
- NumContainedTys = 1;
- setSubclassData(AddrSpace);
-}
-
PointerType::PointerType(LLVMContext &C, unsigned AddrSpace)
- : Type(C, PointerTyID), PointeeTy(nullptr) {
+ : Type(C, PointerTyID) {
setSubclassData(AddrSpace);
}
@@ -850,10 +890,14 @@ struct TargetTypeInfo {
static TargetTypeInfo getTargetTypeInfo(const TargetExtType *Ty) {
LLVMContext &C = Ty->getContext();
StringRef Name = Ty->getName();
- if (Name.startswith("spirv.")) {
+ if (Name.startswith("spirv."))
return TargetTypeInfo(Type::getInt8PtrTy(C, 0), TargetExtType::HasZeroInit,
TargetExtType::CanBeGlobal);
- }
+
+ // Opaque types in the AArch64 name space.
+ if (Name == "aarch64.svcount")
+ return TargetTypeInfo(ScalableVectorType::get(Type::getInt1Ty(C), 16));
+
return TargetTypeInfo(Type::getVoidTy(C));
}