[spirv] Start the SPIR-V dialect
authorLei Zhang <antiagainst@google.com>
Sun, 26 May 2019 12:43:20 +0000 (05:43 -0700)
committerMehdi Amini <joker.eph@gmail.com>
Sun, 2 Jun 2019 03:03:33 +0000 (20:03 -0700)
    This CL sets up the basic structure for a SPIR-V dialect: operation
    definition specification, dialect registration, testing, etc.
    A single op, FMul, is defined and tested to showcase.

    The SPIR-V dialect aims to be a simple proxy for the SPIR-V binary format
    to enable straightforward and lightweight conversion from/to the binary
    format. Ops in this dialect should stay as the same semantic level and
    try to be a mechanical mapping to the corresponding SPIR-V instructions;
    but they can deviate representationally to allow using MLIR mechanisms.

--

PiperOrigin-RevId: 250040830

13 files changed:
mlir/include/mlir/CMakeLists.txt
mlir/include/mlir/IR/DialectSymbolRegistry.def
mlir/include/mlir/SPIRV/CMakeLists.txt [new file with mode: 0644]
mlir/include/mlir/SPIRV/SPIRVDialect.h [new file with mode: 0644]
mlir/include/mlir/SPIRV/SPIRVOps.h [new file with mode: 0644]
mlir/include/mlir/SPIRV/SPIRVOps.td [new file with mode: 0644]
mlir/lib/CMakeLists.txt
mlir/lib/SPIRV/CMakeLists.txt [new file with mode: 0644]
mlir/lib/SPIRV/DialectRegistration.cpp [new file with mode: 0644]
mlir/lib/SPIRV/SPIRVDialect.cpp [new file with mode: 0644]
mlir/lib/SPIRV/SPIRVOps.cpp [new file with mode: 0644]
mlir/test/SPIRV/ops.mlir [new file with mode: 0644]
mlir/tools/mlir-opt/CMakeLists.txt

index d7d8175..a737b69 100644 (file)
@@ -3,4 +3,5 @@ add_subdirectory(EDSC)
 add_subdirectory(GPU)
 add_subdirectory(Linalg)
 add_subdirectory(LLVMIR)
+add_subdirectory(SPIRV)
 add_subdirectory(StandardOps)
index 4736c3a..6b0850c 100644 (file)
@@ -28,6 +28,7 @@ DEFINE_SYM_KIND_RANGE(QUANTIZATION)
 DEFINE_SYM_KIND_RANGE(IREE) // IREE stands for IR Execution Engine
 DEFINE_SYM_KIND_RANGE(LINALG) // Linear Algebra Dialect
 DEFINE_SYM_KIND_RANGE(TOY) // Toy language (tutorial) Dialect
+DEFINE_SYM_KIND_RANGE(SPIRV) // SPIR-V dialect
 
 // The following ranges are reserved for experimenting with MLIR dialects in a
 // private context without having to register them here.
diff --git a/mlir/include/mlir/SPIRV/CMakeLists.txt b/mlir/include/mlir/SPIRV/CMakeLists.txt
new file mode 100644 (file)
index 0000000..df4287b
--- /dev/null
@@ -0,0 +1,4 @@
+set(LLVM_TARGET_DEFINITIONS SPIRVOps.td)
+mlir_tablegen(SPIRVOps.h.inc -gen-op-decls)
+mlir_tablegen(SPIRVOps.cpp.inc -gen-op-defs)
+add_public_tablegen_target(MLIRSPIRVOpsIncGen)
diff --git a/mlir/include/mlir/SPIRV/SPIRVDialect.h b/mlir/include/mlir/SPIRV/SPIRVDialect.h
new file mode 100644 (file)
index 0000000..14a576b
--- /dev/null
@@ -0,0 +1,40 @@
+//===- SPIRVDialect.h - MLIR SPIR-V dialect ---------------------*- C++ -*-===//
+//
+// Copyright 2019 The MLIR Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// =============================================================================
+//
+// This file declares the SPIR-V dialect in MLIR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_SPIRV_SPIRVDIALECT_H_
+#define MLIR_SPIRV_SPIRVDIALECT_H_
+
+#include "mlir/IR/Dialect.h"
+
+namespace mlir {
+class MLIRContext;
+
+namespace spirv {
+
+class SPIRVDialect : public Dialect {
+public:
+  explicit SPIRVDialect(MLIRContext *context);
+};
+
+} // end namespace spirv
+} // end namespace mlir
+
+#endif // MLIR_SPIRV_SPIRVDIALECT_H_
diff --git a/mlir/include/mlir/SPIRV/SPIRVOps.h b/mlir/include/mlir/SPIRV/SPIRVOps.h
new file mode 100644 (file)
index 0000000..00f8548
--- /dev/null
@@ -0,0 +1,36 @@
+//===- SPIRVOps.h - MLIR SPIR-V operations ----------------------*- C++ -*-===//
+//
+// Copyright 2019 The MLIR Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// =============================================================================
+//
+// This file declares the operations in the SPIR-V dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_SPIRV_SPIRVOPS_H_
+#define MLIR_SPIRV_SPIRVOPS_H_
+
+#include "mlir/IR/OpDefinition.h"
+
+namespace mlir {
+namespace spirv {
+
+#define GET_OP_CLASSES
+#include "mlir/SPIRV/SPIRVOps.h.inc"
+
+} // end namespace spirv
+} // end namespace mlir
+
+#endif // MLIR_SPIRV_SPIRVOPS_H_
diff --git a/mlir/include/mlir/SPIRV/SPIRVOps.td b/mlir/include/mlir/SPIRV/SPIRVOps.td
new file mode 100644 (file)
index 0000000..73eee63
--- /dev/null
@@ -0,0 +1,96 @@
+//===-- SPIRVOps.td - MLIR SPIR-V Op Definitions Spec ------*- tablegen -*-===//
+//
+// Copyright 2019 The MLIR Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// =============================================================================
+//
+// This is the operation definition specification file for SPIR-V operations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifdef SPIRV_OPS
+#else
+#define SPIRV_OPS
+
+#ifdef OP_BASE
+#else
+include "mlir/IR/OpBase.td"
+#endif // OP_BASE
+
+//===----------------------------------------------------------------------===//
+// SPIR-V dialect definitions
+//===----------------------------------------------------------------------===//
+
+def SPV_Dialect : Dialect {
+  let name = "spv";
+
+  let description = [{
+    The SPIR-V dialect in MLIR.
+
+    SPIR-V is the Khronos Group's binary intermediate language for representing
+    graphical-shader stages and compute kernels for multiple Khronos APIs,
+    including OpenCL, OpenGL, and Vulkan.
+    See https://www.khronos.org/registry/spir-v for more details.
+
+    This dialect aims to be a simple proxy for the SPIR-V binary format to
+    enable straightforward and lightweight conversion from/to the binary
+    format. Ops in this dialect should stay at the same semantic level and
+    try to be a mechanical mapping to the corresponding SPIR-V instructions;
+    but they may deviate representationally to allow using MLIR mechanisms.
+  }];
+
+  let cppNamespace = "spirv";
+}
+
+//===----------------------------------------------------------------------===//
+// SPIR-V type definitions
+//===----------------------------------------------------------------------===//
+
+class SPV_ScalarOrVectorOf<Type type> :
+    Type<Or<[type.predicate, VectorOf<[type]>.predicate]>,
+         "scalar/vector of " # type.description>;
+
+//===----------------------------------------------------------------------===//
+// SPIR-V op definitions
+//===----------------------------------------------------------------------===//
+
+// Base class for all SPIR-V ops.
+class SPV_Op<string mnemonic, list<OpTrait> traits = []> :
+    Op<SPV_Dialect, mnemonic, traits>;
+
+def SPV_FMulOp : SPV_Op<"FMul", [NoSideEffect, SameValueType]> {
+  let summary = "Floating-point multiplication of Operand 1 and Operand 2";
+
+  let description = [{
+    Result Type must be a scalar or vector of floating-point type.
+
+    The types of Operand 1 and Operand 2 both must be the same as Result Type.
+
+    Results are computed per component.
+  }];
+
+  let arguments = (ins
+    SPV_ScalarOrVectorOf<AnyFloat>:$operand1,
+    SPV_ScalarOrVectorOf<AnyFloat>:$operand2
+  );
+
+  let results = (outs
+    SPV_ScalarOrVectorOf<AnyFloat>:$result
+  );
+
+  let parser = [{ return impl::parseBinaryOp(parser, result); }];
+  let printer = [{ return impl::printBinaryOp(getOperation(), p); }];
+}
+
+#endif // SPIRV_OPS
index 4ffd472..68b3224 100644 (file)
@@ -11,6 +11,7 @@ add_subdirectory(Parser)
 add_subdirectory(Pass)
 add_subdirectory(Quantizer)
 add_subdirectory(SDBM)
+add_subdirectory(SPIRV)
 add_subdirectory(StandardOps)
 add_subdirectory(Support)
 add_subdirectory(TableGen)
diff --git a/mlir/lib/SPIRV/CMakeLists.txt b/mlir/lib/SPIRV/CMakeLists.txt
new file mode 100644 (file)
index 0000000..efc8b1e
--- /dev/null
@@ -0,0 +1,12 @@
+add_llvm_library(MLIRSPIRV
+  DialectRegistration.cpp
+  SPIRVDialect.cpp
+  SPIRVOps.cpp
+
+  ADDITIONAL_HEADER_DIRS
+  ${MLIR_MAIN_INCLUDE_DIR}/mlir/SPIRV
+  )
+
+add_dependencies(MLIRSPIRV MLIRSPIRVOpsIncGen)
+
+target_link_libraries(MLIRSPIRV MLIRIR MLIRSupport)
diff --git a/mlir/lib/SPIRV/DialectRegistration.cpp b/mlir/lib/SPIRV/DialectRegistration.cpp
new file mode 100644 (file)
index 0000000..3a464b3
--- /dev/null
@@ -0,0 +1,21 @@
+//===- DialectRegistration.cpp - MLIR SPIR-V dialect registration ---------===//
+//
+// Copyright 2019 The MLIR Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// =============================================================================
+
+#include "mlir/SPIRV/SPIRVDialect.h"
+
+// Static initialization for SPIR-V dialect registration.
+static mlir::DialectRegistration<mlir::spirv::SPIRVDialect> spirvDialect;
diff --git a/mlir/lib/SPIRV/SPIRVDialect.cpp b/mlir/lib/SPIRV/SPIRVDialect.cpp
new file mode 100644 (file)
index 0000000..9df0453
--- /dev/null
@@ -0,0 +1,41 @@
+//===- LLVMDialect.cpp - MLIR SPIR-V dialect ------------------------------===//
+//
+// Copyright 2019 The MLIR Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// =============================================================================
+//
+// This file defines the SPIR-V dialect in MLIR.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/SPIRV/SPIRVDialect.h"
+
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/SPIRV/SPIRVOps.h"
+
+namespace mlir {
+namespace spirv {
+
+SPIRVDialect::SPIRVDialect(MLIRContext *context) : Dialect("spv", context) {
+  addOperations<
+#define GET_OP_LIST
+#include "mlir/SPIRV/SPIRVOps.cpp.inc"
+      >();
+
+  // Allow unknown operations because SPIR-V is extensible.
+  allowUnknownOperations();
+}
+
+} // namespace spirv
+} // namespace mlir
diff --git a/mlir/lib/SPIRV/SPIRVOps.cpp b/mlir/lib/SPIRV/SPIRVOps.cpp
new file mode 100644 (file)
index 0000000..ae23ba2
--- /dev/null
@@ -0,0 +1,33 @@
+//===- SPIRVOps.cpp - MLIR SPIR-V operations ------------------------------===//
+//
+// Copyright 2019 The MLIR Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// =============================================================================
+//
+// This file defines the operations in the SPIR-V dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/SPIRV/SPIRVOps.h"
+
+#include "mlir/IR/StandardTypes.h"
+
+namespace mlir {
+namespace spirv {
+
+#define GET_OP_CLASSES
+#include "mlir/SPIRV/SPIRVOps.cpp.inc"
+
+} // namespace spirv
+} // namespace mlir
diff --git a/mlir/test/SPIRV/ops.mlir b/mlir/test/SPIRV/ops.mlir
new file mode 100644 (file)
index 0000000..7b471e3
--- /dev/null
@@ -0,0 +1,34 @@
+// RUN: mlir-opt -split-input-file -verify %s | FileCheck %s
+
+//===----------------------------------------------------------------------===//
+// spv.FMul
+//===----------------------------------------------------------------------===//
+
+func @fmul_scalar(%arg: f32) -> f32 {
+  // CHECK: spv.FMul
+  %0 = spv.FMul %arg, %arg : f32
+  return %0 : f32
+}
+
+func @fmul_vector(%arg: vector<4xf32>) -> vector<4xf32> {
+  // CHECK: spv.FMul
+  %0 = spv.FMul %arg, %arg : vector<4xf32>
+  return %0 : vector<4xf32>
+}
+
+// -----
+
+func @fmul_i32(%arg: i32) -> i32 {
+  // expected-error @+1 {{must be scalar/vector of floating-point}}
+  %0 = spv.FMul %arg, %arg : i32
+  return %0 : i32
+}
+
+// -----
+
+func @fmul_tensor(%arg: tensor<4xf32>) -> tensor<4xf32> {
+  // expected-error @+1 {{must be scalar/vector of floating-point}}
+  %0 = spv.FMul %arg, %arg : tensor<4xf32>
+  return %0 : tensor<4xf32>
+}
+
index 636d186..276be6a 100644 (file)
@@ -28,6 +28,7 @@ set(LIBS
   MLIRPass
   MLIRQuantizerTransforms
   MLIRQuantOps
+  MLIRSPIRV
   MLIRStandardOps
   MLIRTransforms
   MLIRSupport