[Mlir-commits] [mlir] fda5192 - [MLIR][SPIRVToLLVM] Add skeleton for SPIR-V to LLVM dialect conversion

Lei Zhang llvmlistbot at llvm.org
Mon Jun 8 15:45:14 PDT 2020


Author: George Mitenkov
Date: 2020-06-08T18:22:42-04:00
New Revision: fda5192d4fa67e44f211b1a5dc04168670aa86ef

URL: https://github.com/llvm/llvm-project/commit/fda5192d4fa67e44f211b1a5dc04168670aa86ef
DIFF: https://github.com/llvm/llvm-project/commit/fda5192d4fa67e44f211b1a5dc04168670aa86ef.diff

LOG: [MLIR][SPIRVToLLVM] Add skeleton for SPIR-V to LLVM dialect conversion

These commits set up the skeleton for SPIR-V to LLVM dialect conversion.
I created SPIR-V to LLVM pass, registered it in Passes.td, InitAllPasses.h.
Added a pattern for `spv.BitwiseAndOp` and tests for it. Integer, float
and vector types are converted through LLVMTypeConverter.

Differential Revision: https://reviews.llvm.org/D81100

Added: 
    mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h
    mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.h
    mlir/lib/Conversion/SPIRVToLLVM/CMakeLists.txt
    mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
    mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.cpp
    mlir/test/Conversion/SPIRVToLLVM/convert-to-llvm.mlir

Modified: 
    mlir/include/mlir/Conversion/Passes.td
    mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h
    mlir/include/mlir/InitAllPasses.h
    mlir/lib/Conversion/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td
index 4bcfd8d34aa2..9b9caa46feda 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -206,6 +206,15 @@ def ConvertShapeToStandard : Pass<"convert-shape-to-std", "ModuleOp"> {
   let constructor = "mlir::createConvertShapeToStandardPass()";
 }
 
+//===----------------------------------------------------------------------===//
+// SPIRVToLLVM
+//===----------------------------------------------------------------------===//
+
+def ConvertSPIRVToLLVM : Pass<"convert-spirv-to-llvm", "ModuleOp"> {
+  let summary = "Convert SPIR-V dialect to LLVM dialect";
+  let constructor = "mlir::createConvertSPIRVToLLVMPass()";
+}
+
 //===----------------------------------------------------------------------===//
 // StandardToLLVM
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h b/mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h
new file mode 100644
index 000000000000..2bf74d65b90d
--- /dev/null
+++ b/mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h
@@ -0,0 +1,30 @@
+//===- ConvertSPIRVToLLVM.h - Convert SPIR-V to LLVM dialect ----*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Provides patterns to convert SPIR-V dialect to LLVM dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVM_H
+#define MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVM_H
+
+#include "mlir/Transforms/DialectConversion.h"
+
+namespace mlir {
+class LLVMTypeConverter;
+class MLIRContext;
+class ModuleOp;
+
+/// Populates the given list with patterns that convert from SPIR-V to LLVM.
+void populateSPIRVToLLVMConversionPatterns(MLIRContext *context,
+                                           LLVMTypeConverter &typeConverter,
+                                           OwningRewritePatternList &patterns);
+
+} // namespace mlir
+
+#endif // MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVM_H

diff  --git a/mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.h b/mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.h
new file mode 100644
index 000000000000..9cfce928ff6e
--- /dev/null
+++ b/mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.h
@@ -0,0 +1,28 @@
+//===- ConvertSPIRVToLLVMPass.h - SPIR-V dialect to LLVM pass ---*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Provides a pass to lower from SPIR-V dialect to LLVM dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVMPASS_H
+#define MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVMPASS_H
+
+#include <memory>
+
+namespace mlir {
+class ModuleOp;
+template <typename T>
+class OperationPass;
+
+/// Creates a pass to convert SPIR-V operations to the LLVMIR dialect.
+std::unique_ptr<OperationPass<ModuleOp>> createConvertSPIRVToLLVMPass();
+
+} // namespace mlir
+
+#endif // MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVMPASS_H_

diff  --git a/mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h b/mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h
index 0ef6df5c34b3..e09a74d5be83 100644
--- a/mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h
+++ b/mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h
@@ -13,7 +13,8 @@
 namespace mlir {
 class LLVMTypeConverter;
 class ModuleOp;
-template <typename T> class OperationPass;
+template <typename T>
+class OperationPass;
 
 /// Collect a set of patterns to convert from Vector contractions to LLVM Matrix
 /// Intrinsics. To lower to assembly, the LLVM flag -lower-matrix-intrinsics

diff  --git a/mlir/include/mlir/InitAllPasses.h b/mlir/include/mlir/InitAllPasses.h
index 957153770351..f1b78f929664 100644
--- a/mlir/include/mlir/InitAllPasses.h
+++ b/mlir/include/mlir/InitAllPasses.h
@@ -25,6 +25,7 @@
 #include "mlir/Conversion/LinalgToStandard/LinalgToStandard.h"
 #include "mlir/Conversion/SCFToGPU/SCFToGPUPass.h"
 #include "mlir/Conversion/SCFToStandard/SCFToStandard.h"
+#include "mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.h"
 #include "mlir/Conversion/ShapeToStandard/ShapeToStandard.h"
 #include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h"
 #include "mlir/Conversion/StandardToSPIRV/ConvertStandardToSPIRVPass.h"

diff  --git a/mlir/lib/Conversion/CMakeLists.txt b/mlir/lib/Conversion/CMakeLists.txt
index c99dceec31cc..e60a1dfc0e32 100644
--- a/mlir/lib/Conversion/CMakeLists.txt
+++ b/mlir/lib/Conversion/CMakeLists.txt
@@ -11,6 +11,7 @@ add_subdirectory(LinalgToStandard)
 add_subdirectory(SCFToGPU)
 add_subdirectory(SCFToStandard)
 add_subdirectory(ShapeToStandard)
+add_subdirectory(SPIRVToLLVM)
 add_subdirectory(StandardToLLVM)
 add_subdirectory(StandardToSPIRV)
 add_subdirectory(VectorToLLVM)

diff  --git a/mlir/lib/Conversion/SPIRVToLLVM/CMakeLists.txt b/mlir/lib/Conversion/SPIRVToLLVM/CMakeLists.txt
new file mode 100644
index 000000000000..adf835c25a23
--- /dev/null
+++ b/mlir/lib/Conversion/SPIRVToLLVM/CMakeLists.txt
@@ -0,0 +1,18 @@
+add_mlir_conversion_library(MLIRSPIRVToLLVM
+  ConvertSPIRVToLLVM.cpp
+  ConvertSPIRVToLLVMPass.cpp
+
+  ADDITIONAL_HEADER_DIRS
+  ${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/SPIRVToLLVM
+
+  DEPENDS
+  MLIRConversionPassIncGen
+  intrinsics_gen
+
+  LINK_LIBS PUBLIC
+  MLIRSPIRV
+  MLIRLLVMIR
+  MLIRStandardToLLVM
+  MLIRIR
+  MLIRTransforms
+  )

diff  --git a/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp b/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
new file mode 100644
index 000000000000..2ccd2431ac6e
--- /dev/null
+++ b/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
@@ -0,0 +1,53 @@
+//===- ConvertSPIRVToLLVM.cpp - SPIR-V dialect to LLVM dialect conversion -===//
+//
+// 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 patterns to convert SPIR-V dialect to LLVM dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h"
+#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h"
+#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Dialect/SPIRV/SPIRVDialect.h"
+#include "mlir/Dialect/SPIRV/SPIRVOps.h"
+#include "mlir/Dialect/StandardOps/IR/Ops.h"
+#include "mlir/IR/Module.h"
+#include "mlir/IR/PatternMatch.h"
+#include "mlir/Support/LogicalResult.h"
+#include "mlir/Transforms/DialectConversion.h"
+
+using namespace mlir;
+
+namespace {
+
+class BitwiseAndOpConversion : public ConvertToLLVMPattern {
+public:
+  explicit BitwiseAndOpConversion(MLIRContext *context,
+                                  LLVMTypeConverter &typeConverter)
+      : ConvertToLLVMPattern(spirv::BitwiseAndOp::getOperationName(), context,
+                             typeConverter) {}
+
+  LogicalResult
+  matchAndRewrite(Operation *op, ArrayRef<Value> operands,
+                  ConversionPatternRewriter &rewriter) const override {
+    auto bitwiseAndOp = cast<spirv::BitwiseAndOp>(op);
+    auto dstType = typeConverter.convertType(bitwiseAndOp.getType());
+    if (!dstType)
+      return failure();
+    rewriter.replaceOpWithNewOp<LLVM::AndOp>(bitwiseAndOp, dstType, operands);
+    return success();
+  }
+};
+} // namespace
+
+void mlir::populateSPIRVToLLVMConversionPatterns(
+    MLIRContext *context, LLVMTypeConverter &typeConverter,
+    OwningRewritePatternList &patterns) {
+  patterns.insert<BitwiseAndOpConversion>(context, typeConverter);
+}

diff  --git a/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.cpp b/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.cpp
new file mode 100644
index 000000000000..c8e2d731c581
--- /dev/null
+++ b/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.cpp
@@ -0,0 +1,54 @@
+//===- ConvertSPIRVToLLVMPass.cpp - Convert SPIR-V ops to LLVM ops --------===//
+//
+// 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 to convert MLIR SPIR-V ops into LLVM ops
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.h"
+#include "../PassDetail.h"
+#include "mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h"
+#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h"
+#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Dialect/SPIRV/SPIRVDialect.h"
+
+using namespace mlir;
+
+namespace {
+/// A pass converting MLIR SPIR-V operations into LLVM dialect.
+class ConvertSPIRVToLLVMPass
+    : public ConvertSPIRVToLLVMBase<ConvertSPIRVToLLVMPass> {
+  void runOnOperation() override;
+};
+} // namespace
+
+void ConvertSPIRVToLLVMPass::runOnOperation() {
+  MLIRContext *context = &getContext();
+  ModuleOp module = getOperation();
+  LLVMTypeConverter converter(&getContext());
+
+  OwningRewritePatternList patterns;
+  populateSPIRVToLLVMConversionPatterns(context, converter, patterns);
+
+  // Currently pulls in Std to LLVM conversion patterns
+  // that help with testing. This allows to convert
+  // function arguments to LLVM.
+  populateStdToLLVMConversionPatterns(converter, patterns);
+
+  ConversionTarget target(getContext());
+  target.addIllegalDialect<spirv::SPIRVDialect>();
+  target.addLegalDialect<LLVM::LLVMDialect>();
+
+  if (failed(applyPartialConversion(module, target, patterns, &converter)))
+    signalPassFailure();
+}
+
+std::unique_ptr<OperationPass<ModuleOp>> mlir::createConvertSPIRVToLLVMPass() {
+  return std::make_unique<ConvertSPIRVToLLVMPass>();
+}

diff  --git a/mlir/test/Conversion/SPIRVToLLVM/convert-to-llvm.mlir b/mlir/test/Conversion/SPIRVToLLVM/convert-to-llvm.mlir
new file mode 100644
index 000000000000..326ef3a18854
--- /dev/null
+++ b/mlir/test/Conversion/SPIRVToLLVM/convert-to-llvm.mlir
@@ -0,0 +1,13 @@
+// RUN: mlir-opt -convert-spirv-to-llvm %s | FileCheck %s
+
+func @bitwise_and_scalar(%arg0: i32, %arg1: i32) {
+	// CHECK: %{{.*}} = llvm.and %{{.*}}, %{{.*}} : !llvm.i32
+	%0 = spv.BitwiseAnd %arg0, %arg1 : i32
+	return
+}
+
+func @bitwise_and_vector(%arg0: vector<4xi64>, %arg1: vector<4xi64>) {
+	// CHECK: %{{.*}} = llvm.and %{{.*}}, %{{.*}} : !llvm<"<4 x i64>">
+	%0 = spv.BitwiseAnd %arg0, %arg1 : vector<4xi64>
+	return
+}


        


More information about the Mlir-commits mailing list