MLIR  15.0.0git
SPIRVConversion.h
Go to the documentation of this file.
1 //===- SPIRVConversion.h - SPIR-V Conversion Utilities ----------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Defines utilities to use while converting to the SPIR-V dialect.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef MLIR_DIALECT_SPIRV_TRANSFORMS_SPIRVCONVERSION_H
14 #define MLIR_DIALECT_SPIRV_TRANSFORMS_SPIRVCONVERSION_H
15 
20 #include "llvm/ADT/SmallSet.h"
21 
22 namespace mlir {
23 
24 //===----------------------------------------------------------------------===//
25 // Type Converter
26 //===----------------------------------------------------------------------===//
27 
28 /// Type conversion from builtin types to SPIR-V types for shader interface.
29 ///
30 /// For memref types, this converter additionally performs type wrapping to
31 /// satisfy shader interface requirements: shader interface types must be
32 /// pointers to structs.
34 public:
35  struct Options {
36  /// Whether to emulate non-32-bit scalar types with 32-bit scalar types if
37  /// no native support.
38  ///
39  /// Non-32-bit scalar types require special hardware support that may not
40  /// exist on all GPUs. This is reflected in SPIR-V as that non-32-bit scalar
41  /// types require special capabilities or extensions. This option controls
42  /// whether to use 32-bit types to emulate, if a scalar type of a certain
43  /// bitwidth is not supported in the target environment. This requires the
44  /// runtime to also feed in data with a matched bitwidth and layout for
45  /// interface types. The runtime can do that by inspecting the SPIR-V
46  /// module.
47  ///
48  /// If the original scalar type has less than 32-bit, a multiple of its
49  /// values will be packed into one 32-bit value to be memory efficient.
51 
52  /// Use 64-bit integers to convert index types.
53  bool use64bitIndex{false};
54 
55  /// The number of bits to store a boolean value. It is eight bits by
56  /// default.
57  unsigned boolNumBits{8};
58 
59  // Note: we need this instead of inline initializers because of
60  // https://bugs.llvm.org/show_bug.cgi?id=36684
62 
63  {}
64  };
65 
66  explicit SPIRVTypeConverter(spirv::TargetEnvAttr targetAttr,
67  Options options = {});
68 
69  /// Gets the SPIR-V correspondence for the standard index type.
70  Type getIndexType() const;
71 
72  /// Returns the corresponding memory space for memref given a SPIR-V storage
73  /// class.
74  static unsigned getMemorySpaceForStorageClass(spirv::StorageClass);
75 
76  /// Returns the SPIR-V storage class given a memory space for memref. Return
77  /// llvm::None if the memory space does not map to any SPIR-V storage class.
79  getStorageClassForMemorySpace(unsigned space);
80 
81  /// Returns the options controlling the SPIR-V type converter.
82  const Options &getOptions() const;
83 
84 private:
85  spirv::TargetEnv targetEnv;
86  Options options;
87 
88  MLIRContext *getContext() const;
89 };
90 
91 //===----------------------------------------------------------------------===//
92 // Conversion Target
93 //===----------------------------------------------------------------------===//
94 
95 // The default SPIR-V conversion target.
96 //
97 // It takes a SPIR-V target environment and controls operation legality based on
98 // the their availability in the target environment.
100 public:
101  /// Creates a SPIR-V conversion target for the given target environment.
102  static std::unique_ptr<SPIRVConversionTarget>
103  get(spirv::TargetEnvAttr targetAttr);
104 
105 private:
106  explicit SPIRVConversionTarget(spirv::TargetEnvAttr targetAttr);
107 
108  // Be explicit that instance of this class cannot be copied or moved: there
109  // are lambdas capturing fields of the instance.
112  SPIRVConversionTarget &operator=(const SPIRVConversionTarget &) = delete;
113  SPIRVConversionTarget &operator=(SPIRVConversionTarget &&) = delete;
114 
115  /// Returns true if the given `op` is legal to use under the current target
116  /// environment.
117  bool isLegalOp(Operation *op);
118 
119  spirv::TargetEnv targetEnv;
120 };
121 
122 //===----------------------------------------------------------------------===//
123 // Patterns and Utility Functions
124 //===----------------------------------------------------------------------===//
125 
126 /// Appends to a pattern list additional patterns for translating the builtin
127 /// `func` op to the SPIR-V dialect. These patterns do not handle shader
128 /// interface/ABI; they convert function parameters to be of SPIR-V allowed
129 /// types.
131  RewritePatternSet &patterns);
132 
133 namespace spirv {
134 class AccessChainOp;
135 
136 /// Returns the value for the given `builtin` variable. This function gets or
137 /// inserts the global variable associated for the builtin within the nearest
138 /// symbol table enclosing `op`. Returns null Value on error.
139 Value getBuiltinVariableValue(Operation *op, BuiltIn builtin, Type integerType,
140  OpBuilder &builder);
141 
142 /// Gets the value at the given `offset` of the push constant storage with a
143 /// total of `elementCount` `integerType` integers. A global variable will be
144 /// created in the nearest symbol table enclosing `op` for the push constant
145 /// storage if not existing. Load ops will be created via the given `builder` to
146 /// load values from the push constant. Returns null Value on error.
147 Value getPushConstantValue(Operation *op, unsigned elementCount,
148  unsigned offset, Type integerType,
149  OpBuilder &builder);
150 
151 /// Generates IR to perform index linearization with the given `indices` and
152 /// their corresponding `strides`, adding an initial `offset`.
154  int64_t offset, Type integerType, Location loc,
155  OpBuilder &builder);
156 
157 /// Performs the index computation to get to the element at `indices` of the
158 /// memory pointed to by `basePtr`, using the layout map of `baseType`.
159 /// Returns null if index computation cannot be performed.
160 
161 // TODO: This method assumes that the `baseType` is a MemRefType with AffineMap
162 // that has static strides. Extend to handle dynamic strides.
163 spirv::AccessChainOp getElementPtr(SPIRVTypeConverter &typeConverter,
164  MemRefType baseType, Value basePtr,
165  ValueRange indices, Location loc,
166  OpBuilder &builder);
167 
168 } // namespace spirv
169 } // namespace mlir
170 
171 #endif // MLIR_DIALECT_SPIRV_TRANSFORMS_SPIRVCONVERSION_H
Include the generated interface declarations.
Type getIndexType() const
Gets the SPIR-V correspondence for the standard index type.
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:28
const Options & getOptions() const
Returns the options controlling the SPIR-V type converter.
bool use64bitIndex
Use 64-bit integers to convert index types.
static unsigned getMemorySpaceForStorageClass(spirv::StorageClass)
Returns the corresponding memory space for memref given a SPIR-V storage class.
SPIRVTypeConverter(spirv::TargetEnvAttr targetAttr, Options options={})
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:48
Value getBuiltinVariableValue(Operation *op, BuiltIn builtin, Type integerType, OpBuilder &builder)
Returns the value for the given builtin variable.
void populateBuiltinFuncToSPIRVPatterns(SPIRVTypeConverter &typeConverter, RewritePatternSet &patterns)
Appends to a pattern list additional patterns for translating the builtin func op to the SPIR-V diale...
A wrapper class around a spirv::TargetEnvAttr to provide query methods for allowed version/capabiliti...
Definition: TargetAndABI.h:28
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:72
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:85
Value getPushConstantValue(Operation *op, unsigned elementCount, unsigned offset, Type integerType, OpBuilder &builder)
Gets the value at the given offset of the push constant storage with a total of elementCount integerT...
Type conversion class.
Value linearizeIndex(ValueRange indices, ArrayRef< int64_t > strides, int64_t offset, Type integerType, Location loc, OpBuilder &builder)
Generates IR to perform index linearization with the given indices and their corresponding strides...
spirv::AccessChainOp getElementPtr(SPIRVTypeConverter &typeConverter, MemRefType baseType, Value basePtr, ValueRange indices, Location loc, OpBuilder &builder)
Performs the index computation to get to the element at indices of the memory pointed to by basePtr...
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:55
unsigned boolNumBits
The number of bits to store a boolean value.
This class describes a specific conversion target.
static Optional< spirv::StorageClass > getStorageClassForMemorySpace(unsigned space)
Returns the SPIR-V storage class given a memory space for memref.
This class helps build Operations.
Definition: Builders.h:177
This class provides an abstraction over the different types of ranges over Values.
bool emulateNon32BitScalarTypes
Whether to emulate non-32-bit scalar types with 32-bit scalar types if no native support.
An attribute that specifies the target version, allowed extensions and capabilities, and resource limits.
Type conversion from builtin types to SPIR-V types for shader interface.