[Mlir-commits] [mlir] 2ad7e1a - [MLIR][SPIRVToLLVM] Conversion for global and addressof
George Mitenkov
llvmlistbot at llvm.org
Tue Aug 11 23:45:23 PDT 2020
Author: George Mitenkov
Date: 2020-08-12T09:41:14+03:00
New Revision: 2ad7e1a301f8af7412208da3ed8049ae08b0fae8
URL: https://github.com/llvm/llvm-project/commit/2ad7e1a301f8af7412208da3ed8049ae08b0fae8
DIFF: https://github.com/llvm/llvm-project/commit/2ad7e1a301f8af7412208da3ed8049ae08b0fae8.diff
LOG: [MLIR][SPIRVToLLVM] Conversion for global and addressof
Inital conversion of `spv._address_of` and `spv.globalVariable`.
In SPIR-V, the global returns a pointer, whereas in LLVM dialect
the global holds an actual value. This difference is handled by
`spv._address_of` and `llvm.mlir.addressof`ops that both return
a pointer. Moreover, only current invocation is in conversion's
scope.
Reviewed By: antiagainst, mravishankar
Differential Revision: https://reviews.llvm.org/D84626
Added:
Modified:
mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
mlir/test/Conversion/SPIRVToLLVM/memory-ops-to-llvm.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp b/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
index 024f2b14a9890..e7c5b3c9f6dcd 100644
--- a/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
+++ b/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
@@ -273,6 +273,22 @@ static Optional<Type> convertStructType(spirv::StructType type,
namespace {
+class AddressOfPattern : public SPIRVToLLVMConversion<spirv::AddressOfOp> {
+public:
+ using SPIRVToLLVMConversion<spirv::AddressOfOp>::SPIRVToLLVMConversion;
+
+ LogicalResult
+ matchAndRewrite(spirv::AddressOfOp op, ArrayRef<Value> operands,
+ ConversionPatternRewriter &rewriter) const override {
+ auto dstType = typeConverter.convertType(op.pointer().getType());
+ if (!dstType)
+ return failure();
+ rewriter.replaceOpWithNewOp<LLVM::AddressOfOp>(
+ op, dstType.cast<LLVM::LLVMType>(), op.variable());
+ return success();
+ }
+};
+
class BitFieldInsertPattern
: public SPIRVToLLVMConversion<spirv::BitFieldInsertOp> {
public:
@@ -507,6 +523,55 @@ class DirectConversionPattern : public SPIRVToLLVMConversion<SPIRVOp> {
}
};
+/// Converts `spv.globalVariable` to `llvm.mlir.global`. Note that SPIR-V global
+/// returns a pointer, whereas in LLVM dialect the global holds an actual value.
+/// This
diff erence is handled by `spv._address_of` and `llvm.mlir.addressof`ops
+/// that both return a pointer.
+class GlobalVariablePattern
+ : public SPIRVToLLVMConversion<spirv::GlobalVariableOp> {
+public:
+ using SPIRVToLLVMConversion<spirv::GlobalVariableOp>::SPIRVToLLVMConversion;
+
+ LogicalResult
+ matchAndRewrite(spirv::GlobalVariableOp op, ArrayRef<Value> operands,
+ ConversionPatternRewriter &rewriter) const override {
+ // Currently, there is no support of initialization with a constant value in
+ // SPIR-V dialect. Specialization constants are not considered as well.
+ if (op.initializer())
+ return failure();
+
+ auto srcType = op.type().cast<spirv::PointerType>();
+ auto dstType = typeConverter.convertType(srcType.getPointeeType());
+ if (!dstType)
+ return failure();
+
+ // Limit conversion to the current invocation only for now.
+ auto storageClass = srcType.getStorageClass();
+ if (storageClass != spirv::StorageClass::Input &&
+ storageClass != spirv::StorageClass::Private &&
+ storageClass != spirv::StorageClass::Output) {
+ return failure();
+ }
+
+ // LLVM dialect spec: "If the global value is a constant, storing into it is
+ // not allowed.". This corresponds to SPIR-V 'Input' storage class that is
+ // read-only.
+ bool isConstant = storageClass == spirv::StorageClass::Input;
+ // SPIR-V spec: "By default, functions and global variables are private to a
+ // module and cannot be accessed by other modules. However, a module may be
+ // written to export or import functions and global (module scope)
+ // variables.". Therefore, map 'Private' storage class to private linkage,
+ // 'Input' and 'Output' to external linkage.
+ auto linkage = storageClass == spirv::StorageClass::Private
+ ? LLVM::Linkage::Private
+ : LLVM::Linkage::External;
+ rewriter.replaceOpWithNewOp<LLVM::GlobalOp>(
+ op, dstType.cast<LLVM::LLVMType>(), isConstant, linkage, op.sym_name(),
+ Attribute());
+ return success();
+ }
+};
+
/// Converts SPIR-V cast ops that do not have straightforward LLVM
/// equivalent in LLVM dialect.
template <typename SPIRVOp, typename LLVMExtOp, typename LLVMTruncOp>
@@ -1230,8 +1295,8 @@ void mlir::populateSPIRVToLLVMConversionPatterns(
NotPattern<spirv::LogicalNotOp>,
// Memory ops
- LoadStorePattern<spirv::LoadOp>, LoadStorePattern<spirv::StoreOp>,
- VariablePattern,
+ AddressOfPattern, GlobalVariablePattern, LoadStorePattern<spirv::LoadOp>,
+ LoadStorePattern<spirv::StoreOp>, VariablePattern,
// Miscellaneous ops
DirectConversionPattern<spirv::SelectOp, LLVM::SelectOp>,
diff --git a/mlir/test/Conversion/SPIRVToLLVM/memory-ops-to-llvm.mlir b/mlir/test/Conversion/SPIRVToLLVM/memory-ops-to-llvm.mlir
index a565d396e6702..51a734c462a36 100644
--- a/mlir/test/Conversion/SPIRVToLLVM/memory-ops-to-llvm.mlir
+++ b/mlir/test/Conversion/SPIRVToLLVM/memory-ops-to-llvm.mlir
@@ -1,5 +1,25 @@
// RUN: mlir-opt -convert-spirv-to-llvm %s | FileCheck %s
+//===----------------------------------------------------------------------===//
+// spv.globalVariable and spv._address_of
+//===----------------------------------------------------------------------===//
+
+spv.module Logical GLSL450 {
+ // CHECK: llvm.mlir.global external constant @var() : !llvm.float
+ spv.globalVariable @var : !spv.ptr<f32, Input>
+}
+
+spv.module Logical GLSL450 {
+ // CHECK: llvm.mlir.global private @struct() : !llvm.struct<packed (float, array<10 x float>)>
+ // CHECK-LABEL: @func
+ // CHECK: llvm.mlir.addressof @struct : !llvm.ptr<struct<packed (float, array<10 x float>)>>
+ spv.globalVariable @struct : !spv.ptr<!spv.struct<f32, !spv.array<10xf32>>, Private>
+ spv.func @func() -> () "None" {
+ %0 = spv._address_of @struct : !spv.ptr<!spv.struct<f32, !spv.array<10xf32>>, Private>
+ spv.Return
+ }
+}
+
//===----------------------------------------------------------------------===//
// spv.Load
//===----------------------------------------------------------------------===//
More information about the Mlir-commits
mailing list