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