1//===-- Passes.td - Conversion pass definition file --------*- tablegen -*-===// 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#ifndef MLIR_CONVERSION_PASSES 10#define MLIR_CONVERSION_PASSES 11 12include "mlir/Pass/PassBase.td" 13 14//===----------------------------------------------------------------------===// 15// AffineToStandard 16//===----------------------------------------------------------------------===// 17 18def ConvertAffineToStandard : Pass<"lower-affine"> { 19 let summary = "Lower Affine operations to a combination of Standard and SCF " 20 "operations"; 21 let description = [{ 22 23 Convert operations from the affine dialect into operations from the SCF and 24 standard dialects. 25 26 `affine.for` operations are converted to `scf.for` operations that are free 27 of certain structural restrictions (on their bounds and step). `affine.if` 28 is similarly converted to the `scf.if` operation. `affine.apply` operations 29 are converted into sequences of primitive arithmetic operations from the 30 standard dialect that have the same effect, using operands of the `index` 31 type. Consequently, named maps and sets thare are no longer in use may be 32 removed from the module. 33 34 For example, `%r = affine.apply affine_map<(d0, d1)[s0] -> (d0 + 2*d1 + 35 s0)>(%d0, %d1)[%s0]` 36 can be converted into: 37 38 ```mlir 39 %d0 = <...> 40 %d1 = <...> 41 %s0 = <...> 42 %0 = constant 2 : index 43 %1 = muli %0, %d1 44 %2 = addi %d0, %1 45 %r = addi %2, %s0 46 ``` 47 48 #### Input invariant 49 50 - no `Tensor` types; 51 52 These restrictions may be lifted in the future. 53 54 #### Output IR 55 56 Functions with `affine.for` and `affine.if` operations eliminated. These 57 functions may contain operations from the Standard dialect in addition to 58 those already present before the pass. 59 60 #### Invariants 61 62 - Functions without a body are not modified. 63 - The semantics of the other functions is preserved. 64 - Individual operations other than those mentioned above are not modified 65 if they do not depend on the loop iterator value or on the result of 66 `affine.apply`. 67 }]; 68 let constructor = "mlir::createLowerAffinePass()"; 69 let dependentDialects = [ 70 "scf::SCFDialect", 71 "StandardOpsDialect", 72 "vector::VectorDialect" 73 ]; 74} 75 76//===----------------------------------------------------------------------===// 77// AsyncToLLVM 78//===----------------------------------------------------------------------===// 79 80def ConvertAsyncToLLVM : Pass<"convert-async-to-llvm", "ModuleOp"> { 81 let summary = "Convert the operations from the async dialect into the LLVM " 82 "dialect"; 83 let description = [{ 84 Convert `async.execute` operations to LLVM coroutines and use async runtime 85 API to execute them. 86 }]; 87 let constructor = "mlir::createConvertAsyncToLLVMPass()"; 88 let dependentDialects = ["LLVM::LLVMDialect"]; 89} 90 91//===----------------------------------------------------------------------===// 92// GPUCommon 93//===----------------------------------------------------------------------===// 94 95def GpuToLLVMConversionPass : Pass<"gpu-to-llvm", "ModuleOp"> { 96 let summary = "Convert GPU dialect to LLVM dialect with GPU runtime calls"; 97 let constructor = "mlir::createGpuToLLVMConversionPass()"; 98 let dependentDialects = ["LLVM::LLVMDialect"]; 99 let options = [ 100 Option<"gpuBinaryAnnotation", "gpu-binary-annotation", "std::string", 101 "", "Annotation attribute string for GPU binary">, 102 ]; 103} 104 105def LowerHostCodeToLLVM : Pass<"lower-host-to-llvm", "ModuleOp"> { 106 let summary = "Lowers the host module code and `gpu.launch_func` to LLVM"; 107 let constructor = "mlir::createLowerHostCodeToLLVMPass()"; 108 let dependentDialects = ["LLVM::LLVMDialect"]; 109} 110 111//===----------------------------------------------------------------------===// 112// GPUToNVVM 113//===----------------------------------------------------------------------===// 114 115def ConvertGpuOpsToNVVMOps : Pass<"convert-gpu-to-nvvm", "gpu::GPUModuleOp"> { 116 let summary = "Generate NVVM operations for gpu operations"; 117 let constructor = "mlir::createLowerGpuOpsToNVVMOpsPass()"; 118 let dependentDialects = ["NVVM::NVVMDialect"]; 119 let options = [ 120 Option<"indexBitwidth", "index-bitwidth", "unsigned", 121 /*default=kDeriveIndexBitwidthFromDataLayout*/"0", 122 "Bitwidth of the index type, 0 to use size of machine word"> 123 ]; 124} 125 126//===----------------------------------------------------------------------===// 127// GPUToROCDL 128//===----------------------------------------------------------------------===// 129 130def ConvertGpuOpsToROCDLOps : Pass<"convert-gpu-to-rocdl", "gpu::GPUModuleOp"> { 131 let summary = "Generate ROCDL operations for gpu operations"; 132 let constructor = "mlir::createLowerGpuOpsToROCDLOpsPass()"; 133 let dependentDialects = ["ROCDL::ROCDLDialect"]; 134 let options = [ 135 Option<"indexBitwidth", "index-bitwidth", "unsigned", 136 /*default=kDeriveIndexBitwidthFromDataLayout*/"0", 137 "Bitwidth of the index type, 0 to use size of machine word"> 138 ]; 139} 140 141//===----------------------------------------------------------------------===// 142// GPUToSPIRV 143//===----------------------------------------------------------------------===// 144 145def ConvertGPUToSPIRV : Pass<"convert-gpu-to-spirv", "ModuleOp"> { 146 let summary = "Convert GPU dialect to SPIR-V dialect"; 147 let constructor = "mlir::createConvertGPUToSPIRVPass()"; 148 let dependentDialects = ["spirv::SPIRVDialect"]; 149} 150 151//===----------------------------------------------------------------------===// 152// GPUToVulkan 153//===----------------------------------------------------------------------===// 154 155def ConvertGpuLaunchFuncToVulkanLaunchFunc 156 : Pass<"convert-gpu-launch-to-vulkan-launch", "ModuleOp"> { 157 let summary = "Convert gpu.launch_func to vulkanLaunch external call"; 158 let constructor = "mlir::createConvertGpuLaunchFuncToVulkanLaunchFuncPass()"; 159 let dependentDialects = ["spirv::SPIRVDialect"]; 160} 161 162def ConvertVulkanLaunchFuncToVulkanCalls 163 : Pass<"launch-func-to-vulkan", "ModuleOp"> { 164 let summary = "Convert vulkanLaunch external call to Vulkan runtime external " 165 "calls"; 166 let constructor = "mlir::createConvertVulkanLaunchFuncToVulkanCallsPass()"; 167 let dependentDialects = ["LLVM::LLVMDialect"]; 168} 169 170//===----------------------------------------------------------------------===// 171// LinalgToLLVM 172//===----------------------------------------------------------------------===// 173 174def ConvertLinalgToLLVM : Pass<"convert-linalg-to-llvm", "ModuleOp"> { 175 let summary = "Convert the operations from the linalg dialect into the LLVM " 176 "dialect"; 177 let constructor = "mlir::createConvertLinalgToLLVMPass()"; 178 let dependentDialects = ["scf::SCFDialect", "LLVM::LLVMDialect"]; 179} 180 181//===----------------------------------------------------------------------===// 182// LinalgToStandard 183//===----------------------------------------------------------------------===// 184 185def ConvertLinalgToStandard : Pass<"convert-linalg-to-std", "ModuleOp"> { 186 let summary = "Convert the operations from the linalg dialect into the " 187 "Standard dialect"; 188 let constructor = "mlir::createConvertLinalgToStandardPass()"; 189 let dependentDialects = ["StandardOpsDialect"]; 190} 191 192//===----------------------------------------------------------------------===// 193// LinalgToSPIRV 194//===----------------------------------------------------------------------===// 195 196def ConvertLinalgToSPIRV : Pass<"convert-linalg-to-spirv", "ModuleOp"> { 197 let summary = "Convert Linalg ops to SPIR-V ops"; 198 let constructor = "mlir::createLinalgToSPIRVPass()"; 199 let dependentDialects = ["spirv::SPIRVDialect"]; 200} 201 202//===----------------------------------------------------------------------===// 203// OpenMPToLLVM 204//===----------------------------------------------------------------------===// 205 206def ConvertOpenMPToLLVM : Pass<"convert-openmp-to-llvm", "ModuleOp"> { 207 let summary = "Convert the OpenMP ops to OpenMP ops with LLVM dialect"; 208 let constructor = "mlir::createConvertOpenMPToLLVMPass()"; 209 let dependentDialects = ["LLVM::LLVMDialect"]; 210} 211 212//===----------------------------------------------------------------------===// 213// PDLToPDLInterp 214//===----------------------------------------------------------------------===// 215 216def ConvertPDLToPDLInterp : Pass<"convert-pdl-to-pdl-interp", "ModuleOp"> { 217 let summary = "Convert PDL ops to PDL interpreter ops"; 218 let constructor = "mlir::createPDLToPDLInterpPass()"; 219 let dependentDialects = ["pdl_interp::PDLInterpDialect"]; 220} 221 222//===----------------------------------------------------------------------===// 223// SCFToOpenMP 224//===----------------------------------------------------------------------===// 225 226def ConvertSCFToOpenMP : FunctionPass<"convert-scf-to-openmp"> { 227 let summary = "Convert SCF parallel loop to OpenMP parallel + workshare " 228 "constructs."; 229 let constructor = "mlir::createConvertSCFToOpenMPPass()"; 230 let dependentDialects = ["omp::OpenMPDialect"]; 231} 232 233//===----------------------------------------------------------------------===// 234// SCFToStandard 235//===----------------------------------------------------------------------===// 236 237def SCFToStandard : Pass<"convert-scf-to-std"> { 238 let summary = "Convert SCF dialect to Standard dialect, replacing structured" 239 " control flow with a CFG"; 240 let constructor = "mlir::createLowerToCFGPass()"; 241 let dependentDialects = ["StandardOpsDialect"]; 242} 243 244//===----------------------------------------------------------------------===// 245// SCFToGPU 246//===----------------------------------------------------------------------===// 247 248def ConvertAffineForToGPU : FunctionPass<"convert-affine-for-to-gpu"> { 249 let summary = "Convert top-level AffineFor Ops to GPU kernels"; 250 let constructor = "mlir::createAffineForToGPUPass()"; 251 let dependentDialects = ["gpu::GPUDialect"]; 252 let options = [ 253 Option<"numBlockDims", "gpu-block-dims", "unsigned", /*default=*/"1u", 254 "Number of GPU block dimensions for mapping">, 255 Option<"numThreadDims", "gpu-thread-dims", "unsigned", /*default=*/"1u", 256 "Number of GPU thread dimensions for mapping"> 257 ]; 258} 259 260def ConvertParallelLoopToGpu : Pass<"convert-parallel-loops-to-gpu"> { 261 let summary = "Convert mapped scf.parallel ops to gpu launch operations"; 262 let constructor = "mlir::createParallelLoopToGpuPass()"; 263 let dependentDialects = ["AffineDialect", "gpu::GPUDialect"]; 264} 265 266//===----------------------------------------------------------------------===// 267// ShapeToStandard 268//===----------------------------------------------------------------------===// 269 270def ConvertShapeToStandard : Pass<"convert-shape-to-std", "ModuleOp"> { 271 let summary = "Convert operations from the shape dialect into the standard " 272 "dialect"; 273 let constructor = "mlir::createConvertShapeToStandardPass()"; 274 let dependentDialects = ["StandardOpsDialect", "scf::SCFDialect"]; 275} 276 277def ConvertShapeConstraints: Pass<"convert-shape-constraints", "FuncOp"> { 278 let summary = "Convert shape constraint operations to the standard dialect"; 279 let description = [{ 280 This pass eliminates shape constraints from the program, converting them to 281 eager (side-effecting) error handling code. 282 283 This pass is separate from the regular convert-shape-to-standard, despite 284 converting between the same dialects, because converting shape constraints 285 can happen at a different part of the program than general shape 286 computation lowering. 287 }]; 288 let constructor = "mlir::createConvertShapeConstraintsPass()"; 289 let dependentDialects = ["StandardOpsDialect", "scf::SCFDialect"]; 290} 291 292//===----------------------------------------------------------------------===// 293// SPIRVToLLVM 294//===----------------------------------------------------------------------===// 295 296def ConvertSPIRVToLLVM : Pass<"convert-spirv-to-llvm", "ModuleOp"> { 297 let summary = "Convert SPIR-V dialect to LLVM dialect"; 298 let constructor = "mlir::createConvertSPIRVToLLVMPass()"; 299 let dependentDialects = ["LLVM::LLVMDialect"]; 300} 301 302//===----------------------------------------------------------------------===// 303// StandardToLLVM 304//===----------------------------------------------------------------------===// 305 306def ConvertStandardToLLVM : Pass<"convert-std-to-llvm", "ModuleOp"> { 307 let summary = "Convert scalar and vector operations from the Standard to the " 308 "LLVM dialect"; 309 let description = [{ 310 Convert standard operations into the LLVM IR dialect operations. 311 312 #### Input invariant 313 314 - operations including: arithmetic on integers and floats, constants, 315 direct calls, returns and branches; 316 - no `tensor` types; 317 - all `vector` are one-dimensional; 318 - all blocks are reachable by following the successors of the first basic 319 block; 320 321 If other operations are present and their results are required by the LLVM 322 IR dialect operations, the pass will fail. Any LLVM IR operations or types 323 already present in the IR will be kept as is. 324 325 #### Output IR 326 327 Functions converted to LLVM IR. Function arguments types are converted 328 one-to-one. Function results are converted one-to-one and, in case more than 329 1 value is returned, packed into an LLVM IR struct type. Function calls and 330 returns are updated accordingly. Block argument types are updated to use 331 LLVM IR types. 332 }]; 333 let constructor = "mlir::createLowerToLLVMPass()"; 334 let dependentDialects = ["LLVM::LLVMDialect"]; 335 let options = [ 336 Option<"useAlignedAlloc", "use-aligned-alloc", "bool", /*default=*/"false", 337 "Use aligned_alloc in place of malloc for heap allocations">, 338 Option<"useBarePtrCallConv", "use-bare-ptr-memref-call-conv", "bool", 339 /*default=*/"false", 340 "Replace FuncOp's MemRef arguments with bare pointers to the MemRef " 341 "element types">, 342 Option<"emitCWrappers", "emit-c-wrappers", "bool", /*default=*/"false", 343 "Emit wrappers for C-compatible pointer-to-struct memref " 344 "descriptors">, 345 Option<"indexBitwidth", "index-bitwidth", "unsigned", 346 /*default=kDeriveIndexBitwidthFromDataLayout*/"0", 347 "Bitwidth of the index type, 0 to use size of machine word">, 348 Option<"dataLayout", "data-layout", "std::string", 349 /*default=*/"\"\"", 350 "String description (LLVM format) of the data layout that is " 351 "expected on the produced module"> 352 ]; 353} 354 355//===----------------------------------------------------------------------===// 356// StandardToSPIRV 357//===----------------------------------------------------------------------===// 358 359def LegalizeStandardForSPIRV : Pass<"legalize-std-for-spirv"> { 360 let summary = "Legalize standard ops for SPIR-V lowering"; 361 let constructor = "mlir::createLegalizeStdOpsForSPIRVLoweringPass()"; 362 let dependentDialects = ["spirv::SPIRVDialect"]; 363} 364 365def ConvertStandardToSPIRV : Pass<"convert-std-to-spirv", "ModuleOp"> { 366 let summary = "Convert Standard Ops to SPIR-V dialect"; 367 let constructor = "mlir::createConvertStandardToSPIRVPass()"; 368 let dependentDialects = ["spirv::SPIRVDialect"]; 369} 370 371//===----------------------------------------------------------------------===// 372// VectorToSCF 373//===----------------------------------------------------------------------===// 374 375def ConvertVectorToSCF : FunctionPass<"convert-vector-to-scf"> { 376 let summary = "Lower the operations from the vector dialect into the SCF " 377 "dialect"; 378 let constructor = "mlir::createConvertVectorToSCFPass()"; 379 let dependentDialects = ["AffineDialect", "scf::SCFDialect"]; 380 let options = [ 381 Option<"fullUnroll", "full-unroll", "bool", /*default=*/"false", 382 "Perform full unrolling when converting vector transfers to SCF">, 383 ]; 384} 385 386//===----------------------------------------------------------------------===// 387// VectorToLLVM 388//===----------------------------------------------------------------------===// 389 390def ConvertVectorToLLVM : Pass<"convert-vector-to-llvm", "ModuleOp"> { 391 let summary = "Lower the operations from the vector dialect into the LLVM " 392 "dialect"; 393 let description = [{ 394 395 Convert operations from the vector dialect into the LLVM IR dialect 396 operations. The lowering pass provides several options to control 397 the kinds of optimizations that are allowed. It also provides options 398 that enable the use of one or more architectural-specific dialects 399 (AVX512, Neon, SVE, etc.) in combination with the architectural-neutral 400 vector dialect lowering. 401 402 }]; 403 let constructor = "mlir::createConvertVectorToLLVMPass()"; 404 let dependentDialects = ["LLVM::LLVMDialect", "LLVM::LLVMAVX512Dialect"]; 405 let options = [ 406 Option<"reassociateFPReductions", "reassociate-fp-reductions", 407 "bool", /*default=*/"false", 408 "Allows llvm to reassociate floating-point reductions for speed">, 409 Option<"enableIndexOptimizations", "enable-index-optimizations", 410 "bool", /*default=*/"true", 411 "Allows compiler to assume indices fit in 32-bit if that yields " 412 "faster code">, 413 Option<"enableAVX512", "enable-avx512", 414 "bool", /*default=*/"false", 415 "Enables the use of AVX512 dialect while lowering the vector " 416 "dialect."> 417 ]; 418} 419 420//===----------------------------------------------------------------------===// 421// VectorToROCDL 422//===----------------------------------------------------------------------===// 423 424def ConvertVectorToROCDL : Pass<"convert-vector-to-rocdl", "ModuleOp"> { 425 let summary = "Lower the operations from the vector dialect into the ROCDL " 426 "dialect"; 427 let constructor = "mlir::createConvertVectorToROCDLPass()"; 428 let dependentDialects = ["ROCDL::ROCDLDialect"]; 429} 430 431//===----------------------------------------------------------------------===// 432// VectorToSPIRV 433//===----------------------------------------------------------------------===// 434 435def ConvertVectorToSPIRV : Pass<"convert-vector-to-spirv", "ModuleOp"> { 436 let summary = "Lower the operations from the vector dialect into the SPIR-V " 437 "dialect"; 438 let constructor = "mlir::createConvertVectorToSPIRVPass()"; 439 let dependentDialects = ["spirv::SPIRVDialect"]; 440} 441 442#endif // MLIR_CONVERSION_PASSES 443