//===- 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(createConvertMathToLLVMPass()); 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(createStripDebugInfoPass()); ConvertGpuOpsToNVVMOpsOptions opt; opt.useBarePtrCallConv = options.kernelUseBarePtrCallConv; opt.indexBitwidth = options.indexBitWidth; pm.addNestedPass(createConvertGpuOpsToNVVMOps(opt)); pm.addNestedPass(createCanonicalizerPass()); pm.addNestedPass(createCSEPass()); pm.addNestedPass(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(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( "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