Skip to content

Commit

Permalink
[MLIR][SPIRVToLLVM] Implementation of SPIR-V module conversion pattern
Browse files Browse the repository at this point in the history
This patch introduces conversion patterns for `spv.module` and `spv._module_end`.
SPIR-V module is converted into `ModuleOp`. This will play a role of enclosing
scope to LLVM ops. At the moment, SPIR-V module attributes (such as memory model,
etc) are ignored.

Differential Revision: https://reviews.llvm.org/D82468
  • Loading branch information
georgemitenkov authored and antiagainst committed Jun 25, 2020
1 parent e6a343e commit b5c24c2
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 0 deletions.
5 changes: 5 additions & 0 deletions mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ void populateSPIRVToLLVMFunctionConversionPatterns(
MLIRContext *context, LLVMTypeConverter &typeConverter,
OwningRewritePatternList &patterns);

/// Populates the given patterns for module conversion from SPIR-V to LLVM.
void populateSPIRVToLLVMModuleConversionPatterns(
MLIRContext *context, LLVMTypeConverter &typeConverter,
OwningRewritePatternList &patterns);

} // namespace mlir

#endif // MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVM_H
44 changes: 44 additions & 0 deletions mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,43 @@ class FuncConversionPattern : public SPIRVToLLVMConversion<spirv::FuncOp> {
return success();
}
};

//===----------------------------------------------------------------------===//
// ModuleOp conversion
//===----------------------------------------------------------------------===//

class ModuleConversionPattern : public SPIRVToLLVMConversion<spirv::ModuleOp> {
public:
using SPIRVToLLVMConversion<spirv::ModuleOp>::SPIRVToLLVMConversion;

LogicalResult
matchAndRewrite(spirv::ModuleOp spvModuleOp, ArrayRef<Value> operands,
ConversionPatternRewriter &rewriter) const override {

auto newModuleOp = rewriter.create<ModuleOp>(spvModuleOp.getLoc());
rewriter.inlineRegionBefore(spvModuleOp.body(), newModuleOp.getBody());

// Remove the terminator block that was automatically added by builder
rewriter.eraseBlock(&newModuleOp.getBodyRegion().back());
rewriter.eraseOp(spvModuleOp);
return success();
}
};

class ModuleEndConversionPattern
: public SPIRVToLLVMConversion<spirv::ModuleEndOp> {
public:
using SPIRVToLLVMConversion<spirv::ModuleEndOp>::SPIRVToLLVMConversion;

LogicalResult
matchAndRewrite(spirv::ModuleEndOp moduleEndOp, ArrayRef<Value> operands,
ConversionPatternRewriter &rewriter) const override {

rewriter.replaceOpWithNewOp<ModuleTerminatorOp>(moduleEndOp);
return success();
}
};

} // namespace

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -361,3 +398,10 @@ void mlir::populateSPIRVToLLVMFunctionConversionPatterns(
OwningRewritePatternList &patterns) {
patterns.insert<FuncConversionPattern>(context, typeConverter);
}

void mlir::populateSPIRVToLLVMModuleConversionPatterns(
MLIRContext *context, LLVMTypeConverter &typeConverter,
OwningRewritePatternList &patterns) {
patterns.insert<ModuleConversionPattern, ModuleEndConversionPattern>(
context, typeConverter);
}
6 changes: 6 additions & 0 deletions mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ void ConvertSPIRVToLLVMPass::runOnOperation() {
LLVMTypeConverter converter(&getContext());

OwningRewritePatternList patterns;
populateSPIRVToLLVMModuleConversionPatterns(context, converter, patterns);
populateSPIRVToLLVMConversionPatterns(context, converter, patterns);
populateSPIRVToLLVMFunctionConversionPatterns(context, converter, patterns);

Expand All @@ -45,6 +46,11 @@ void ConvertSPIRVToLLVMPass::runOnOperation() {
ConversionTarget target(getContext());
target.addIllegalDialect<spirv::SPIRVDialect>();
target.addLegalDialect<LLVM::LLVMDialect>();

// set `ModuleOp` and `ModuleTerminatorOp` as legal for `spv.module`
// conversion.
target.addLegalOp<ModuleOp>();
target.addLegalOp<ModuleTerminatorOp>();
if (failed(applyPartialConversion(module, target, patterns)))
signalPassFailure();
}
Expand Down
26 changes: 26 additions & 0 deletions mlir/test/Conversion/SPIRVToLLVM/module-ops-to-llvm.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// RUN: mlir-opt -convert-spirv-to-llvm %s | FileCheck %s

//===----------------------------------------------------------------------===//
// spv.module
//===----------------------------------------------------------------------===//

// CHECK: module
spv.module Logical GLSL450 {}

// CHECK: module
spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], [SPV_KHR_16bit_storage]> {}

// CHECK: module
spv.module Logical GLSL450 {
// CHECK: }
spv._module_end
}

// CHECK: module
spv.module Logical GLSL450 {
// CHECK-LABEL: llvm.func @empty()
spv.func @empty() -> () "None" {
// CHECK: llvm.return
spv.Return
}
}

0 comments on commit b5c24c2

Please sign in to comment.