| //===- GPUToNVVMPipeline.cpp - Test lowering to NVVM as a sink pass -------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file implements a pass for testing the lowering to NVVM as a generally |
| // usable sink pass. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "mlir/Conversion/AffineToStandard/AffineToStandard.h" |
| #include "mlir/Conversion/ArithToLLVM/ArithToLLVM.h" |
| #include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVMPass.h" |
| #include "mlir/Conversion/GPUCommon/GPUCommonPass.h" |
| #include "mlir/Conversion/GPUToNVVM/GPUToNVVMPass.h" |
| #include "mlir/Conversion/IndexToLLVM/IndexToLLVM.h" |
| #include "mlir/Conversion/MathToLLVM/MathToLLVM.h" |
| #include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h" |
| #include "mlir/Conversion/NVGPUToNVVM/NVGPUToNVVM.h" |
| #include "mlir/Conversion/NVVMToLLVM/NVVMToLLVM.h" |
| #include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h" |
| #include "mlir/Conversion/SCFToControlFlow/SCFToControlFlow.h" |
| #include "mlir/Conversion/VectorToLLVM/ConvertVectorToLLVMPass.h" |
| #include "mlir/Conversion/VectorToSCF/VectorToSCF.h" |
| #include "mlir/Dialect/Func/IR/FuncOps.h" |
| #include "mlir/Dialect/GPU/IR/GPUDialect.h" |
| #include "mlir/Dialect/GPU/Pipelines/Passes.h" |
| #include "mlir/Dialect/GPU/Transforms/Passes.h" |
| #include "mlir/Dialect/LLVMIR/LLVMDialect.h" |
| #include "mlir/Dialect/Linalg/Passes.h" |
| #include "mlir/Dialect/MemRef/Transforms/Passes.h" |
| #include "mlir/Pass/PassManager.h" |
| #include "mlir/Pass/PassOptions.h" |
| #include "mlir/Transforms/Passes.h" |
| |
| using namespace mlir; |
| |
| #if MLIR_CUDA_CONVERSIONS_ENABLED |
| namespace { |
| |
| //===----------------------------------------------------------------------===// |
| // Common pipeline |
| //===----------------------------------------------------------------------===// |
| void buildCommonPassPipeline( |
| OpPassManager &pm, const mlir::gpu::GPUToNVVMPipelineOptions &options) { |
| pm.addPass(createConvertNVGPUToNVVMPass()); |
| pm.addPass(createGpuKernelOutliningPass()); |
| pm.addPass(createConvertVectorToSCFPass()); |
| pm.addPass(createConvertSCFToCFPass()); |
| pm.addPass(createConvertNVVMToLLVMPass()); |
| pm.addPass(createConvertFuncToLLVMPass()); |
| pm.addPass(memref::createExpandStridedMetadataPass()); |
| |
| GpuNVVMAttachTargetOptions nvvmTargetOptions; |
| nvvmTargetOptions.triple = options.cubinTriple; |
| nvvmTargetOptions.chip = options.cubinChip; |
| nvvmTargetOptions.features = options.cubinFeatures; |
| nvvmTargetOptions.optLevel = options.optLevel; |
| pm.addPass(createGpuNVVMAttachTarget(nvvmTargetOptions)); |
| pm.addPass(createLowerAffinePass()); |
| pm.addPass(createArithToLLVMConversionPass()); |
| ConvertIndexToLLVMPassOptions convertIndexToLLVMPassOpt; |
| convertIndexToLLVMPassOpt.indexBitwidth = options.indexBitWidth; |
| pm.addPass(createConvertIndexToLLVMPass(convertIndexToLLVMPassOpt)); |
| pm.addPass(createCanonicalizerPass()); |
| pm.addPass(createCSEPass()); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // GPUModule-specific stuff. |
| //===----------------------------------------------------------------------===// |
| void buildGpuPassPipeline(OpPassManager &pm, |
| const mlir::gpu::GPUToNVVMPipelineOptions &options) { |
| pm.addNestedPass<gpu::GPUModuleOp>(createStripDebugInfoPass()); |
| ConvertGpuOpsToNVVMOpsOptions opt; |
| opt.useBarePtrCallConv = options.kernelUseBarePtrCallConv; |
| opt.indexBitwidth = options.indexBitWidth; |
| pm.addNestedPass<gpu::GPUModuleOp>(createConvertGpuOpsToNVVMOps(opt)); |
| pm.addNestedPass<gpu::GPUModuleOp>(createCanonicalizerPass()); |
| pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass()); |
| pm.addNestedPass<gpu::GPUModuleOp>(createReconcileUnrealizedCastsPass()); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Host Post-GPU pipeline |
| //===----------------------------------------------------------------------===// |
| void buildHostPostPipeline(OpPassManager &pm, |
| const mlir::gpu::GPUToNVVMPipelineOptions &options) { |
| GpuToLLVMConversionPassOptions opt; |
| opt.hostBarePtrCallConv = options.hostUseBarePtrCallConv; |
| opt.kernelBarePtrCallConv = options.kernelUseBarePtrCallConv; |
| pm.addPass(createGpuToLLVMConversionPass(opt)); |
| |
| GpuModuleToBinaryPassOptions gpuModuleToBinaryPassOptions; |
| gpuModuleToBinaryPassOptions.compilationTarget = options.cubinFormat; |
| pm.addPass(createGpuModuleToBinaryPass(gpuModuleToBinaryPassOptions)); |
| pm.addPass(createConvertMathToLLVMPass()); |
| pm.addPass(createCanonicalizerPass()); |
| pm.addPass(createCSEPass()); |
| pm.addPass(createReconcileUnrealizedCastsPass()); |
| } |
| |
| } // namespace |
| |
| void mlir::gpu::buildLowerToNVVMPassPipeline( |
| OpPassManager &pm, const GPUToNVVMPipelineOptions &options) { |
| // Common pipelines |
| buildCommonPassPipeline(pm, options); |
| |
| // GPUModule-specific stuff |
| buildGpuPassPipeline(pm, options); |
| |
| // Host post-GPUModule-specific stuff |
| buildHostPostPipeline(pm, options); |
| } |
| |
| void mlir::gpu::registerGPUToNVVMPipeline() { |
| PassPipelineRegistration<GPUToNVVMPipelineOptions>( |
| "gpu-lower-to-nvvm-pipeline", |
| "The default pipeline lowers main dialects (arith, memref, scf, " |
| "vector, gpu, and nvgpu) to NVVM. It starts by lowering GPU code to the " |
| "specified compilation target (default is fatbin) then lowers the host " |
| "code.", |
| buildLowerToNVVMPassPipeline); |
| } |
| |
| #endif // MLIR_CUDA_CONVERSIONS_ENABLED |