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

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