18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/TypeSwitch.h"
20#include "llvm/Support/ErrorHandling.h"
36class TypeExtensionVisitor {
39 std::optional<StorageClass> storage)
40 : extensions(extensions), storage(storage) {}
44 void add(SPIRVType type) {
49 .Case<CooperativeMatrixType, PointerType, ScalarType, TensorArmType>(
50 [
this](
auto concreteType) { addConcrete(concreteType); })
51 .Case<ArrayType, ImageType, MatrixType, RuntimeArrayType, VectorType>(
52 [
this](
auto concreteType) {
add(concreteType.getElementType()); })
53 .Case([
this](SampledImageType concreteType) {
56 .Case([
this](StructType concreteType) {
60 .Case<SamplerType>([](
auto) { })
61 .DefaultUnreachable(
"Unhandled type");
64 void add(Type type) {
add(cast<SPIRVType>(type)); }
68 void addConcrete(CooperativeMatrixType type);
69 void addConcrete(PointerType type);
70 void addConcrete(ScalarType type);
71 void addConcrete(TensorArmType type);
74 std::optional<StorageClass> storage;
75 llvm::SmallDenseSet<std::pair<Type, std::optional<StorageClass>>> seen;
85class TypeCapabilityVisitor {
88 std::optional<StorageClass> storage)
89 : capabilities(capabilities), storage(storage) {}
93 void add(SPIRVType type) {
98 .Case<CooperativeMatrixType, ImageType, MatrixType, PointerType,
99 RuntimeArrayType, ScalarType, TensorArmType, VectorType>(
100 [
this](
auto concreteType) { addConcrete(concreteType); })
101 .Case([
this](ArrayType concreteType) {
104 .Case([
this](SampledImageType concreteType) {
107 .Case([
this](StructType concreteType) {
111 .Case<SamplerType>([](
auto) { })
112 .DefaultUnreachable(
"Unhandled type");
115 void add(Type type) {
add(cast<SPIRVType>(type)); }
119 void addConcrete(CooperativeMatrixType type);
120 void addConcrete(ImageType type);
121 void addConcrete(MatrixType type);
122 void addConcrete(PointerType type);
123 void addConcrete(RuntimeArrayType type);
124 void addConcrete(ScalarType type);
125 void addConcrete(TensorArmType type);
126 void addConcrete(VectorType type);
129 std::optional<StorageClass> storage;
130 llvm::SmallDenseSet<std::pair<Type, std::optional<StorageClass>>> seen;
140 using KeyTy = std::tuple<Type, unsigned, unsigned>;
161 assert(elementCount &&
"ArrayType needs at least one element");
168 assert(elementCount &&
"ArrayType needs at least one element");
183 if (
auto vectorType = dyn_cast<VectorType>(type))
191 return type.getRank() == 1 &&
192 llvm::is_contained({2, 3, 4, 8, 16}, type.getNumElements()) &&
193 (isa<ScalarType>(type.getElementType()) ||
194 isa<PointerType>(type.getElementType()));
200 TensorArmType>([](
auto type) {
return type.getElementType(); })
203 .DefaultUnreachable(
"Invalid composite type");
209 [](
auto type) {
return type.getNumElements(); })
211 .DefaultUnreachable(
"Invalid type for number of elements query");
215 return !isa<CooperativeMatrixType, RuntimeArrayType>(*
this);
218void TypeCapabilityVisitor::addConcrete(VectorType type) {
219 add(type.getElementType());
221 int64_t vecSize = type.getNumElements();
222 if (vecSize == 8 || vecSize == 16) {
223 static constexpr auto cap = Capability::Vector16;
224 capabilities.push_back(cap);
247 std::tuple<Type, int64_t, int64_t, Scope, CooperativeMatrixUseKHR>;
261 shape({std::get<1>(key), std::get<2>(key)}), scope(std::get<3>(key)),
262 use(std::get<4>(key)) {}
268 CooperativeMatrixUseKHR
use;
273 uint32_t columns, Scope scope,
274 CooperativeMatrixUseKHR use) {
285 return static_cast<uint32_t
>(
getImpl()->shape[0]);
290 return static_cast<uint32_t
>(
getImpl()->shape[1]);
305 static constexpr auto ext = Extension::SPV_KHR_cooperative_matrix;
306 extensions.push_back(ext);
311 static constexpr auto caps = Capability::CooperativeMatrixKHR;
312 capabilities.push_back(caps);
325 static_assert((1 << 3) > getMaxEnumValForDim(),
326 "Not enough bits to encode Dim value");
331 static_assert((1 << 2) > getMaxEnumValForImageDepthInfo(),
332 "Not enough bits to encode ImageDepthInfo value");
337 static_assert((1 << 1) > getMaxEnumValForImageArrayedInfo(),
338 "Not enough bits to encode ImageArrayedInfo value");
343 static_assert((1 << 1) > getMaxEnumValForImageSamplingInfo(),
344 "Not enough bits to encode ImageSamplingInfo value");
349 static_assert((1 << 2) > getMaxEnumValForImageSamplerUseInfo(),
350 "Not enough bits to encode ImageSamplerUseInfo value");
355 static_assert((1 << 6) > getMaxEnumValForImageFormat(),
356 "Not enough bits to encode ImageFormat value");
362 using KeyTy = std::tuple<
Type, Dim, ImageDepthInfo, ImageArrayedInfo,
363 ImageSamplingInfo, ImageSamplerUseInfo, ImageFormat>;
392 ImageSamplingInfo, ImageSamplerUseInfo, ImageFormat>
408 return getImpl()->samplingInfo;
412 return getImpl()->samplerUseInfo;
417void TypeCapabilityVisitor::addConcrete(
ImageType type) {
418 if (
auto dimCaps = spirv::getCapabilities(type.
getDim()))
419 capabilities.push_back(*dimCaps);
422 capabilities.push_back(*fmtCaps);
434 using KeyTy = std::pair<Type, StorageClass>;
460 return getImpl()->storageClass;
463void TypeExtensionVisitor::addConcrete(
PointerType type) {
466 std::optional<StorageClass> oldStorageClass = storage;
469 storage = oldStorageClass;
472 extensions.push_back(*scExts);
475void TypeCapabilityVisitor::addConcrete(
PointerType type) {
478 std::optional<StorageClass> oldStorageClass = storage;
481 storage = oldStorageClass;
484 capabilities.push_back(*scCaps);
492 using KeyTy = std::pair<Type, unsigned>;
525 static constexpr auto cap = Capability::Shader;
526 capabilities.push_back(cap);
534 if (
auto floatType = dyn_cast<FloatType>(type)) {
537 if (
auto intType = dyn_cast<IntegerType>(type)) {
544 if (type.isF8E4M3FN() || type.isF8E5M2())
546 return llvm::is_contained({16u, 32u, 64u}, type.getWidth());
550 return llvm::is_contained({1u, 8u, 16u, 32u, 64u}, type.getWidth());
553void TypeExtensionVisitor::addConcrete(
ScalarType type) {
554 if (isa<BFloat16Type>(type)) {
555 static constexpr auto ext = Extension::SPV_KHR_bfloat16;
556 extensions.push_back(ext);
559 if (isa<Float8E4M3FNType, Float8E5M2Type>(type)) {
560 static constexpr auto ext = Extension::SPV_EXT_float8;
561 extensions.push_back(ext);
571 case StorageClass::PushConstant:
572 case StorageClass::StorageBuffer:
573 case StorageClass::Uniform:
575 static constexpr auto ext = Extension::SPV_KHR_8bit_storage;
576 extensions.push_back(ext);
579 case StorageClass::Input:
580 case StorageClass::Output:
582 static constexpr auto ext = Extension::SPV_KHR_16bit_storage;
583 extensions.push_back(ext);
591void TypeCapabilityVisitor::addConcrete(
ScalarType type) {
598#define STORAGE_CASE(storage, cap8, cap16) \
599 case StorageClass::storage: { \
600 if (bitwidth == 8) { \
601 static constexpr auto cap = Capability::cap8; \
602 capabilities.push_back(cap); \
605 if (bitwidth == 16) { \
606 static constexpr auto cap = Capability::cap16; \
607 capabilities.push_back(cap); \
618 STORAGE_CASE(PushConstant, StoragePushConstant8, StoragePushConstant16);
620 StorageBuffer16BitAccess);
623 case StorageClass::Input:
624 case StorageClass::Output: {
625 if (bitwidth == 16) {
626 static constexpr auto cap = Capability::StorageInputOutput16;
627 capabilities.push_back(cap);
641#define WIDTH_CASE(type, width) \
643 static constexpr auto cap = Capability::type##width; \
644 capabilities.push_back(cap); \
647 if (
auto intType = dyn_cast<IntegerType>(type)) {
656 llvm_unreachable(
"invalid bitwidth to getCapabilities");
659 assert(isa<FloatType>(type));
662 if (isa<Float8E4M3FNType, Float8E5M2Type>(type)) {
663 static constexpr auto cap = Capability::Float8EXT;
664 capabilities.push_back(cap);
666 llvm_unreachable(
"invalid 8-bit float type to getCapabilities");
671 if (isa<BFloat16Type>(type)) {
672 static constexpr auto cap = Capability::BFloat16TypeKHR;
673 capabilities.push_back(cap);
675 static constexpr auto cap = Capability::Float16;
676 capabilities.push_back(cap);
684 llvm_unreachable(
"invalid bitwidth to getCapabilities");
699 if (isa<ScalarType>(type))
701 if (
auto vectorType = dyn_cast<VectorType>(type))
703 if (
auto tensorArmType = dyn_cast<TensorArmType>(type))
704 return isa<ScalarType>(tensorArmType.getElementType());
713 std::optional<StorageClass> storage) {
714 TypeExtensionVisitor{extensions, storage}.add(*
this);
719 std::optional<StorageClass> storage) {
720 TypeCapabilityVisitor{capabilities, storage}.add(*
this);
725 .Case([](
ScalarType type) -> std::optional<int64_t> {
738 .Case([](
ArrayType type) -> std::optional<int64_t> {
741 auto elementType = cast<SPIRVType>(type.getElementType());
742 if (std::optional<int64_t> size = elementType.getSizeInBytes())
743 return (*size + type.getArrayStride()) * type.getNumElements();
746 .Case<VectorType, TensorArmType>([](
auto type) -> std::optional<int64_t> {
747 if (std::optional<int64_t> elementSize =
748 cast<ScalarType>(type.getElementType()).getSizeInBytes())
749 return *elementSize * type.getNumElements();
752 .Default(std::nullopt);
789 auto image = dyn_cast<ImageType>(imageType);
791 return emitError() <<
"expected image type";
796 if (llvm::is_contained({Dim::SubpassData, Dim::Buffer}, image.getDim()))
797 return emitError() <<
"Dim must not be SubpassData or Buffer";
898 StringRef keyIdentifier = std::get<0>(key);
900 if (!keyIdentifier.empty()) {
912 const Type *typesList =
nullptr;
913 if (!keyTypes.empty()) {
914 typesList = allocator.
copyInto(keyTypes).data();
918 if (!std::get<2>(key).empty()) {
920 assert(keyOffsetInfo.size() == keyTypes.size() &&
921 "size of offset information must be same as the size of number of "
923 offsetInfoList = allocator.
copyInto(keyOffsetInfo).data();
928 if (!std::get<3>(key).empty()) {
929 auto keyMemberDecorations = std::get<3>(key);
931 memberDecorationList = allocator.
copyInto(keyMemberDecorations).data();
936 if (!std::get<4>(key).empty()) {
937 auto keyStructDecorations = std::get<4>(key);
939 structDecorationList = allocator.
copyInto(keyStructDecorations).data();
1004 if (!structMemberTypes.empty())
1006 allocator.
copyInto(structMemberTypes).data());
1008 if (!structOffsetInfo.empty()) {
1009 assert(structOffsetInfo.size() == structMemberTypes.size() &&
1010 "size of offset information must be same as the size of number of "
1015 if (!structMemberDecorationInfo.empty()) {
1018 allocator.
copyInto(structMemberDecorationInfo).data();
1021 if (!structDecorationInfo.empty()) {
1044 assert(!memberTypes.empty() &&
"Struct needs at least one member type");
1048 llvm::array_pod_sort(sortedMemberDecorations.begin(),
1049 sortedMemberDecorations.end());
1052 llvm::array_pod_sort(sortedStructDecorations.begin(),
1053 sortedStructDecorations.end());
1055 return Base::get(memberTypes.vec().front().getContext(),
1056 StringRef(), memberTypes, offsetInfo,
1057 sortedMemberDecorations, sortedStructDecorations);
1061 StringRef identifier) {
1062 assert(!identifier.empty() &&
1063 "StructType identifier must be non-empty string");
1084 return newStructType;
1095 return getImpl()->memberTypesAndIsBodySet.getPointer()[
index];
1107 getImpl()->getStructDecorationsInfo())
1108 if (info.decoration == decoration)
1122 memberDecorations.clear();
1123 auto implMemberDecorations =
getImpl()->getMemberDecorationsInfo();
1124 memberDecorations.append(implMemberDecorations.begin(),
1125 implMemberDecorations.end());
1132 auto memberDecorations =
getImpl()->getMemberDecorationsInfo();
1133 decorationsInfo.clear();
1134 for (
const auto &memberDecoration : memberDecorations) {
1135 if (memberDecoration.memberIndex ==
index) {
1136 decorationsInfo.push_back(memberDecoration);
1138 if (memberDecoration.memberIndex >
index) {
1148 structDecorations.clear();
1149 auto implDecorations =
getImpl()->getStructDecorationsInfo();
1150 structDecorations.append(implDecorations.begin(), implDecorations.end());
1158 return Base::mutate(memberTypes, offsetInfo, memberDecorations,
1164 return llvm::hash_combine(memberDecorationInfo.
memberIndex,
1170 return llvm::hash_value(structDecorationInfo.
decoration);
1181 using KeyTy = std::tuple<Type, int64_t>;
1185 shape({cast<VectorType>(std::get<0>(key)).getShape()[0],
1186 std::get<1>(key)}) {}
1209 Type columnType, uint32_t columnCount) {
1216 Type columnType, uint32_t columnCount) {
1217 if (columnCount < 2 || columnCount > 4)
1218 return emitError() <<
"matrix can have 2, 3, or 4 columns only";
1221 return emitError() <<
"matrix columns must be vectors of floats";
1225 if (columnShape.size() != 1)
1226 return emitError() <<
"matrix columns must be 1D vectors";
1228 if (columnShape[0] < 2 || columnShape[0] > 4)
1229 return emitError() <<
"matrix columns must be of size 2, 3, or 4";
1236 if (
auto vectorType = dyn_cast<VectorType>(columnType)) {
1237 if (isa<FloatType>(vectorType.getElementType()))
1246 return cast<VectorType>(
getImpl()->columnType).getElementType();
1251 assert(
getImpl()->
shape[1] <= std::numeric_limits<unsigned>::max());
1252 return static_cast<uint32_t
>(
getImpl()->shape[1]);
1257 assert(
getImpl()->
shape[0] <= std::numeric_limits<unsigned>::max());
1258 return static_cast<uint32_t
>(
getImpl()->shape[0]);
1267void TypeCapabilityVisitor::addConcrete(
MatrixType type) {
1269 static constexpr auto cap = Capability::Matrix;
1270 capabilities.push_back(cap);
1309 Type elementType)
const {
1318 static constexpr auto ext = Extension::SPV_ARM_tensors;
1319 extensions.push_back(ext);
1322void TypeCapabilityVisitor::addConcrete(
TensorArmType type) {
1324 static constexpr auto cap = Capability::TensorsARM;
1325 capabilities.push_back(cap);
1331 if (llvm::is_contained(
shape, 0))
1332 return emitError() <<
"arm.tensor do not support dimensions = 0";
1333 if (llvm::any_of(
shape, [](
int64_t dim) {
return dim < 0; }) &&
1334 llvm::any_of(
shape, [](
int64_t dim) {
return dim > 0; }))
1336 <<
"arm.tensor shape dimensions must be either fully dynamic or "
1345void SPIRVDialect::registerTypes() {
*if copies could not be generated due to yet unimplemented cases *copyInPlacementStart and copyOutPlacementStart in copyPlacementBlock *specify the insertion points where the incoming copies and outgoing should be inserted(the insertion happens right before the *insertion point). Since `begin` can itself be invalidated due to the memref *rewriting done from this method
false
Parses a map_entries map type from a string format back into its numeric value.
constexpr unsigned getNumBits< ImageSamplerUseInfo >()
#define STORAGE_CASE(storage, cap8, cap16)
constexpr unsigned getNumBits< ImageFormat >()
static constexpr unsigned getNumBits()
#define WIDTH_CASE(type, width)
constexpr unsigned getNumBits< ImageArrayedInfo >()
constexpr unsigned getNumBits< ImageSamplingInfo >()
constexpr unsigned getNumBits< Dim >()
constexpr unsigned getNumBits< ImageDepthInfo >()
This class represents a diagnostic that is inflight and set to be reported.
MLIRContext is the top-level object for a collection of MLIR operations.
ArrayRef< T > copyInto(ArrayRef< T > elements)
Copy the specified array of elements into memory managed by our bump pointer allocator.
T * allocate()
Allocate an instance of the provided type.
This class provides an abstraction over the various different ranges of value types.
TypeStorage()
This constructor is used by derived classes as part of the TypeUniquer.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Dialect & getDialect() const
Get the dialect this type is registered to.
MLIRContext * getContext() const
Return the MLIRContext in which this type was uniqued.
bool isIntOrFloat() const
Return true if this is an integer (of any signedness) or a float type.
unsigned getIntOrFloatBitWidth() const
Return the bit width of an integer or a float type, assert failure on other types.
static ConcreteType get(MLIRContext *ctx, Args &&...args)
LogicalResult mutate(Args &&...args)
static ConcreteType getChecked(const Location &loc, Args &&...args)
ImplType * getImpl() const
Type getElementType() const
unsigned getArrayStride() const
Returns the array stride in bytes.
unsigned getNumElements() const
static ArrayType get(Type elementType, unsigned elementCount)
bool hasCompileTimeKnownNumElements() const
Return true if the number of elements is known at compile time and is not implementation dependent.
unsigned getNumElements() const
Return the number of elements of the type.
static bool isValid(VectorType)
Returns true if the given vector type is valid for the SPIR-V dialect.
Type getElementType(unsigned) const
static bool classof(Type type)
Scope getScope() const
Returns the scope of the matrix.
uint32_t getRows() const
Returns the number of rows of the matrix.
uint32_t getColumns() const
Returns the number of columns of the matrix.
static CooperativeMatrixType get(Type elementType, uint32_t rows, uint32_t columns, Scope scope, CooperativeMatrixUseKHR use)
ArrayRef< int64_t > getShape() const
Type getElementType() const
CooperativeMatrixUseKHR getUse() const
Returns the use parameter of the cooperative matrix.
static ImageType get(Type elementType, Dim dim, ImageDepthInfo depth=ImageDepthInfo::DepthUnknown, ImageArrayedInfo arrayed=ImageArrayedInfo::NonArrayed, ImageSamplingInfo samplingInfo=ImageSamplingInfo::SingleSampled, ImageSamplerUseInfo samplerUse=ImageSamplerUseInfo::SamplerUnknown, ImageFormat format=ImageFormat::Unknown)
ImageDepthInfo getDepthInfo() const
ImageArrayedInfo getArrayedInfo() const
ImageFormat getImageFormat() const
ImageSamplerUseInfo getSamplerUseInfo() const
Type getElementType() const
ImageSamplingInfo getSamplingInfo() const
static MatrixType getChecked(function_ref< InFlightDiagnostic()> emitError, Type columnType, uint32_t columnCount)
unsigned getNumElements() const
Returns total number of elements (rows*columns).
static MatrixType get(Type columnType, uint32_t columnCount)
Type getColumnType() const
static LogicalResult verifyInvariants(function_ref< InFlightDiagnostic()> emitError, Type columnType, uint32_t columnCount)
unsigned getNumColumns() const
Returns the number of columns.
static bool isValidColumnType(Type columnType)
Returns true if the matrix elements are vectors of float elements.
Type getElementType() const
Returns the elements' type (i.e, single element type).
ArrayRef< int64_t > getShape() const
unsigned getNumRows() const
Returns the number of rows.
Type getPointeeType() const
StorageClass getStorageClass() const
static PointerType get(Type pointeeType, StorageClass storageClass)
Type getElementType() const
unsigned getArrayStride() const
Returns the array stride in bytes.
static RuntimeArrayType get(Type elementType)
std::optional< int64_t > getSizeInBytes()
Returns the size in bytes for each type.
static bool classof(Type type)
void getCapabilities(CapabilityArrayRefVector &capabilities, std::optional< StorageClass > storage=std::nullopt)
Appends to capabilities the capabilities needed for this type to appear in the given storage class.
SmallVectorImpl< ArrayRef< Capability > > CapabilityArrayRefVector
The capability requirements for each type are following the ((Capability::A OR Extension::B) AND (Cap...
void getExtensions(ExtensionArrayRefVector &extensions, std::optional< StorageClass > storage=std::nullopt)
Appends to extensions the extensions needed for this type to appear in the given storage class.
SmallVectorImpl< ArrayRef< Extension > > ExtensionArrayRefVector
The extension requirements for each type are following the ((Extension::A OR Extension::B) AND (Exten...
static LogicalResult verifyInvariants(function_ref< InFlightDiagnostic()> emitError, Type imageType)
static SampledImageType getChecked(function_ref< InFlightDiagnostic()> emitError, Type imageType)
Type getImageType() const
static SampledImageType get(Type imageType)
static SamplerType get(MLIRContext *context)
static bool classof(Type type)
static bool isValid(FloatType)
Returns true if the given float type is valid for the SPIR-V dialect.
void getStructDecorations(SmallVectorImpl< StructType::StructDecorationInfo > &structDecorations) const
void getMemberDecorations(SmallVectorImpl< StructType::MemberDecorationInfo > &memberDecorations) const
static StructType getIdentified(MLIRContext *context, StringRef identifier)
Construct an identified StructType.
bool isIdentified() const
Returns true if the StructType is identified.
StringRef getIdentifier() const
For literal structs, return an empty string.
static StructType getEmpty(MLIRContext *context, StringRef identifier="")
Construct a (possibly identified) StructType with no members.
bool hasDecoration(spirv::Decoration decoration) const
Returns true if the struct has a specified decoration.
unsigned getNumElements() const
Type getElementType(unsigned) const
LogicalResult trySetBody(ArrayRef< Type > memberTypes, ArrayRef< OffsetInfo > offsetInfo={}, ArrayRef< MemberDecorationInfo > memberDecorations={}, ArrayRef< StructDecorationInfo > structDecorations={})
Sets the contents of an incomplete identified StructType.
TypeRange getElementTypes() const
static StructType get(ArrayRef< Type > memberTypes, ArrayRef< OffsetInfo > offsetInfo={}, ArrayRef< MemberDecorationInfo > memberDecorations={}, ArrayRef< StructDecorationInfo > structDecorations={})
Construct a literal StructType with at least one member.
uint64_t getMemberOffset(unsigned) const
static LogicalResult verifyInvariants(function_ref< InFlightDiagnostic()> emitError, ArrayRef< int64_t > shape, Type elementType)
Type getElementType() const
static TensorArmType get(ArrayRef< int64_t > shape, Type elementType)
TensorArmType cloneWith(std::optional< ArrayRef< int64_t > > shape, Type elementType) const
ArrayRef< int64_t > getShape() const
llvm::hash_code hash_value(const StructType::MemberDecorationInfo &memberDecorationInfo)
Include the generated interface declarations.
StorageUniquer::StorageAllocator TypeStorageAllocator
This is a utility allocator used to allocate memory for instances of derived Types.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
llvm::TypeSwitch< T, ResultT > TypeSwitch
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
llvm::function_ref< Fn > function_ref
ArrayTypeStorage(const KeyTy &key)
static ArrayTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
std::tuple< Type, unsigned, unsigned > KeyTy
bool operator==(const KeyTy &key) const
CooperativeMatrixTypeStorage(const KeyTy &key)
static CooperativeMatrixTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
CooperativeMatrixUseKHR use
std::array< int64_t, 2 > shape
std::tuple< Type, int64_t, int64_t, Scope, CooperativeMatrixUseKHR > KeyTy
bool operator==(const KeyTy &key) const
std::tuple< Type, Dim, ImageDepthInfo, ImageArrayedInfo, ImageSamplingInfo, ImageSamplerUseInfo, ImageFormat > KeyTy
bool operator==(const KeyTy &key) const
ImageSamplerUseInfo samplerUseInfo
static ImageTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
ImageTypeStorage(const KeyTy &key)
ImageSamplingInfo samplingInfo
ImageArrayedInfo arrayedInfo
MatrixTypeStorage(const KeyTy &key)
std::array< int64_t, 2 > shape
std::tuple< Type, int64_t > KeyTy
bool operator==(const KeyTy &key) const
static MatrixTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
StorageClass storageClass
static PointerTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
PointerTypeStorage(const KeyTy &key)
bool operator==(const KeyTy &key) const
std::pair< Type, StorageClass > KeyTy
RuntimeArrayTypeStorage(const KeyTy &key)
static RuntimeArrayTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
std::pair< Type, unsigned > KeyTy
bool operator==(const KeyTy &key) const
bool operator==(const KeyTy &key) const
static SampledImageTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
SampledImageTypeStorage(const KeyTy &key)
Type storage for SPIR-V structure types:
ArrayRef< StructType::MemberDecorationInfo > getMemberDecorationsInfo() const
StructType::OffsetInfo const * offsetInfo
static StructTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
If the given key contains a non-empty identifier, this method constructs an identified struct and lea...
bool operator==(const KeyTy &key) const
For identified structs, return true if the given key contains the same identifier.
std::tuple< StringRef, ArrayRef< Type >, ArrayRef< StructType::OffsetInfo >, ArrayRef< StructType::MemberDecorationInfo >, ArrayRef< StructType::StructDecorationInfo > > KeyTy
A storage key is divided into 2 parts:
ArrayRef< StructType::OffsetInfo > getOffsetInfo() const
StructTypeStorage(StringRef identifier)
Construct a storage object for an identified struct type.
unsigned numStructDecorations
ArrayRef< StructType::StructDecorationInfo > getStructDecorationsInfo() const
StructType::MemberDecorationInfo const * memberDecorationsInfo
StructTypeStorage(unsigned numMembers, Type const *memberTypes, StructType::OffsetInfo const *layoutInfo, unsigned numMemberDecorations, StructType::MemberDecorationInfo const *memberDecorationsInfo, unsigned numStructDecorations, StructType::StructDecorationInfo const *structDecorationsInfo)
Construct a storage object for a literal struct type.
StructType::StructDecorationInfo const * structDecorationsInfo
llvm::PointerIntPair< Type const *, 1, bool > memberTypesAndIsBodySet
StringRef getIdentifier() const
ArrayRef< Type > getMemberTypes() const
unsigned numMemberDecorations
bool isIdentified() const
LogicalResult mutate(TypeStorageAllocator &allocator, ArrayRef< Type > structMemberTypes, ArrayRef< StructType::OffsetInfo > structOffsetInfo, ArrayRef< StructType::MemberDecorationInfo > structMemberDecorationInfo, ArrayRef< StructType::StructDecorationInfo > structDecorationInfo)
Sets the struct type content for identified structs.
static TensorArmTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
static llvm::hash_code hashKey(const KeyTy &key)
std::tuple< ArrayRef< int64_t >, Type > KeyTy
TensorArmTypeStorage(ArrayRef< int64_t > shape, Type elementType)
bool operator==(const KeyTy &key) const
ArrayRef< int64_t > shape