Index: mlir/docs/Dialects/SPIR-V.md =================================================================== --- mlir/docs/Dialects/SPIR-V.md +++ mlir/docs/Dialects/SPIR-V.md @@ -840,7 +840,87 @@ ## Conversions -(TODO: expand this section) +One of the main features of MLIR is the ability to progressively lower from +dialects that capture programmer abstraction into dialects that are closer to a +machine representation, like SPIR-V dialect. This progressive lowering through +multiple dialects is enabled through the use of the +[DialectConversion][MlirDialectConversion] framework in MLIR. To simplify +targeting SPIR-V dialect using the Dialect Conversion framework, two utility +class are provided. + +(**Note** : While SPIR-V has some [validation rules][SpirvShaderValidation], +additional rules are imposed by [Vulkan shaders][VulkanSpirv]. The lowering +described below implements these requirements.) + + +### SPIRVTypeConverter + +The `mlir::spirv::SPIRVTypeConverter` derives from +`mlir::TypeConverter` and provides type conversion for standard +types to SPIR-V types: + +* [Standard Integer][MlirIntegerType] -> Standard Integer +* [Standard Float][MlirFloatType] -> Standard Float +* [Vector Type][MlirVectorType] -> Vector Type +* [Memref Type][MlirMemrefType] with static shape and stride -> `spv.array` + with number of elements obtained from the layout specification of the + `memref`, and same element type. + +(TODO: Generate the conversion matrix from comments automatically) + +[Index Type][MlirIndexType] need special handling since they are not directly +supported in SPIR-V. Currently the `index` type is converted to `i32`. + +(TODO: Allow for configuring the integer width to use for `index` types in the +SPIR-V dialect) + +### SPIRVOpLowering + +A base class that can be used to specify the patterns used for implementing the +lowering. For now this only provides derived classes access to an instance of +`mlir::spirv::SPIRVTypeLowering` class. + +### Utility functions for lowering + +#### Creating builtin variables + +In SPIR-V dialect, builtins are represented using `spv.globalVariable`s, with +`spv._address_of` used to get a handle to the builtin as an SSA value. The +method `mlir::spirv::getBuiltinVariableValue` returns an SSA value, and creates +a `spv.globalVariable` for the builtin in the current `spv.module` if it does +not exist already. + +#### Setting layout for shader interface variables + +SPIR-V validation rules for shaders require composite objects to be explicitly +laid out. If a `spv.globalVariable` is not explicitly laid out, the utility +method `mlir::spirv::decorateType` implements a layout consistent with +the [Vulkan shader requirements][VulkanShaderInterface]. + +#### Setting shader interface + +The method `mlir::spirv::setABIAttrs` allows setting the [shader interface +attributes](#shader-interface-abi) for a function that is to be an entry +point function within the `spv.module` on lowering. A later pass +`mlir::spirv::LowerABIAttributesPass` uses this information to lower the entry +point function and its ABI consistent with the Vulkan validation +rules. Specifically, + +* Creates `spv.globalVariable`s for the arguments, and replaces all uses of + the argument with this variable. The SSA value used for replacement is + obtained using the `spv._address_of` operation. +* Adds the `spv.EntryPoint` and `spv.ExecutionMode` operations into the + `spv.module` for the entry function. + +### Current conversions to SPIR-V + +Using the above infrastructure, conversion are implemented from + +* [Standard Dialect][MlirStandardDialect] : Only arithmetic and logical + operations conversions are implemented. +* [GPU Dialect][MlirGpuDialect] : Module with the attribute + `gpu.kernel_module` is converted to a `spv.module`. Functions within this + module with the attribute `gpu.kernel` is lowered as an entry function. ## Code organization @@ -1046,22 +1126,47 @@ ### Add a new conversion -(TODO: add details for this section) +To add conversion for a type update the `mlir::spirv::SPIRVTypeConverter` to +return the converted type (must be a valid SPIR-V type). See [Type +Conversion][MlirDialectConversionTypeConversion] for more details. + +To lower an operation into SPIR-V dialect, implement a [conversion +pattern][MlirDialectConversionRewritePattern]. If the conversion requires type +conversion as well, the pattern must inherit from the +`mlir::spirv::SPIRVOpLowering` class to get access to +`mlir::spirv::SPIRVTypeConverter`. If the operation has a region, [signature +conversion][MlirDialectConversionSignatureConversion] might be needed as well. + +**Note**: The current validation rules of `spv.module` require that all +operations contained within its region are valid operations in the SPIR-V +dialect. [Spirv]: https://www.khronos.org/registry/spir-v/ [SpirvSpec]: https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html [SpirvLogicalLayout]: https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#_a_id_logicallayout_a_logical_layout_of_a_module [SpirvGrammar]: https://raw.githubusercontent.com/KhronosGroup/SPIRV-Headers/master/include/spirv/unified1/spirv.core.grammar.json +[SpirvShaderValidation]: https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#_a_id_shadervalidation_a_validation_rules_for_shader_a_href_capability_capabilities_a [GlslStd450]: https://www.khronos.org/registry/spir-v/specs/1.0/GLSL.std.450.html [ArrayType]: https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#OpTypeArray [ImageType]: https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#OpTypeImage [PointerType]: https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#OpTypePointer [RuntimeArrayType]: https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#OpTypeRuntimeArray +[MlirDialectConversion]: https://github.com/llvm/llvm-project/blob/master/mlir/docs/DialectConversion.md [StructType]: https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#Structure [SpirvTools]: https://github.com/KhronosGroup/SPIRV-Tools [Rationale]: https://mlir.llvm.org/docs/Rationale/#block-arguments-vs-phi-nodes [ODS]: https://mlir.llvm.org/docs/OpDefinitions/ [GreedyPatternRewriter]: https://github.com/llvm/llvm-project/blob/master/mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp +[MlirDialectConversionTypeConversion]: https://github.com/llvm/llvm-project/blob/master/mlir/docs/DialectConversion.md#type-converter +[MlirDialectConversionRewritePattern]: https://github.com/llvm/llvm-project/blob/master/mlir/docs/DialectConversion.md#conversion-patterns +[MlirDialectConversionSignatureConversion]: https://github.com/llvm/llvm-project/blob/master/mlir/docs/DialectConversion.md#region-signature-conversion +[MlirIntegerType]: https://github.com/llvm/llvm-project/blob/master/mlir/docs/LangRef.md#integer-type +[MlirFloatType]: https://github.com/llvm/llvm-project/blob/master/mlir/docs/LangRef.md#floating-point-types +[MlirVectorType]: https://github.com/llvm/llvm-project/blob/master/mlir/docs/LangRef.md#vector-type +[MlirMemrefType]: https://github.com/llvm/llvm-project/blob/master/mlir/docs/LangRef.md#memref-type +[MlirIndexType]: https://github.com/llvm/llvm-project/blob/master/mlir/docs/LangRef.md#index-type +[MlirGpuDialect]: https://github.com/llvm/llvm-project/blob/master/mlir/docs/Dialects/GPU.md +[MlirStandardDialect]: https://github.com/llvm/llvm-project/blob/master/mlir/docs/Dialects/Standard.md [MlirSpirvHeaders]: https://github.com/llvm/llvm-project/tree/master/mlir/include/mlir/Dialect/SPIRV [MlirSpirvLibs]: https://github.com/llvm/llvm-project/tree/master/mlir/lib/Dialect/SPIRV [MlirSpirvTests]: https://github.com/llvm/llvm-project/tree/master/mlir/test/Dialect/SPIRV @@ -1084,3 +1189,5 @@ [GenSpirvUtilsPy]: https://github.com/llvm/llvm-project/blob/master/mlir/utils/spirv/gen_spirv_dialect.py [LlvmMlirSpirvDoc]: https://mlir.llvm.org/docs/Dialects/SPIRVOps/ [CustomTypeAttrTutorial]: https://mlir.llvm.org/docs/DefiningAttributesAndTypes/ +[VulkanSpirv]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#spirvenv +[VulkanShaderInterface]: https://renderdoc.org/vkspec_chunked/chap14.html#interfaces-resources