diff --git a/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRV.cpp b/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRV.cpp --- a/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRV.cpp +++ b/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRV.cpp @@ -13,12 +13,12 @@ #include "mlir/Conversion/GPUToSPIRV/GPUToSPIRV.h" #include "mlir/Dialect/GPU/GPUDialect.h" #include "mlir/Dialect/SPIRV/IR/SPIRVDialect.h" +#include "mlir/Dialect/SPIRV/IR/SPIRVEnums.h" #include "mlir/Dialect/SPIRV/IR/SPIRVOps.h" #include "mlir/Dialect/SPIRV/IR/TargetAndABI.h" #include "mlir/Dialect/SPIRV/Transforms/SPIRVConversion.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/Transforms/DialectConversion.h" -#include "llvm/ADT/StringSwitch.h" using namespace mlir; @@ -109,6 +109,16 @@ ConversionPatternRewriter &rewriter) const override; }; +/// Pattern to convert a gpu.barrier op into a spv.ControlBarrier op. +class GPUBarrierConversion final : public OpConversionPattern { +public: + using OpConversionPattern::OpConversionPattern; + + LogicalResult + matchAndRewrite(gpu::BarrierOp barrierOp, OpAdaptor adaptor, + ConversionPatternRewriter &rewriter) const override; +}; + } // namespace //===----------------------------------------------------------------------===// @@ -326,6 +336,25 @@ return success(); } +//===----------------------------------------------------------------------===// +// Barrier. +//===----------------------------------------------------------------------===// + +LogicalResult GPUBarrierConversion::matchAndRewrite( + gpu::BarrierOp barrierOp, OpAdaptor adaptor, + ConversionPatternRewriter &rewriter) const { + MLIRContext *context = getContext(); + // Both execution and memory scope should be workgroup. + auto scope = spirv::ScopeAttr::get(context, spirv::Scope::Workgroup); + // Require acquire and release memory semantics for workgroup memory. + auto memorySemantics = spirv::MemorySemanticsAttr::get( + context, spirv::MemorySemantics::WorkgroupMemory | + spirv::MemorySemantics::AcquireRelease); + rewriter.replaceOpWithNewOp(barrierOp, scope, scope, + memorySemantics); + return success(); +} + //===----------------------------------------------------------------------===// // GPU To SPIRV Patterns. //===----------------------------------------------------------------------===// @@ -333,8 +362,8 @@ void mlir::populateGPUToSPIRVPatterns(SPIRVTypeConverter &typeConverter, RewritePatternSet &patterns) { patterns.add< - GPUFuncOpConversion, GPUModuleConversion, GPUModuleEndConversion, - GPUReturnOpConversion, + GPUBarrierConversion, GPUFuncOpConversion, GPUModuleConversion, + GPUModuleEndConversion, GPUReturnOpConversion, LaunchConfigConversion, LaunchConfigConversion, LaunchConfigConversion) kernel + attributes {spv.entry_point_abi = {local_size = dense<[32, 4, 1]>: vector<3xi32>}} { + // CHECK: spv.ControlBarrier Workgroup, Workgroup, "AcquireRelease|WorkgroupMemory" + gpu.barrier + gpu.return + } + } + + func @main() { + %0 = "op"() : () -> (f32) + %1 = "op"() : () -> (memref<12xf32>) + %cst = arith.constant 1 : index + gpu.launch_func @kernels::@barrier + blocks in (%cst, %cst, %cst) threads in (%cst, %cst, %cst) + args(%0 : f32, %1 : memref<12xf32>) + return + } +}