1//===- GPUToNVVMPipeline.cpp - Test lowering to NVVM as a sink pass -------===//
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// This file implements a pass for testing the lowering to NVVM as a generally
10// usable sink pass.
11//
12//===----------------------------------------------------------------------===//
13
14#include "mlir/Conversion/AffineToStandard/AffineToStandard.h"
15#include "mlir/Conversion/ArithToLLVM/ArithToLLVM.h"
16#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVMPass.h"
17#include "mlir/Conversion/GPUCommon/GPUCommonPass.h"
18#include "mlir/Conversion/GPUToNVVM/GPUToNVVMPass.h"
19#include "mlir/Conversion/IndexToLLVM/IndexToLLVM.h"
20#include "mlir/Conversion/MathToLLVM/MathToLLVM.h"
21#include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h"
22#include "mlir/Conversion/NVGPUToNVVM/NVGPUToNVVM.h"
23#include "mlir/Conversion/NVVMToLLVM/NVVMToLLVM.h"
24#include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h"
25#include "mlir/Conversion/SCFToControlFlow/SCFToControlFlow.h"
26#include "mlir/Conversion/VectorToLLVM/ConvertVectorToLLVMPass.h"
27#include "mlir/Conversion/VectorToSCF/VectorToSCF.h"
28#include "mlir/Dialect/Func/IR/FuncOps.h"
29#include "mlir/Dialect/GPU/IR/GPUDialect.h"
30#include "mlir/Dialect/GPU/Pipelines/Passes.h"
31#include "mlir/Dialect/GPU/Transforms/Passes.h"
32#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
33#include "mlir/Dialect/Linalg/Passes.h"
34#include "mlir/Dialect/MemRef/Transforms/Passes.h"
35#include "mlir/Pass/PassManager.h"
36#include "mlir/Pass/PassOptions.h"
37#include "mlir/Transforms/Passes.h"
38
39using namespace mlir;
40
41namespace {
42
43//===----------------------------------------------------------------------===//
44// Common pipeline
45//===----------------------------------------------------------------------===//
46void buildCommonPassPipeline(
47 OpPassManager &pm, const mlir::gpu::GPUToNVVMPipelineOptions &options) {
48 pm.addPass(pass: createConvertNVGPUToNVVMPass());
49 pm.addPass(pass: createGpuKernelOutliningPass());
50 pm.addPass(createConvertVectorToSCFPass());
51 pm.addPass(pass: createSCFToControlFlowPass());
52 pm.addPass(pass: createConvertNVVMToLLVMPass());
53 pm.addPass(pass: createConvertFuncToLLVMPass());
54 pm.addPass(memref::createExpandStridedMetadataPass());
55
56 GpuNVVMAttachTargetOptions nvvmTargetOptions;
57 nvvmTargetOptions.triple = options.cubinTriple;
58 nvvmTargetOptions.chip = options.cubinChip;
59 nvvmTargetOptions.features = options.cubinFeatures;
60 nvvmTargetOptions.optLevel = options.optLevel;
61 nvvmTargetOptions.cmdOptions = options.cmdOptions;
62 pm.addPass(pass: createGpuNVVMAttachTarget(nvvmTargetOptions));
63 pm.addPass(pass: createLowerAffinePass());
64 pm.addPass(pass: createArithToLLVMConversionPass());
65 ConvertIndexToLLVMPassOptions convertIndexToLLVMPassOpt;
66 convertIndexToLLVMPassOpt.indexBitwidth = options.indexBitWidth;
67 pm.addPass(pass: createConvertIndexToLLVMPass(convertIndexToLLVMPassOpt));
68 pm.addPass(pass: createCanonicalizerPass());
69 pm.addPass(pass: createCSEPass());
70}
71
72//===----------------------------------------------------------------------===//
73// GPUModule-specific stuff.
74//===----------------------------------------------------------------------===//
75void buildGpuPassPipeline(OpPassManager &pm,
76 const mlir::gpu::GPUToNVVMPipelineOptions &options) {
77 ConvertGpuOpsToNVVMOpsOptions opt;
78 opt.useBarePtrCallConv = options.kernelUseBarePtrCallConv;
79 opt.indexBitwidth = options.indexBitWidth;
80 pm.addNestedPass<gpu::GPUModuleOp>(createConvertGpuOpsToNVVMOps(opt));
81 pm.addNestedPass<gpu::GPUModuleOp>(pass: createCanonicalizerPass());
82 pm.addNestedPass<gpu::GPUModuleOp>(pass: createCSEPass());
83 pm.addNestedPass<gpu::GPUModuleOp>(createReconcileUnrealizedCastsPass());
84}
85
86//===----------------------------------------------------------------------===//
87// Host Post-GPU pipeline
88//===----------------------------------------------------------------------===//
89void buildHostPostPipeline(OpPassManager &pm,
90 const mlir::gpu::GPUToNVVMPipelineOptions &options) {
91 GpuToLLVMConversionPassOptions opt;
92 opt.hostBarePtrCallConv = options.hostUseBarePtrCallConv;
93 opt.kernelBarePtrCallConv = options.kernelUseBarePtrCallConv;
94 pm.addPass(pass: createGpuToLLVMConversionPass(opt));
95
96 GpuModuleToBinaryPassOptions gpuModuleToBinaryPassOptions;
97 gpuModuleToBinaryPassOptions.compilationTarget = options.cubinFormat;
98 pm.addPass(pass: createGpuModuleToBinaryPass(gpuModuleToBinaryPassOptions));
99 pm.addPass(pass: createConvertMathToLLVMPass());
100 pm.addPass(pass: createCanonicalizerPass());
101 pm.addPass(pass: createCSEPass());
102 pm.addPass(pass: createReconcileUnrealizedCastsPass());
103}
104
105} // namespace
106
107void mlir::gpu::buildLowerToNVVMPassPipeline(
108 OpPassManager &pm, const GPUToNVVMPipelineOptions &options) {
109 // Common pipelines
110 buildCommonPassPipeline(pm, options);
111
112 // GPUModule-specific stuff
113 buildGpuPassPipeline(pm, options);
114
115 // Host post-GPUModule-specific stuff
116 buildHostPostPipeline(pm, options);
117}
118
119void mlir::gpu::registerGPUToNVVMPipeline() {
120 PassPipelineRegistration<GPUToNVVMPipelineOptions>(
121 "gpu-lower-to-nvvm-pipeline",
122 "The default pipeline lowers main dialects (arith, memref, scf, "
123 "vector, gpu, and nvgpu) to NVVM. It starts by lowering GPU code to the "
124 "specified compilation target (default is fatbin) then lowers the host "
125 "code.",
126 buildLowerToNVVMPassPipeline);
127}
128

source code of mlir/lib/Dialect/GPU/Pipelines/GPUToNVVMPipeline.cpp