[Mlir-commits] [mlir] 8b5a3e4 - [MLIR] Change FuncOp assembly syntax to print visibility inline instead of in attrib dict.

Rahul Joshi llvmlistbot at llvm.org
Mon Nov 9 11:10:39 PST 2020


Author: Rahul Joshi
Date: 2020-11-09T11:08:08-08:00
New Revision: 8b5a3e46326f646c3cca187058c2ef71910daeb0

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

LOG: [MLIR] Change FuncOp assembly syntax to print visibility inline instead of in attrib dict.

- Change syntax for FuncOp to be `func <visibility>? @name` instead of printing the
  visibility in the attribute dictionary.
- Since printFunctionLikeOp() and parseFunctionLikeOp() are also used by other
  operations, make the "inline visibility" an opt-in feature.
- Updated unit test to use and check the new syntax.

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

Added: 
    

Modified: 
    mlir/docs/SymbolsAndSymbolTables.md
    mlir/include/mlir/IR/FunctionImplementation.h
    mlir/include/mlir/IR/OpImplementation.h
    mlir/include/mlir/IR/SymbolTable.h
    mlir/include/mlir/Transforms/Passes.td
    mlir/lib/IR/Function.cpp
    mlir/lib/IR/FunctionImplementation.cpp
    mlir/lib/IR/SymbolTable.cpp
    mlir/lib/Parser/Parser.cpp
    mlir/test/Conversion/AsyncToLLVM/convert-to-llvm.mlir
    mlir/test/Examples/Toy/Ch4/codegen.toy
    mlir/test/Examples/Toy/Ch4/shape_inference.mlir
    mlir/test/Examples/Toy/Ch5/codegen.toy
    mlir/test/Examples/Toy/Ch5/shape_inference.mlir
    mlir/test/Examples/Toy/Ch6/codegen.toy
    mlir/test/Examples/Toy/Ch6/shape_inference.mlir
    mlir/test/Examples/Toy/Ch7/codegen.toy
    mlir/test/Examples/Toy/Ch7/shape_inference.mlir
    mlir/test/Examples/Toy/Ch7/struct-codegen.toy
    mlir/test/IR/core-ops.mlir
    mlir/test/Transforms/inlining-dce.mlir
    mlir/test/Transforms/sccp-callgraph.mlir
    mlir/test/Transforms/test-symbol-dce.mlir
    mlir/test/mlir-reduce/dce-test.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/docs/SymbolsAndSymbolTables.md b/mlir/docs/SymbolsAndSymbolTables.md
index a2cd828fd4d1..d7bcfa46d4e5 100644
--- a/mlir/docs/SymbolsAndSymbolTables.md
+++ b/mlir/docs/SymbolsAndSymbolTables.md
@@ -194,20 +194,21 @@ symbol has one of the following visibilities:
         table, but not outside of the visible IR, as long as each symbol table
         parent also defines a non-private symbol.
 
-A few examples of what this looks like in the IR are shown below:
+For Functions, the visibility is printed after the operation name without a
+quote. A few examples of what this looks like in the IR are shown below:
 
 ```mlir
 module @public_module {
   // This function can be accessed by 'live.user', but cannot be referenced
   // externally; all uses are known to reside within parent regions.
-  func @nested_function() attributes { sym_visibility = "nested" }
+  func nested @nested_function()
 
   // This function cannot be accessed outside of 'public_module'.
-  func @private_function() attributes { sym_visibility = "private" }
+  func private @private_function()
 }
 
 // This function can only be accessed from within the top-level module.
-func @private_function() attributes { sym_visibility = "private" }
+func private @private_function()
 
 // This function may be referenced externally.
 func @public_function()

diff  --git a/mlir/include/mlir/IR/FunctionImplementation.h b/mlir/include/mlir/IR/FunctionImplementation.h
index c19100c55219..bad32fe3df38 100644
--- a/mlir/include/mlir/IR/FunctionImplementation.h
+++ b/mlir/include/mlir/IR/FunctionImplementation.h
@@ -78,15 +78,23 @@ parseFunctionSignature(OpAsmParser &parser, bool allowVariadic,
 /// whether the function is variadic.  If the builder returns a null type,
 /// `result` will not contain the `type` attribute.  The caller can then add a
 /// type, report the error or delegate the reporting to the op's verifier.
+/// If `allowInlineVisibility` is true, then the parser will allow visibility
+/// to be specified after the operation name. If the visibility is not specified
+/// there or `allowInlineVisibility` is false, visibility will be allowed in the
+/// attribute dict.
 ParseResult parseFunctionLikeOp(OpAsmParser &parser, OperationState &result,
                                 bool allowVariadic,
-                                FuncTypeBuilder funcTypeBuilder);
+                                FuncTypeBuilder funcTypeBuilder,
+                                bool allowInlineVisibility = false);
 
 /// Printer implementation for function-like operations.  Accepts lists of
-/// argument and result types to use while printing.
+/// argument and result types to use while printing. If `printVisibilityInline`
+/// is true, visibility is printed "inline" after the operation name and elided
+/// from the attributes dict. Otherwise, it is printed in the attribute dict.
 void printFunctionLikeOp(OpAsmPrinter &p, Operation *op,
                          ArrayRef<Type> argTypes, bool isVariadic,
-                         ArrayRef<Type> resultTypes);
+                         ArrayRef<Type> resultTypes,
+                         bool printVisibilityInline = false);
 
 /// Prints the signature of the function-like operation `op`.  Assumes `op` has
 /// the FunctionLike trait and passed the verification.

diff  --git a/mlir/include/mlir/IR/OpImplementation.h b/mlir/include/mlir/IR/OpImplementation.h
index d24561333a3d..48bd03eb46a9 100644
--- a/mlir/include/mlir/IR/OpImplementation.h
+++ b/mlir/include/mlir/IR/OpImplementation.h
@@ -351,6 +351,12 @@ class OpAsmParser {
   /// Parse a keyword, if present, into 'keyword'.
   virtual ParseResult parseOptionalKeyword(StringRef *keyword) = 0;
 
+  /// Parse a keyword, if present, and if one of the 'allowedValues',
+  /// into 'keyword'
+  virtual ParseResult
+  parseOptionalKeyword(StringRef *keyword,
+                       ArrayRef<StringRef> allowedValues) = 0;
+
   /// Parse a `(` token.
   virtual ParseResult parseLParen() = 0;
 

diff  --git a/mlir/include/mlir/IR/SymbolTable.h b/mlir/include/mlir/IR/SymbolTable.h
index d54d7590f2bb..0e3230672568 100644
--- a/mlir/include/mlir/IR/SymbolTable.h
+++ b/mlir/include/mlir/IR/SymbolTable.h
@@ -302,6 +302,18 @@ class SymbolTable : public TraitBase<ConcreteType, SymbolTable> {
 };
 
 } // end namespace OpTrait
+
+//===----------------------------------------------------------------------===//
+// Visibility parsing implementation.
+//===----------------------------------------------------------------------===//
+
+namespace impl {
+/// Parse an optional visibility attribute keyword (i.e., public, private, or
+/// nested) without quotes in a string attribute named 'attrName'.
+ParseResult parseOptionalVisibilityKeyword(OpAsmParser &parser,
+                                           NamedAttrList &attrs);
+} // end namespace impl
+
 } // end namespace mlir
 
 /// Include the generated symbol interfaces.

diff  --git a/mlir/include/mlir/Transforms/Passes.td b/mlir/include/mlir/Transforms/Passes.td
index 031b30812179..3fcbb9a15087 100644
--- a/mlir/include/mlir/Transforms/Passes.td
+++ b/mlir/include/mlir/Transforms/Passes.td
@@ -570,11 +570,11 @@ def SymbolDCE : Pass<"symbol-dce"> {
     For example, consider the following input:
 
     ```mlir
-    func @dead_private_function() attributes { sym_visibility = "private" }
-    func @live_private_function() attributes { sym_visibility = "private" }
+    func private @dead_private_function()
+    func private @live_private_function()
 
     // Note: The `public` isn't necessary here, as this is the default.
-    func @public_function() attributes { sym_visibility = "public" } {
+    func public @public_function() {
       "foo.return"() {uses = [@live_private_function]} : () -> ()
     }
     ```
@@ -586,9 +586,9 @@ def SymbolDCE : Pass<"symbol-dce"> {
     are no links to known-live operations. After running, we get the expected:
 
     ```mlir
-    func @live_private_function() attributes { sym_visibility = "private" }
+    func private @live_private_function()
 
-    func @public_function() attributes { sym_visibility = "public" } {
+    func public @public_function() {
       "foo.return"() {uses = [@live_private_function]} : () -> ()
     }
     ```

diff  --git a/mlir/lib/IR/Function.cpp b/mlir/lib/IR/Function.cpp
index 03378f21f638..2139545ddd28 100644
--- a/mlir/lib/IR/Function.cpp
+++ b/mlir/lib/IR/Function.cpp
@@ -69,13 +69,15 @@ ParseResult FuncOp::parse(OpAsmParser &parser, OperationState &result) {
   };
 
   return impl::parseFunctionLikeOp(parser, result, /*allowVariadic=*/false,
-                                   buildFuncType);
+                                   buildFuncType,
+                                   /*allowInlineVisibility=*/true);
 }
 
 void FuncOp::print(OpAsmPrinter &p) {
   FunctionType fnType = getType();
   impl::printFunctionLikeOp(p, *this, fnType.getInputs(), /*isVariadic=*/false,
-                            fnType.getResults());
+                            fnType.getResults(),
+                            /*printVisibilityInline=*/true);
 }
 
 LogicalResult FuncOp::verify() {

diff  --git a/mlir/lib/IR/FunctionImplementation.cpp b/mlir/lib/IR/FunctionImplementation.cpp
index 56b2221fd44f..a4e249338fd4 100644
--- a/mlir/lib/IR/FunctionImplementation.cpp
+++ b/mlir/lib/IR/FunctionImplementation.cpp
@@ -159,10 +159,9 @@ void mlir::impl::addArgAndResultAttrs(Builder &builder, OperationState &result,
 
 /// Parser implementation for function-like operations.  Uses `funcTypeBuilder`
 /// to construct the custom function type given lists of input and output types.
-ParseResult
-mlir::impl::parseFunctionLikeOp(OpAsmParser &parser, OperationState &result,
-                                bool allowVariadic,
-                                mlir::impl::FuncTypeBuilder funcTypeBuilder) {
+ParseResult mlir::impl::parseFunctionLikeOp(
+    OpAsmParser &parser, OperationState &result, bool allowVariadic,
+    mlir::impl::FuncTypeBuilder funcTypeBuilder, bool allowInlineVisibility) {
   SmallVector<OpAsmParser::OperandType, 4> entryArgs;
   SmallVector<NamedAttrList, 4> argAttrs;
   SmallVector<NamedAttrList, 4> resultAttrs;
@@ -170,9 +169,13 @@ mlir::impl::parseFunctionLikeOp(OpAsmParser &parser, OperationState &result,
   SmallVector<Type, 4> resultTypes;
   auto &builder = parser.getBuilder();
 
+  // Parse visibility if inline visibility is allowed.
+  if (allowInlineVisibility)
+    impl::parseOptionalVisibilityKeyword(parser, result.attributes);
+
   // Parse the name as a symbol.
   StringAttr nameAttr;
-  if (parser.parseSymbolName(nameAttr, ::mlir::SymbolTable::getSymbolAttrName(),
+  if (parser.parseSymbolName(nameAttr, SymbolTable::getSymbolAttrName(),
                              result.attributes))
     return failure();
 
@@ -303,17 +306,24 @@ void mlir::impl::printFunctionAttributes(OpAsmPrinter &p, Operation *op,
 /// argument and result types to use while printing.
 void mlir::impl::printFunctionLikeOp(OpAsmPrinter &p, Operation *op,
                                      ArrayRef<Type> argTypes, bool isVariadic,
-                                     ArrayRef<Type> resultTypes) {
+                                     ArrayRef<Type> resultTypes,
+                                     bool printVisibilityInline) {
   // Print the operation and the function name.
   auto funcName =
-      op->getAttrOfType<StringAttr>(::mlir::SymbolTable::getSymbolAttrName())
+      op->getAttrOfType<StringAttr>(SymbolTable::getSymbolAttrName())
           .getValue();
   p << op->getName() << ' ';
+  StringRef elidedAttr;
+  if (printVisibilityInline) {
+    elidedAttr = SymbolTable::getVisibilityAttrName();
+    if (auto visibility = op->getAttrOfType<StringAttr>(elidedAttr))
+      p << visibility.getValue() << ' ';
+  }
   p.printSymbolName(funcName);
 
   printFunctionSignature(p, op, argTypes, isVariadic, resultTypes);
-  printFunctionAttributes(p, op, argTypes.size(), resultTypes.size());
-
+  printFunctionAttributes(p, op, argTypes.size(), resultTypes.size(),
+                          {elidedAttr});
   // Print the body if this is not an external function.
   Region &body = op->getRegion(0);
   if (!body.empty())

diff  --git a/mlir/lib/IR/SymbolTable.cpp b/mlir/lib/IR/SymbolTable.cpp
index 90b4a9dac4e7..85c08c3a7e8f 100644
--- a/mlir/lib/IR/SymbolTable.cpp
+++ b/mlir/lib/IR/SymbolTable.cpp
@@ -7,6 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "mlir/IR/SymbolTable.h"
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/OpImplementation.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallString.h"
@@ -986,6 +988,22 @@ SymbolTable &SymbolTableCollection::getSymbolTable(Operation *op) {
   return *it.first->second;
 }
 
+//===----------------------------------------------------------------------===//
+// Visibility parsing implementation.
+//===----------------------------------------------------------------------===//
+
+ParseResult impl::parseOptionalVisibilityKeyword(OpAsmParser &parser,
+                                                 NamedAttrList &attrs) {
+  StringRef visibility;
+  if (parser.parseOptionalKeyword(&visibility, {"public", "private", "nested"}))
+    return failure();
+
+  StringAttr visibilityAttr = parser.getBuilder().getStringAttr(visibility);
+  attrs.push_back(parser.getBuilder().getNamedAttr(
+      SymbolTable::getVisibilityAttrName(), visibilityAttr));
+  return success();
+}
+
 //===----------------------------------------------------------------------===//
 // Symbol Interfaces
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/lib/Parser/Parser.cpp b/mlir/lib/Parser/Parser.cpp
index 8c581ad7bc0c..739e37b8c078 100644
--- a/mlir/lib/Parser/Parser.cpp
+++ b/mlir/lib/Parser/Parser.cpp
@@ -1136,6 +1136,24 @@ class CustomOpAsmParser : public OpAsmParser {
     return success();
   }
 
+  /// Parse a keyword if it is one of the 'allowedKeywords'.
+  ParseResult
+  parseOptionalKeyword(StringRef *keyword,
+                       ArrayRef<StringRef> allowedKeywords) override {
+    // Check that the current token is a keyword.
+    if (!isCurrentTokenAKeyword())
+      return failure();
+
+    StringRef currentKeyword = parser.getTokenSpelling();
+    if (llvm::is_contained(allowedKeywords, currentKeyword)) {
+      *keyword = currentKeyword;
+      parser.consumeToken();
+      return success();
+    }
+
+    return failure();
+  }
+
   /// Parse an optional @-identifier and store it (without the '@' symbol) in a
   /// string attribute named 'attrName'.
   ParseResult parseOptionalSymbolName(StringAttr &result, StringRef attrName,

diff  --git a/mlir/test/Conversion/AsyncToLLVM/convert-to-llvm.mlir b/mlir/test/Conversion/AsyncToLLVM/convert-to-llvm.mlir
index f8287dd0a360..aa912baef566 100644
--- a/mlir/test/Conversion/AsyncToLLVM/convert-to-llvm.mlir
+++ b/mlir/test/Conversion/AsyncToLLVM/convert-to-llvm.mlir
@@ -15,8 +15,8 @@ func @execute_no_async_args(%arg0: f32, %arg1: memref<1xf32>) {
 }
 
 // Function outlined from the async.execute operation.
-// CHECK-LABEL: func @async_execute_fn(%arg0: f32, %arg1: memref<1xf32>)
-// CHECK-SAME: -> !llvm.ptr<i8> attributes {sym_visibility = "private"}
+// CHECK-LABEL: func private @async_execute_fn(%arg0: f32, %arg1: memref<1xf32>)
+// CHECK-SAME: -> !llvm.ptr<i8>
 
 // Create token for return op, and mark a function as a coroutine.
 // CHECK: %[[RET:.*]] = call @mlirAsyncRuntimeCreateToken()
@@ -79,8 +79,8 @@ func @nested_async_execute(%arg0: f32, %arg1: f32, %arg2: memref<1xf32>) {
 }
 
 // Function outlined from the inner async.execute operation.
-// CHECK-LABEL: func @async_execute_fn(%arg0: f32, %arg1: memref<1xf32>, %arg2: index)
-// CHECK-SAME: -> !llvm.ptr<i8> attributes {sym_visibility = "private"}
+// CHECK-LABEL: func private @async_execute_fn(%arg0: f32, %arg1: memref<1xf32>, %arg2: index)
+// CHECK-SAME: -> !llvm.ptr<i8>
 // CHECK: %[[RET_0:.*]] = call @mlirAsyncRuntimeCreateToken()
 // CHECK: %[[HDL_0:.*]] = llvm.call @llvm.coro.begin
 // CHECK: call @mlirAsyncRuntimeExecute
@@ -89,8 +89,8 @@ func @nested_async_execute(%arg0: f32, %arg1: f32, %arg2: memref<1xf32>) {
 // CHECK: call @mlirAsyncRuntimeEmplaceToken(%[[RET_0]])
 
 // Function outlined from the outer async.execute operation.
-// CHECK-LABEL: func @async_execute_fn_0(%arg0: f32, %arg1: memref<1xf32>, %arg2: f32)
-// CHECK-SAME: -> !llvm.ptr<i8> attributes {sym_visibility = "private"}
+// CHECK-LABEL: func private @async_execute_fn_0(%arg0: f32, %arg1: memref<1xf32>, %arg2: f32)
+// CHECK-SAME: -> !llvm.ptr<i8>
 // CHECK: %[[RET_1:.*]] = call @mlirAsyncRuntimeCreateToken()
 // CHECK: %[[HDL_1:.*]] = llvm.call @llvm.coro.begin
 
@@ -128,8 +128,8 @@ func @async_execute_token_dependency(%arg0: f32, %arg1: memref<1xf32>) {
 }
 
 // Function outlined from the first async.execute operation.
-// CHECK-LABEL: func @async_execute_fn(%arg0: f32, %arg1: memref<1xf32>)
-// CHECK-SAME: -> !llvm.ptr<i8> attributes {sym_visibility = "private"}
+// CHECK-LABEL: func private @async_execute_fn(%arg0: f32, %arg1: memref<1xf32>)
+// CHECK-SAME: -> !llvm.ptr<i8>
 // CHECK: %[[RET_0:.*]] = call @mlirAsyncRuntimeCreateToken()
 // CHECK: %[[HDL_0:.*]] = llvm.call @llvm.coro.begin
 // CHECK: call @mlirAsyncRuntimeExecute
@@ -138,8 +138,8 @@ func @async_execute_token_dependency(%arg0: f32, %arg1: memref<1xf32>) {
 // CHECK: call @mlirAsyncRuntimeEmplaceToken(%[[RET_0]])
 
 // Function outlined from the second async.execute operation with dependency.
-// CHECK-LABEL: func @async_execute_fn_0(%arg0: !llvm.ptr<i8>, %arg1: f32, %arg2: memref<1xf32>)
-// CHECK-SAME: -> !llvm.ptr<i8> attributes {sym_visibility = "private"}
+// CHECK-LABEL: func private @async_execute_fn_0(%arg0: !llvm.ptr<i8>, %arg1: f32, %arg2: memref<1xf32>)
+// CHECK-SAME: -> !llvm.ptr<i8>
 // CHECK: %[[RET_1:.*]] = call @mlirAsyncRuntimeCreateToken()
 // CHECK: %[[HDL_1:.*]] = llvm.call @llvm.coro.begin
 

diff  --git a/mlir/test/Examples/Toy/Ch4/codegen.toy b/mlir/test/Examples/Toy/Ch4/codegen.toy
index 785817f5c877..c1a862bfb61c 100644
--- a/mlir/test/Examples/Toy/Ch4/codegen.toy
+++ b/mlir/test/Examples/Toy/Ch4/codegen.toy
@@ -13,7 +13,7 @@ def main() {
   print(d);
 }
 
-# CHECK-LABEL: func @multiply_transpose(
+# CHECK-LABEL: func private @multiply_transpose(
 # CHECK-SAME:                           [[VAL_0:%.*]]: tensor<*xf64>, [[VAL_1:%.*]]: tensor<*xf64>) -> tensor<*xf64>
 # CHECK:         [[VAL_2:%.*]] = toy.transpose([[VAL_0]] : tensor<*xf64>) to tensor<*xf64>
 # CHECK-NEXT:    [[VAL_3:%.*]] = toy.transpose([[VAL_1]] : tensor<*xf64>) to tensor<*xf64>

diff  --git a/mlir/test/Examples/Toy/Ch4/shape_inference.mlir b/mlir/test/Examples/Toy/Ch4/shape_inference.mlir
index 7c7f2513b96d..02788f8e671a 100644
--- a/mlir/test/Examples/Toy/Ch4/shape_inference.mlir
+++ b/mlir/test/Examples/Toy/Ch4/shape_inference.mlir
@@ -2,8 +2,7 @@
 
 // Check the result of inlining+shape inference on an input module.
 
-func @multiply_transpose(%arg0: tensor<*xf64>, %arg1: tensor<*xf64>) -> tensor<*xf64>
-    attributes { sym_visibility = "private" } {
+func private @multiply_transpose(%arg0: tensor<*xf64>, %arg1: tensor<*xf64>) -> tensor<*xf64> {
   %0 = toy.transpose(%arg0 : tensor<*xf64>) to tensor<*xf64>
   %1 = toy.transpose(%arg1 : tensor<*xf64>) to tensor<*xf64>
   %2 = toy.mul %0, %1 : tensor<*xf64>
@@ -20,7 +19,7 @@ func @main() {
   toy.return
 }
 
-// CHECK-NOT: func @multiply_transpose
+// CHECK-NOT: func private @multiply_transpose
 // CHECK-NOT: tensor<*xf64>
 
 // CHECK-LABEL: func @main()

diff  --git a/mlir/test/Examples/Toy/Ch5/codegen.toy b/mlir/test/Examples/Toy/Ch5/codegen.toy
index 2083a6abb1c7..d2b72d82e063 100644
--- a/mlir/test/Examples/Toy/Ch5/codegen.toy
+++ b/mlir/test/Examples/Toy/Ch5/codegen.toy
@@ -13,7 +13,7 @@ def main() {
   print(d);
 }
 
-# CHECK-LABEL: func @multiply_transpose(
+# CHECK-LABEL: func private @multiply_transpose(
 # CHECK-SAME:                           [[VAL_0:%.*]]: tensor<*xf64>, [[VAL_1:%.*]]: tensor<*xf64>) -> tensor<*xf64>
 # CHECK:         [[VAL_2:%.*]] = toy.transpose([[VAL_0]] : tensor<*xf64>) to tensor<*xf64>
 # CHECK-NEXT:    [[VAL_3:%.*]] = toy.transpose([[VAL_1]] : tensor<*xf64>) to tensor<*xf64>

diff  --git a/mlir/test/Examples/Toy/Ch5/shape_inference.mlir b/mlir/test/Examples/Toy/Ch5/shape_inference.mlir
index 37d9249281c9..1f4afb1bfe68 100644
--- a/mlir/test/Examples/Toy/Ch5/shape_inference.mlir
+++ b/mlir/test/Examples/Toy/Ch5/shape_inference.mlir
@@ -2,8 +2,7 @@
 
 // Check the result of inlining+shape inference on an input module.
 
-func @multiply_transpose(%arg0: tensor<*xf64>, %arg1: tensor<*xf64>) -> tensor<*xf64>
-    attributes { sym_visibility = "private" } {
+func private @multiply_transpose(%arg0: tensor<*xf64>, %arg1: tensor<*xf64>) -> tensor<*xf64> {
   %0 = toy.transpose(%arg0 : tensor<*xf64>) to tensor<*xf64>
   %1 = toy.transpose(%arg1 : tensor<*xf64>) to tensor<*xf64>
   %2 = toy.mul %0, %1 : tensor<*xf64>

diff  --git a/mlir/test/Examples/Toy/Ch6/codegen.toy b/mlir/test/Examples/Toy/Ch6/codegen.toy
index 97746ceec0fc..47573d958ad4 100644
--- a/mlir/test/Examples/Toy/Ch6/codegen.toy
+++ b/mlir/test/Examples/Toy/Ch6/codegen.toy
@@ -13,7 +13,7 @@ def main() {
   print(d);
 }
 
-# CHECK-LABEL: func @multiply_transpose(
+# CHECK-LABEL: func private @multiply_transpose(
 # CHECK-SAME:                           [[VAL_0:%.*]]: tensor<*xf64>, [[VAL_1:%.*]]: tensor<*xf64>) -> tensor<*xf64>
 # CHECK:         [[VAL_2:%.*]] = toy.transpose([[VAL_0]] : tensor<*xf64>) to tensor<*xf64>
 # CHECK-NEXT:    [[VAL_3:%.*]] = toy.transpose([[VAL_1]] : tensor<*xf64>) to tensor<*xf64>

diff  --git a/mlir/test/Examples/Toy/Ch6/shape_inference.mlir b/mlir/test/Examples/Toy/Ch6/shape_inference.mlir
index 44a8e66a58bb..d1f5833485da 100644
--- a/mlir/test/Examples/Toy/Ch6/shape_inference.mlir
+++ b/mlir/test/Examples/Toy/Ch6/shape_inference.mlir
@@ -2,8 +2,7 @@
 
 // Check the result of inlining+shape inference on an input module.
 
-func @multiply_transpose(%arg0: tensor<*xf64>, %arg1: tensor<*xf64>) -> tensor<*xf64>
-    attributes { sym_visibility = "private" } {
+func private @multiply_transpose(%arg0: tensor<*xf64>, %arg1: tensor<*xf64>) -> tensor<*xf64> {
   %0 = toy.transpose(%arg0 : tensor<*xf64>) to tensor<*xf64>
   %1 = toy.transpose(%arg1 : tensor<*xf64>) to tensor<*xf64>
   %2 = toy.mul %0, %1 : tensor<*xf64>

diff  --git a/mlir/test/Examples/Toy/Ch7/codegen.toy b/mlir/test/Examples/Toy/Ch7/codegen.toy
index 3956fe668d58..57923960736f 100644
--- a/mlir/test/Examples/Toy/Ch7/codegen.toy
+++ b/mlir/test/Examples/Toy/Ch7/codegen.toy
@@ -13,7 +13,7 @@ def main() {
   print(d);
 }
 
-# CHECK-LABEL: func @multiply_transpose(
+# CHECK-LABEL: func private @multiply_transpose(
 # CHECK-SAME:                           [[VAL_0:%.*]]: tensor<*xf64>, [[VAL_1:%.*]]: tensor<*xf64>) -> tensor<*xf64>
 # CHECK:         [[VAL_2:%.*]] = toy.transpose([[VAL_0]] : tensor<*xf64>) to tensor<*xf64>
 # CHECK-NEXT:    [[VAL_3:%.*]] = toy.transpose([[VAL_1]] : tensor<*xf64>) to tensor<*xf64>

diff  --git a/mlir/test/Examples/Toy/Ch7/shape_inference.mlir b/mlir/test/Examples/Toy/Ch7/shape_inference.mlir
index 8d679458aa59..a27673c565e3 100644
--- a/mlir/test/Examples/Toy/Ch7/shape_inference.mlir
+++ b/mlir/test/Examples/Toy/Ch7/shape_inference.mlir
@@ -2,8 +2,7 @@
 
 // Check the result of inlining+shape inference on an input module.
 
-func @multiply_transpose(%arg0: tensor<*xf64>, %arg1: tensor<*xf64>) -> tensor<*xf64>
-    attributes { sym_visibility = "private" } {
+func private @multiply_transpose(%arg0: tensor<*xf64>, %arg1: tensor<*xf64>) -> tensor<*xf64> {
   %0 = toy.transpose(%arg0 : tensor<*xf64>) to tensor<*xf64>
   %1 = toy.transpose(%arg1 : tensor<*xf64>) to tensor<*xf64>
   %2 = toy.mul %0, %1 : tensor<*xf64>

diff  --git a/mlir/test/Examples/Toy/Ch7/struct-codegen.toy b/mlir/test/Examples/Toy/Ch7/struct-codegen.toy
index b650e3a8dc09..3e8928091812 100644
--- a/mlir/test/Examples/Toy/Ch7/struct-codegen.toy
+++ b/mlir/test/Examples/Toy/Ch7/struct-codegen.toy
@@ -21,9 +21,8 @@ def main() {
   print(c);
 }
 
-# CHECK-LABEL:   func @multiply_transpose(
+# CHECK-LABEL:   func private @multiply_transpose(
 # CHECK-SAME:                             [[VAL_0:%.*]]: !toy.struct<tensor<*xf64>, tensor<*xf64>>) -> tensor<*xf64>
-# CHECK-SAME:        attributes {sym_visibility = "private"}
 # CHECK-NEXT:      [[VAL_1:%.*]] = toy.struct_access [[VAL_0]][0] : !toy.struct<tensor<*xf64>, tensor<*xf64>> -> tensor<*xf64>
 # CHECK-NEXT:      [[VAL_2:%.*]] = toy.transpose([[VAL_1]] : tensor<*xf64>) to tensor<*xf64>
 # CHECK-NEXT:      [[VAL_3:%.*]] = toy.struct_access [[VAL_0]][1] : !toy.struct<tensor<*xf64>, tensor<*xf64>> -> tensor<*xf64>

diff  --git a/mlir/test/IR/core-ops.mlir b/mlir/test/IR/core-ops.mlir
index dfed144fb44e..838452619990 100644
--- a/mlir/test/IR/core-ops.mlir
+++ b/mlir/test/IR/core-ops.mlir
@@ -969,3 +969,7 @@ func @subtensor_insert(%t: tensor<8x16x4xf32>, %t2: tensor<16x32x8xf32>, %idx :
 
   return
 }
+
+// CHECK-LABEL: func private @legacy_visibility_syntax
+func @legacy_visibility_syntax() attributes { sym_visibility = "private" }
+

diff  --git a/mlir/test/Transforms/inlining-dce.mlir b/mlir/test/Transforms/inlining-dce.mlir
index 06504ec39e71..01f4cb087411 100644
--- a/mlir/test/Transforms/inlining-dce.mlir
+++ b/mlir/test/Transforms/inlining-dce.mlir
@@ -3,14 +3,14 @@
 // This file tests the callgraph dead code elimination performed by the inliner.
 
 // Function is already dead.
-// CHECK-NOT: func @dead_function
-func @dead_function() attributes {sym_visibility = "private"} {
+// CHECK-NOT: func private @dead_function
+func private @dead_function() {
   return
 }
 
 // Function becomes dead after inlining.
-// CHECK-NOT: func @dead_function_b
-func @dead_function_b() attributes {sym_visibility = "private"} {
+// CHECK-NOT: func private @dead_function_b
+func @dead_function_b() {
   return
 }
 
@@ -26,13 +26,13 @@ func @live_function() {
 func @live_function_b() {
   return
 }
-// CHECK-NOT: func @dead_function_c
-func @dead_function_c() attributes {sym_visibility = "private"} {
+// CHECK-NOT: func private @dead_function_c
+func private @dead_function_c() {
   call @live_function_b() : () -> ()
   return
 }
-// CHECK-NOT: func @dead_function_d
-func @dead_function_d() attributes {sym_visibility = "private"} {
+// CHECK-NOT: func private @dead_function_d
+func private @dead_function_d() {
   call @dead_function_c() : () -> ()
   call @dead_function_c() : () -> ()
   return
@@ -45,8 +45,8 @@ func @live_function_c() {
 }
 
 // Function is referenced by non-callable top-level user.
-// CHECK: func @live_function_d
-func @live_function_d() attributes {sym_visibility = "private"} {
+// CHECK: func private @live_function_d
+func private @live_function_d() {
   return
 }
 
@@ -63,11 +63,11 @@ func @live_function_e() {
   return
 }
 // CHECK-NOT: func @dead_function_e
-func @dead_function_e() -> () attributes {sym_visibility = "private"} {
+func private @dead_function_e() -> () {
   "test.fold_to_call_op"() {callee=@dead_function_f} : () -> ()
   return
 }
-// CHECK-NOT: func @dead_function_f
-func @dead_function_f() attributes {sym_visibility = "private"} {
+// CHECK-NOT: func private @dead_function_f
+func private @dead_function_f() {
   return
 }

diff  --git a/mlir/test/Transforms/sccp-callgraph.mlir b/mlir/test/Transforms/sccp-callgraph.mlir
index c30cdf7bfb97..4b81fad9b3c7 100644
--- a/mlir/test/Transforms/sccp-callgraph.mlir
+++ b/mlir/test/Transforms/sccp-callgraph.mlir
@@ -4,8 +4,8 @@
 /// Check that a constant is properly propagated through the arguments and
 /// results of a private function.
 
-// CHECK-LABEL: func @private(
-func @private(%arg0 : i32) -> i32 attributes { sym_visibility = "private" } {
+// CHECK-LABEL: func private @private(
+func private @private(%arg0 : i32) -> i32 {
   // CHECK: %[[CST:.*]] = constant 1 : i32
   // CHECK: return %[[CST]] : i32
 
@@ -27,8 +27,8 @@ func @simple_private() -> i32 {
 /// Check that a constant is properly propagated through the arguments and
 /// results of a visible nested function.
 
-// CHECK: func @nested(
-func @nested(%arg0 : i32) -> i32 attributes { sym_visibility = "nested" } {
+// CHECK: func nested @nested(
+func nested @nested(%arg0 : i32) -> i32 {
   // CHECK: %[[CST:.*]] = constant 1 : i32
   // CHECK: return %[[CST]] : i32
 
@@ -52,8 +52,8 @@ module {
   // NESTED-LABEL: module @nested_module
   module @nested_module attributes { sym_visibility = "public" } {
 
-    // NESTED: func @nested(
-    func @nested(%arg0 : i32) -> (i32, i32) attributes { sym_visibility = "nested" } {
+    // NESTED: func nested @nested(
+    func nested @nested(%arg0 : i32) -> (i32, i32) {
       // NESTED: %[[CST:.*]] = constant 1 : i32
       // NESTED: return %[[CST]], %arg0 : i32, i32
 
@@ -79,7 +79,7 @@ module {
 /// Check that public functions do not track arguments.
 
 // CHECK-LABEL: func @public(
-func @public(%arg0 : i32) -> (i32, i32) attributes { sym_visibility = "public" } {
+func @public(%arg0 : i32) -> (i32, i32) {
   %1 = constant 1 : i32
   return %1, %arg0 : i32, i32
 }
@@ -99,7 +99,7 @@ func @simple_public() -> (i32, i32) {
 
 /// Check that functions with non-call users don't have arguments tracked.
 
-func @callable(%arg0 : i32) -> (i32, i32) attributes { sym_visibility = "private" } {
+func private @callable(%arg0 : i32) -> (i32, i32) {
   %1 = constant 1 : i32
   return %1, %arg0 : i32, i32
 }
@@ -121,7 +121,7 @@ func @non_call_users() -> (i32, i32) {
 
 /// Check that return values are overdefined in the presence of an unknown terminator.
 
-func @callable(%arg0 : i32) -> i32 attributes { sym_visibility = "private" } {
+func private @callable(%arg0 : i32) -> i32 {
   "unknown.return"(%arg0) : (i32) -> ()
 }
 
@@ -139,7 +139,7 @@ func @unknown_terminator() -> i32 {
 
 /// Check that return values are overdefined when the constant conflicts.
 
-func @callable(%arg0 : i32) -> i32 attributes { sym_visibility = "private" } {
+func private @callable(%arg0 : i32) -> i32 {
   "unknown.return"(%arg0) : (i32) -> ()
 }
 
@@ -161,7 +161,7 @@ func @conflicting_constant() -> (i32, i32) {
 /// Check that return values are overdefined when the constant conflicts with a
 /// non-constant.
 
-func @callable(%arg0 : i32) -> i32 attributes { sym_visibility = "private" } {
+func private @callable(%arg0 : i32) -> i32 {
   "unknown.return"(%arg0) : (i32) -> ()
 }
 
@@ -181,8 +181,8 @@ func @conflicting_constant(%arg0 : i32) -> (i32, i32) {
 
 /// Check a more complex interaction with calls and control flow.
 
-// CHECK-LABEL: func @complex_inner_if(
-func @complex_inner_if(%arg0 : i32) -> i32 attributes { sym_visibility = "private" } {
+// CHECK-LABEL: func private @complex_inner_if(
+func private @complex_inner_if(%arg0 : i32) -> i32 {
   // CHECK-DAG: %[[TRUE:.*]] = constant true
   // CHECK-DAG: %[[CST:.*]] = constant 1 : i32
   // CHECK: cond_br %[[TRUE]], ^bb1
@@ -206,8 +206,8 @@ func @complex_inner_if(%arg0 : i32) -> i32 attributes { sym_visibility = "privat
 
 func @complex_cond() -> i1
 
-// CHECK-LABEL: func @complex_callee(
-func @complex_callee(%arg0 : i32) -> i32 attributes { sym_visibility = "private" } {
+// CHECK-LABEL: func private @complex_callee(
+func private @complex_callee(%arg0 : i32) -> i32 {
   // CHECK: %[[CST:.*]] = constant 1 : i32
 
   %loop_cond = call @complex_cond() : () -> i1

diff  --git a/mlir/test/Transforms/test-symbol-dce.mlir b/mlir/test/Transforms/test-symbol-dce.mlir
index f81c2ca84894..08b87ff4ae9f 100644
--- a/mlir/test/Transforms/test-symbol-dce.mlir
+++ b/mlir/test/Transforms/test-symbol-dce.mlir
@@ -5,25 +5,25 @@
 
 // CHECK-LABEL: module attributes {test.simple}
 module attributes {test.simple} {
-  // CHECK-NOT: func @dead_private_function
-  func @dead_private_function() attributes { sym_visibility = "private" }
+  // CHECK-NOT: func private @dead_private_function
+  func private @dead_private_function()
 
-  // CHECK-NOT: func @dead_nested_function
-  func @dead_nested_function() attributes { sym_visibility = "nested" }
+  // CHECK-NOT: func nested @dead_nested_function
+  func nested @dead_nested_function()
 
-  // CHECK: func @live_private_function
-  func @live_private_function() attributes { sym_visibility = "private" }
+  // CHECK: func private @live_private_function
+  func private @live_private_function()
 
-  // CHECK: func @live_nested_function
-  func @live_nested_function() attributes { sym_visibility = "nested" }
+  // CHECK: func nested @live_nested_function
+  func nested @live_nested_function()
 
   // CHECK: func @public_function
   func @public_function() {
     "foo.return"() {uses = [@live_private_function, @live_nested_function]} : () -> ()
   }
 
-  // CHECK: func @public_function_explicit
-  func @public_function_explicit() attributes { sym_visibility = "public" }
+  // CHECK: func public @public_function_explicit
+  func public @public_function_explicit()
 }
 
 // -----
@@ -33,14 +33,14 @@ module attributes {test.simple} {
 module attributes {test.nested} {
   // CHECK: module @public_module
   module @public_module {
-    // CHECK-NOT: func @dead_nested_function
-    func @dead_nested_function() attributes { sym_visibility = "nested" }
+    // CHECK-NOT: func nested @dead_nested_function
+    func nested @dead_nested_function()
 
-    // CHECK: func @private_function
-    func @private_function() attributes { sym_visibility = "private" }
+    // CHECK: func private @private_function
+    func private @private_function()
 
-    // CHECK: func @nested_function
-    func @nested_function() attributes { sym_visibility = "nested" } {
+    // CHECK: func nested @nested_function
+    func nested @nested_function() {
       "foo.return"() {uses = [@private_function]} : () -> ()
     }
   }
@@ -56,20 +56,20 @@ module attributes {test.nested} {
 module attributes {test.no_dce_non_hidden_parent} {
   // NESTED: module @public_module
   module @public_module {
-    // NESTED: func @nested_function
-    func @nested_function() attributes { sym_visibility = "nested" }
+    // NESTED: func nested @nested_function
+    func nested @nested_function()
   }
   // NESTED: module @nested_module
   module @nested_module attributes { sym_visibility = "nested" } {
-    // NESTED: func @nested_function
-    func @nested_function() attributes { sym_visibility = "nested" }
+    // NESTED: func nested @nested_function
+    func nested @nested_function()
   }
 
   // Only private modules can be assumed to be hidden.
   // NESTED: module @private_module
   module @private_module attributes { sym_visibility = "private" } {
-    // NESTED-NOT: func @nested_function
-    func @nested_function() attributes { sym_visibility = "nested" }
+    // NESTED-NOT: func nested @nested_function
+    func nested @nested_function()
   }
 
   "live.user"() {uses = [@nested_module, @private_module]} : () -> ()
@@ -78,7 +78,7 @@ module attributes {test.no_dce_non_hidden_parent} {
 // -----
 
 module {
-  func @private_symbol() attributes { sym_visibility = "private" }
+  func private @private_symbol()
 
   // expected-error at +1 {{contains potentially unknown symbol table}}
   "foo.possibly_unknown_symbol_table"() ({

diff  --git a/mlir/test/mlir-reduce/dce-test.mlir b/mlir/test/mlir-reduce/dce-test.mlir
index 307b364bf428..f98f3cd6b1a8 100644
--- a/mlir/test/mlir-reduce/dce-test.mlir
+++ b/mlir/test/mlir-reduce/dce-test.mlir
@@ -6,10 +6,10 @@
 // CHECK-LABEL: func @simple1(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
 
 // CHECK-NOT: func @dead_nested_function
-func @dead_private_function() attributes { sym_visibility = "private" }
+func private @dead_private_function()
 
 // CHECK-NOT: func @dead_nested_function
-func @dead_nested_function() attributes { sym_visibility = "nested" }
+func nested @dead_nested_function()
 
 func @simple1(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
   "test.crashOp" () : () -> ()


        


More information about the Mlir-commits mailing list