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