-
Notifications
You must be signed in to change notification settings - Fork 10.7k
/
SPIRVTypes.h
320 lines (252 loc) · 11.5 KB
/
SPIRVTypes.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
//===- SPIRVTypes.h - MLIR SPIR-V Types -------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file declares the types in the SPIR-V dialect.
//
//===----------------------------------------------------------------------===//
#ifndef MLIR_DIALECT_SPIRV_SPIRVTYPES_H_
#define MLIR_DIALECT_SPIRV_SPIRVTYPES_H_
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/TypeSupport.h"
#include "mlir/IR/Types.h"
#include <tuple>
// Forward declare enum classes related to op availability. Their definitions
// are in the TableGen'erated SPIRVEnums.h.inc and can be referenced by other
// declarations in SPIRVEnums.h.inc.
namespace mlir {
namespace spirv {
enum class Version : uint32_t;
enum class Extension;
enum class Capability : uint32_t;
} // namespace spirv
} // namespace mlir
// Pull in all enum type definitions and utility function declarations
#include "mlir/Dialect/SPIRV/SPIRVEnums.h.inc"
// Pull in all enum type availability query function declarations
#include "mlir/Dialect/SPIRV/SPIRVEnumAvailability.h.inc"
namespace mlir {
namespace spirv {
/// Returns the implied extensions for the given version. These extensions are
/// incorporated into the current version so they are implicitly declared when
/// targeting the given version.
ArrayRef<Extension> getImpliedExtensions(Version version);
/// Returns the directly implied capabilities for the given capability. These
/// capabilities are implicitly declared by the given capability.
ArrayRef<Capability> getDirectImpliedCapabilities(Capability cap);
/// Returns the recursively implied capabilities for the given capability. These
/// capabilities are implicitly declared by the given capability. Compared to
/// the above function, this function collects implied capabilities recursively:
/// if an implicitly declared capability implicitly declares a third one, the
/// third one will also be returned.
SmallVector<Capability, 0> getRecursiveImpliedCapabilities(Capability cap);
namespace detail {
struct ArrayTypeStorage;
struct ImageTypeStorage;
struct PointerTypeStorage;
struct RuntimeArrayTypeStorage;
struct StructTypeStorage;
} // namespace detail
namespace TypeKind {
enum Kind {
Array = Type::FIRST_SPIRV_TYPE,
Image,
Pointer,
RuntimeArray,
Struct,
LAST_SPIRV_TYPE = Struct,
};
}
// Base SPIR-V type for providing availability queries.
class SPIRVType : public Type {
public:
using Type::Type;
static bool classof(Type type);
/// The extension requirements for each type are following the
/// ((Extension::A OR Extension::B) AND (Extension::C OR Extension::D))
/// convention.
using ExtensionArrayRefVector = SmallVectorImpl<ArrayRef<spirv::Extension>>;
/// Appends to `extensions` the extensions needed for this type to appear in
/// the given `storage` class. This method does not guarantee the uniqueness
/// of extensions; the same extension may be appended multiple times.
void getExtensions(ExtensionArrayRefVector &extensions,
Optional<spirv::StorageClass> storage = llvm::None);
/// The capability requirements for each type are following the
/// ((Capability::A OR Extension::B) AND (Capability::C OR Capability::D))
/// convention.
using CapabilityArrayRefVector = SmallVectorImpl<ArrayRef<spirv::Capability>>;
/// Appends to `capabilities` the capabilities needed for this type to appear
/// in the given `storage` class. This method does not guarantee the
/// uniqueness of capabilities; the same capability may be appended multiple
/// times.
void getCapabilities(CapabilityArrayRefVector &capabilities,
Optional<spirv::StorageClass> storage = llvm::None);
};
// SPIR-V scalar type: bool type, integer type, floating point type.
class ScalarType : public SPIRVType {
public:
using SPIRVType::SPIRVType;
static bool classof(Type type);
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
Optional<spirv::StorageClass> storage = llvm::None);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
Optional<spirv::StorageClass> storage = llvm::None);
};
// SPIR-V composite type: VectorType, SPIR-V ArrayType, or SPIR-V StructType.
class CompositeType : public SPIRVType {
public:
using SPIRVType::SPIRVType;
static bool classof(Type type);
unsigned getNumElements() const;
Type getElementType(unsigned) const;
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
Optional<spirv::StorageClass> storage = llvm::None);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
Optional<spirv::StorageClass> storage = llvm::None);
};
// SPIR-V array type
class ArrayType : public Type::TypeBase<ArrayType, CompositeType,
detail::ArrayTypeStorage> {
public:
using Base::Base;
// Zero layout specifies that is no layout
using LayoutInfo = uint64_t;
static bool kindof(unsigned kind) { return kind == TypeKind::Array; }
static ArrayType get(Type elementType, unsigned elementCount);
static ArrayType get(Type elementType, unsigned elementCount,
LayoutInfo layoutInfo);
unsigned getNumElements() const;
Type getElementType() const;
bool hasLayout() const;
uint64_t getArrayStride() const;
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
Optional<spirv::StorageClass> storage = llvm::None);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
Optional<spirv::StorageClass> storage = llvm::None);
};
// SPIR-V image type
class ImageType
: public Type::TypeBase<ImageType, SPIRVType, detail::ImageTypeStorage> {
public:
using Base::Base;
static bool kindof(unsigned kind) { return kind == TypeKind::Image; }
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) {
return ImageType::get(
std::tuple<Type, Dim, ImageDepthInfo, ImageArrayedInfo,
ImageSamplingInfo, ImageSamplerUseInfo, ImageFormat>(
elementType, dim, depth, arrayed, samplingInfo, samplerUse,
format));
}
static ImageType
get(std::tuple<Type, Dim, ImageDepthInfo, ImageArrayedInfo,
ImageSamplingInfo, ImageSamplerUseInfo, ImageFormat>);
Type getElementType() const;
Dim getDim() const;
ImageDepthInfo getDepthInfo() const;
ImageArrayedInfo getArrayedInfo() const;
ImageSamplingInfo getSamplingInfo() const;
ImageSamplerUseInfo getSamplerUseInfo() const;
ImageFormat getImageFormat() const;
// TODO(ravishankarm): Add support for Access qualifier
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
Optional<spirv::StorageClass> storage = llvm::None);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
Optional<spirv::StorageClass> storage = llvm::None);
};
// SPIR-V pointer type
class PointerType : public Type::TypeBase<PointerType, SPIRVType,
detail::PointerTypeStorage> {
public:
using Base::Base;
static bool kindof(unsigned kind) { return kind == TypeKind::Pointer; }
static PointerType get(Type pointeeType, StorageClass storageClass);
Type getPointeeType() const;
StorageClass getStorageClass() const;
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
Optional<spirv::StorageClass> storage = llvm::None);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
Optional<spirv::StorageClass> storage = llvm::None);
};
// SPIR-V run-time array type
class RuntimeArrayType
: public Type::TypeBase<RuntimeArrayType, SPIRVType,
detail::RuntimeArrayTypeStorage> {
public:
using Base::Base;
static bool kindof(unsigned kind) { return kind == TypeKind::RuntimeArray; }
static RuntimeArrayType get(Type elementType);
Type getElementType() const;
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
Optional<spirv::StorageClass> storage = llvm::None);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
Optional<spirv::StorageClass> storage = llvm::None);
};
// SPIR-V struct type
class StructType : public Type::TypeBase<StructType, CompositeType,
detail::StructTypeStorage> {
public:
using Base::Base;
// Layout information used for members in a struct in SPIR-V
//
// TODO(ravishankarm) : For now this only supports the offset type, so uses
// uint64_t value to represent the offset, with
// std::numeric_limit<uint64_t>::max indicating no offset. Change this to
// something that can hold all the information needed for different member
// types
using LayoutInfo = uint64_t;
using MemberDecorationInfo = std::pair<uint32_t, spirv::Decoration>;
static bool kindof(unsigned kind) { return kind == TypeKind::Struct; }
/// Construct a StructType with at least one member.
static StructType get(ArrayRef<Type> memberTypes,
ArrayRef<LayoutInfo> layoutInfo = {},
ArrayRef<MemberDecorationInfo> memberDecorations = {});
/// Construct a struct with no members.
static StructType getEmpty(MLIRContext *context);
unsigned getNumElements() const;
Type getElementType(unsigned) const;
/// Range class for element types.
class ElementTypeRange
: public ::mlir::detail::indexed_accessor_range_base<
ElementTypeRange, const Type *, Type, Type, Type> {
private:
using RangeBaseT::RangeBaseT;
/// See `mlir::detail::indexed_accessor_range_base` for details.
static const Type *offset_base(const Type *object, ptrdiff_t index) {
return object + index;
}
/// See `mlir::detail::indexed_accessor_range_base` for details.
static Type dereference_iterator(const Type *object, ptrdiff_t index) {
return object[index];
}
/// Allow base class access to `offset_base` and `dereference_iterator`.
friend RangeBaseT;
};
ElementTypeRange getElementTypes() const;
bool hasLayout() const;
uint64_t getOffset(unsigned) const;
// Returns in `allMemberDecorations` the spirv::Decorations (apart from
// Offset) associated with all members of the StructType.
void getMemberDecorations(SmallVectorImpl<StructType::MemberDecorationInfo>
&allMemberDecorations) const;
// Returns in `memberDecorations` all the spirv::Decorations (apart from
// Offset) associated with the `i`-th member of the StructType.
void getMemberDecorations(
unsigned i, SmallVectorImpl<spirv::Decoration> &memberDecorations) const;
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
Optional<spirv::StorageClass> storage = llvm::None);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
Optional<spirv::StorageClass> storage = llvm::None);
};
} // end namespace spirv
} // end namespace mlir
#endif // MLIR_DIALECT_SPIRV_SPIRVTYPES_H_