1//===------------------ TestVulkanRunnerPipeline.cpp --------------------===//
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// Implements a pipeline for use by Vulkan runner tests.
10//
11//===----------------------------------------------------------------------===//
12
13#include "mlir/Conversion/GPUCommon/GPUCommonPass.h"
14#include "mlir/Conversion/GPUToSPIRV/GPUToSPIRVPass.h"
15#include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h"
16#include "mlir/Dialect/Func/IR/FuncOps.h"
17#include "mlir/Dialect/GPU/IR/GPUDialect.h"
18#include "mlir/Dialect/GPU/Transforms/Passes.h"
19#include "mlir/Dialect/LLVMIR/Transforms/RequestCWrappers.h"
20#include "mlir/Dialect/MemRef/Transforms/Passes.h"
21#include "mlir/Dialect/SPIRV/IR/SPIRVOps.h"
22#include "mlir/Dialect/SPIRV/Transforms/Passes.h"
23#include "mlir/Pass/PassManager.h"
24#include "mlir/Pass/PassOptions.h"
25
26using namespace mlir;
27
28// Defined in the test directory, no public header.
29namespace mlir::test {
30std::unique_ptr<Pass> createTestConvertToSPIRVPass(bool convertGPUModules,
31 bool nestInGPUModule);
32}
33
34namespace {
35
36struct VulkanRunnerPipelineOptions
37 : PassPipelineOptions<VulkanRunnerPipelineOptions> {
38 Option<bool> spirvWebGPUPrepare{
39 *this, "spirv-webgpu-prepare",
40 llvm::cl::desc("Run MLIR transforms used when targetting WebGPU")};
41};
42
43void buildTestVulkanRunnerPipeline(OpPassManager &passManager,
44 const VulkanRunnerPipelineOptions &options) {
45 passManager.addPass(pass: createGpuKernelOutliningPass());
46 passManager.addPass(memref::createFoldMemRefAliasOpsPass());
47
48 GpuSPIRVAttachTargetOptions attachTargetOptions{};
49 attachTargetOptions.spirvVersion = "v1.0";
50 attachTargetOptions.spirvCapabilities.push_back("Shader");
51 attachTargetOptions.spirvExtensions.push_back(
52 "SPV_KHR_storage_buffer_storage_class");
53 passManager.addPass(pass: createGpuSPIRVAttachTarget(attachTargetOptions));
54
55 passManager.addPass(pass: test::createTestConvertToSPIRVPass(
56 /*convertGPUModules=*/true, /*nestInGPUModule=*/true));
57
58 OpPassManager &spirvModulePM =
59 passManager.nest<gpu::GPUModuleOp>().nest<spirv::ModuleOp>();
60 spirvModulePM.addPass(spirv::createSPIRVLowerABIAttributesPass());
61 spirvModulePM.addPass(spirv::createSPIRVUpdateVCEPass());
62 if (options.spirvWebGPUPrepare)
63 spirvModulePM.addPass(spirv::createSPIRVWebGPUPreparePass());
64
65 passManager.addPass(pass: createGpuModuleToBinaryPass());
66
67 passManager.addPass(pass: createFinalizeMemRefToLLVMConversionPass());
68 passManager.nest<func::FuncOp>().addPass(
69 LLVM::createLLVMRequestCWrappersPass());
70 // VulkanRuntimeWrappers.cpp requires these calling convention options.
71 GpuToLLVMConversionPassOptions opt;
72 opt.hostBarePtrCallConv = false;
73 opt.kernelBarePtrCallConv = true;
74 opt.kernelIntersperseSizeCallConv = true;
75 passManager.addPass(pass: createGpuToLLVMConversionPass(opt));
76}
77
78} // namespace
79
80namespace mlir::test {
81void registerTestVulkanRunnerPipeline() {
82 PassPipelineRegistration<VulkanRunnerPipelineOptions>(
83 "test-vulkan-runner-pipeline",
84 "Runs a series of passes intended for Vulkan runner tests. Lowers GPU "
85 "dialect to LLVM dialect for the host and to serialized Vulkan SPIR-V "
86 "for the device.",
87 buildTestVulkanRunnerPipeline);
88}
89} // namespace mlir::test
90

source code of mlir/test/lib/Pass/TestVulkanRunnerPipeline.cpp