[spirv] NFC: move SPIR-V control flow ops to a separate file
authorLei Zhang <antiagainst@google.com>
Fri, 23 Aug 2019 18:07:13 +0000 (11:07 -0700)
committerA. Unique TensorFlower <gardener@tensorflow.org>
Fri, 23 Aug 2019 18:07:52 +0000 (11:07 -0700)
This CL is also purely moving code around for better file organization.

PiperOrigin-RevId: 265092566

mlir/include/mlir/Dialect/SPIRV/SPIRVControlFlowOps.td [new file with mode: 0644]
mlir/include/mlir/Dialect/SPIRV/SPIRVOps.td
mlir/lib/Dialect/SPIRV/SPIRVOps.cpp
mlir/test/Dialect/SPIRV/control-flow-ops.mlir [new file with mode: 0644]
mlir/test/Dialect/SPIRV/ops.mlir

diff --git a/mlir/include/mlir/Dialect/SPIRV/SPIRVControlFlowOps.td b/mlir/include/mlir/Dialect/SPIRV/SPIRVControlFlowOps.td
new file mode 100644 (file)
index 0000000..b0cde8b
--- /dev/null
@@ -0,0 +1,87 @@
+//===-- SPIRVControlFlowOps.td - SPIR-V Control Flow Ops ---*- 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 file contains control flow ops for the SPIR-V dialect. It corresponds
+// to "3.32.17. Control-Flow Instructions" of the SPIR-V specification.
+//
+//===----------------------------------------------------------------------===//
+
+#ifdef SPIRV_CONTROLFLOW_OPS
+#else
+#define SPIRV_CONTROLFLOW_OPS
+
+#ifdef SPIRV_BASE
+#else
+include "mlir/SPIRV/SPIRVBase.td"
+#endif // SPIRV_BASE
+
+// -----
+
+def SPV_ReturnOp : SPV_Op<"Return", [InFunctionScope, Terminator]> {
+  let summary = "Return with no value from a function with void return type.";
+
+  let description = [{
+    This instruction must be the last instruction in a block.
+
+    ### Custom assembly form
+
+    ``` {.ebnf}
+    return-op ::= `spv.Return`
+    ```
+  }];
+
+  let arguments = (ins);
+
+  let results = (outs);
+
+  let parser = [{ return parseNoIOOp(parser, result); }];
+  let printer = [{ printNoIOOp(getOperation(), p); }];
+}
+
+// -----
+
+def SPV_ReturnValueOp : SPV_Op<"ReturnValue", [InFunctionScope, Terminator]> {
+  let summary = "Return a value from a function.";
+
+  let description = [{
+    Value is the value returned, by copy, and must match the Return Type
+    operand of the OpTypeFunction type of the OpFunction body this return
+    instruction is in.
+
+    This instruction must be the last instruction in a block.
+
+    ### Custom assembly form
+
+    ``` {.ebnf}
+    return-value-op ::= `spv.ReturnValue` ssa-use `:` spirv-type
+    ```
+
+    For example:
+
+    ```
+    spv.ReturnValue %0 : f32
+    ```
+  }];
+
+  let arguments = (ins
+    SPV_Type:$value
+  );
+
+  let results = (outs);
+}
+
+#endif // SPIRV_CONTROLFLOW_OPS
index a6ff6ec..5fccf1b 100644 (file)
@@ -40,6 +40,11 @@ include "mlir/Dialect/SPIRV/SPIRVBase.td"
 include "mlir/Dialect/SPIRV/SPIRVArithmeticOps.td"
 #endif // SPIRV_ARITHMETIC_OPS
 
+#ifdef SPIRV_CONTROLFLOW_OPS
+#else
+include "mlir/Dialect/SPIRV/SPIRVControlFlowOps.td"
+#endif // SPIRV_CONTROLFLOW_OPS
+
 #ifdef SPIRV_LOGICAL_OPS
 #else
 include "mlir/Dialect/SPIRV/SPIRVLogicalOps.td"
@@ -250,63 +255,6 @@ def SPV_LoadOp : SPV_Op<"Load", []> {
 
 // -----
 
-def SPV_ReturnOp : SPV_Op<"Return", [InFunctionScope, Terminator]> {
-  let summary = "Return with no value from a function with void return type.";
-
-  let description = [{
-    This instruction must be the last instruction in a block.
-
-    ### Custom assembly form
-
-    ``` {.ebnf}
-    return-op ::= `spv.Return`
-    ```
-  }];
-
-  let arguments = (ins);
-
-  let results = (outs);
-
-  let parser = [{ return parseNoIOOp(parser, result); }];
-  let printer = [{ printNoIOOp(getOperation(), p); }];
-
-  let verifier = [{ return verifyReturn(*this); }];
-}
-
-// -----
-
-def SPV_ReturnValueOp : SPV_Op<"ReturnValue", [InFunctionScope, Terminator]> {
-  let summary = "Return a value from a function.";
-
-  let description = [{
-    Value is the value returned, by copy, and must match the Return Type
-    operand of the OpTypeFunction type of the OpFunction body this return
-    instruction is in.
-
-    This instruction must be the last instruction in a block.
-
-    ### Custom assembly form
-
-    ``` {.ebnf}
-    return-value-op ::= `spv.ReturnValue` ssa-use `:` spirv-type
-    ```
-
-    For example:
-
-    ```
-    spv.ReturnValue %0 : f32
-    ```
-  }];
-
-  let arguments = (ins
-    SPV_Type:$value
-  );
-
-  let results = (outs);
-}
-
-// -----
-
 def SPV_StoreOp : SPV_Op<"Store", []> {
   let summary = "Store through a pointer.";
 
index a8a93aa..fef9c0b 100644 (file)
@@ -59,7 +59,7 @@ inline Dst bitwiseCast(Src source) noexcept {
 
 static LogicalResult extractValueFromConstOp(Operation *op,
                                              int32_t &indexValue) {
-  auto constOp = llvm::dyn_cast<spirv::ConstantOp>(op);
+  auto constOp = dyn_cast<spirv::ConstantOp>(op);
   if (!constOp) {
     return failure();
   }
@@ -971,7 +971,7 @@ static LogicalResult verify(spirv::ModuleOp moduleOp) {
       // For EntryPoint op, check that the function and execution model is not
       // duplicated in EntryPointOps. Also verify that the interface specified
       // comes from globalVariables here to make this check cheaper.
-      if (auto entryPointOp = llvm::dyn_cast<spirv::EntryPointOp>(op)) {
+      if (auto entryPointOp = dyn_cast<spirv::EntryPointOp>(op)) {
         auto funcOp = table.lookup<FuncOp>(entryPointOp.fn());
         if (!funcOp) {
           return entryPointOp.emitError("function '")
@@ -1007,7 +1007,7 @@ static LogicalResult verify(spirv::ModuleOp moduleOp) {
       continue;
     }
 
-    auto funcOp = llvm::dyn_cast<FuncOp>(op);
+    auto funcOp = dyn_cast<FuncOp>(op);
     if (!funcOp)
       return op.emitError("'spv.module' can only contain func and spv.* ops");
 
@@ -1019,7 +1019,7 @@ static LogicalResult verify(spirv::ModuleOp moduleOp) {
         if (op.getDialect() == dialect)
           continue;
 
-        if (llvm::isa<FuncOp>(op))
+        if (isa<FuncOp>(op))
           return op.emitError("'spv.module' cannot contain nested functions");
 
         return op.emitError(
@@ -1090,8 +1090,8 @@ static LogicalResult verify(spirv::ReferenceOfOp referenceOfOp) {
 // spv.Return
 //===----------------------------------------------------------------------===//
 
-static LogicalResult verifyReturn(spirv::ReturnOp returnOp) {
-  auto funcOp = llvm::cast<FuncOp>(returnOp.getParentOp());
+static LogicalResult verify(spirv::ReturnOp returnOp) {
+  auto funcOp = cast<FuncOp>(returnOp.getParentOp());
   auto numOutputs = funcOp.getType().getNumResults();
   if (numOutputs != 0)
     return returnOp.emitOpError("cannot be used in functions returning value")
@@ -1120,7 +1120,7 @@ static void print(spirv::ReturnValueOp retValOp, OpAsmPrinter *printer) {
 }
 
 static LogicalResult verify(spirv::ReturnValueOp retValOp) {
-  auto funcOp = llvm::cast<FuncOp>(retValOp.getParentOp());
+  auto funcOp = cast<FuncOp>(retValOp.getParentOp());
   auto numFnResults = funcOp.getType().getNumResults();
   if (numFnResults != 1)
     return retValOp.emitOpError(
diff --git a/mlir/test/Dialect/SPIRV/control-flow-ops.mlir b/mlir/test/Dialect/SPIRV/control-flow-ops.mlir
new file mode 100644 (file)
index 0000000..bacea1e
--- /dev/null
@@ -0,0 +1,56 @@
+// RUN: mlir-opt -split-input-file -verify-diagnostics %s | FileCheck %s
+
+//===----------------------------------------------------------------------===//
+// spv.Return
+//===----------------------------------------------------------------------===//
+
+"foo.function"() ({
+  // expected-error @+1 {{op must appear in a 'func' block}}
+  spv.Return
+})  : () -> ()
+
+// -----
+
+// Return mismatches function signature
+spv.module "Logical" "VulkanKHR" {
+  func @work() -> (i32) {
+    // expected-error @+1 {{cannot be used in functions returning value}}
+    spv.Return
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spv.ReturnValue
+//===----------------------------------------------------------------------===//
+
+func @ret_val() -> (i32) {
+  %0 = spv.constant 42 : i32
+  // CHECK: spv.ReturnValue %{{.*}} : i32
+  spv.ReturnValue %0 : i32
+}
+
+// -----
+
+"foo.function"() ({
+  %0 = spv.constant true
+  // expected-error @+1 {{op must appear in a 'func' block}}
+  spv.ReturnValue %0 : i1
+})  : () -> ()
+
+// -----
+
+func @value_count_mismatch() -> () {
+  %0 = spv.constant 42 : i32
+  // expected-error @+1 {{op returns 1 value but enclosing function requires 0 results}}
+  spv.ReturnValue %0 : i32
+}
+
+// -----
+
+func @value_type_mismatch() -> (f32) {
+  %0 = spv.constant 42 : i32
+  // expected-error @+1 {{return value's type ('i32') mismatch with function's result type ('f32')}}
+  spv.ReturnValue %0 : i32
+}
index d804d7a..3e32b90 100644 (file)
@@ -431,62 +431,6 @@ spv.module "Logical" "VulkanKHR" {
 // -----
 
 //===----------------------------------------------------------------------===//
-// spv.Return
-//===----------------------------------------------------------------------===//
-
-"foo.function"() ({
-  // expected-error @+1 {{op must appear in a 'func' block}}
-  spv.Return
-})  : () -> ()
-
-// -----
-
-// Return mismatches function signature
-spv.module "Logical" "VulkanKHR" {
-  func @work() -> (i32) {
-    // expected-error @+1 {{cannot be used in functions returning value}}
-    spv.Return
-  }
-}
-
-// -----
-
-//===----------------------------------------------------------------------===//
-// spv.ReturnValue
-//===----------------------------------------------------------------------===//
-
-func @ret_val() -> (i32) {
-  %0 = spv.constant 42 : i32
-  spv.ReturnValue %0 : i32
-}
-
-// -----
-
-"foo.function"() ({
-  %0 = spv.constant true
-  // expected-error @+1 {{op must appear in a 'func' block}}
-  spv.ReturnValue %0 : i1
-})  : () -> ()
-
-// -----
-
-func @value_count_mismatch() -> () {
-  %0 = spv.constant 42 : i32
-  // expected-error @+1 {{op returns 1 value but enclosing function requires 0 results}}
-  spv.ReturnValue %0 : i32
-}
-
-// -----
-
-func @value_type_mismatch() -> (f32) {
-  %0 = spv.constant 42 : i32
-  // expected-error @+1 {{return value's type ('i32') mismatch with function's result type ('f32')}}
-  spv.ReturnValue %0 : i32
-}
-
-// -----
-
-//===----------------------------------------------------------------------===//
 // spv.StoreOp
 //===----------------------------------------------------------------------===//