diff --git a/mlir/docs/SymbolsAndSymbolTables.md b/mlir/docs/SymbolsAndSymbolTables.md --- a/mlir/docs/SymbolsAndSymbolTables.md +++ b/mlir/docs/SymbolsAndSymbolTables.md @@ -194,20 +194,21 @@ 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 --- a/mlir/include/mlir/IR/FunctionImplementation.h +++ b/mlir/include/mlir/IR/FunctionImplementation.h @@ -78,15 +78,23 @@ /// 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 argTypes, bool isVariadic, - ArrayRef resultTypes); + ArrayRef 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 --- a/mlir/include/mlir/IR/OpImplementation.h +++ b/mlir/include/mlir/IR/OpImplementation.h @@ -351,6 +351,12 @@ /// 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 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 --- a/mlir/include/mlir/IR/SymbolTable.h +++ b/mlir/include/mlir/IR/SymbolTable.h @@ -302,6 +302,18 @@ }; } // 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 --- a/mlir/include/mlir/Transforms/Passes.td +++ b/mlir/include/mlir/Transforms/Passes.td @@ -570,11 +570,11 @@ 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 @@ 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 --- a/mlir/lib/IR/Function.cpp +++ b/mlir/lib/IR/Function.cpp @@ -69,13 +69,15 @@ }; 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 --- a/mlir/lib/IR/FunctionImplementation.cpp +++ b/mlir/lib/IR/FunctionImplementation.cpp @@ -159,10 +159,9 @@ /// 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 entryArgs; SmallVector argAttrs; SmallVector resultAttrs; @@ -170,9 +169,13 @@ SmallVector 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 @@ /// argument and result types to use while printing. void mlir::impl::printFunctionLikeOp(OpAsmPrinter &p, Operation *op, ArrayRef argTypes, bool isVariadic, - ArrayRef resultTypes) { + ArrayRef resultTypes, + bool printVisibilityInline) { // Print the operation and the function name. auto funcName = - op->getAttrOfType(::mlir::SymbolTable::getSymbolAttrName()) + op->getAttrOfType(SymbolTable::getSymbolAttrName()) .getValue(); p << op->getName() << ' '; + StringRef elidedAttr; + if (printVisibilityInline) { + elidedAttr = SymbolTable::getVisibilityAttrName(); + if (auto visibility = op->getAttrOfType(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 --- 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 @@ 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 --- a/mlir/lib/Parser/Parser.cpp +++ b/mlir/lib/Parser/Parser.cpp @@ -1136,6 +1136,24 @@ return success(); } + /// Parse a keyword if it is one of the 'allowedKeywords'. + ParseResult + parseOptionalKeyword(StringRef *keyword, + ArrayRef 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 --- a/mlir/test/Conversion/AsyncToLLVM/convert-to-llvm.mlir +++ b/mlir/test/Conversion/AsyncToLLVM/convert-to-llvm.mlir @@ -15,8 +15,8 @@ } // Function outlined from the async.execute operation. -// CHECK-LABEL: func @async_execute_fn(%arg0: f32, %arg1: memref<1xf32>) -// CHECK-SAME: -> !llvm.ptr attributes {sym_visibility = "private"} +// CHECK-LABEL: func private @async_execute_fn(%arg0: f32, %arg1: memref<1xf32>) +// CHECK-SAME: -> !llvm.ptr // Create token for return op, and mark a function as a coroutine. // CHECK: %[[RET:.*]] = call @mlirAsyncRuntimeCreateToken() @@ -79,8 +79,8 @@ } // 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 attributes {sym_visibility = "private"} +// CHECK-LABEL: func private @async_execute_fn(%arg0: f32, %arg1: memref<1xf32>, %arg2: index) +// CHECK-SAME: -> !llvm.ptr // CHECK: %[[RET_0:.*]] = call @mlirAsyncRuntimeCreateToken() // CHECK: %[[HDL_0:.*]] = llvm.call @llvm.coro.begin // CHECK: call @mlirAsyncRuntimeExecute @@ -89,8 +89,8 @@ // 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 attributes {sym_visibility = "private"} +// CHECK-LABEL: func private @async_execute_fn_0(%arg0: f32, %arg1: memref<1xf32>, %arg2: f32) +// CHECK-SAME: -> !llvm.ptr // CHECK: %[[RET_1:.*]] = call @mlirAsyncRuntimeCreateToken() // CHECK: %[[HDL_1:.*]] = llvm.call @llvm.coro.begin @@ -128,8 +128,8 @@ } // Function outlined from the first async.execute operation. -// CHECK-LABEL: func @async_execute_fn(%arg0: f32, %arg1: memref<1xf32>) -// CHECK-SAME: -> !llvm.ptr attributes {sym_visibility = "private"} +// CHECK-LABEL: func private @async_execute_fn(%arg0: f32, %arg1: memref<1xf32>) +// CHECK-SAME: -> !llvm.ptr // CHECK: %[[RET_0:.*]] = call @mlirAsyncRuntimeCreateToken() // CHECK: %[[HDL_0:.*]] = llvm.call @llvm.coro.begin // CHECK: call @mlirAsyncRuntimeExecute @@ -138,8 +138,8 @@ // 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, %arg1: f32, %arg2: memref<1xf32>) -// CHECK-SAME: -> !llvm.ptr attributes {sym_visibility = "private"} +// CHECK-LABEL: func private @async_execute_fn_0(%arg0: !llvm.ptr, %arg1: f32, %arg2: memref<1xf32>) +// CHECK-SAME: -> !llvm.ptr // 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 --- a/mlir/test/Examples/Toy/Ch4/codegen.toy +++ b/mlir/test/Examples/Toy/Ch4/codegen.toy @@ -13,7 +13,7 @@ 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 --- 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 @@ 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 --- a/mlir/test/Examples/Toy/Ch5/codegen.toy +++ b/mlir/test/Examples/Toy/Ch5/codegen.toy @@ -13,7 +13,7 @@ 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 --- 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 --- a/mlir/test/Examples/Toy/Ch6/codegen.toy +++ b/mlir/test/Examples/Toy/Ch6/codegen.toy @@ -13,7 +13,7 @@ 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 --- 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 --- a/mlir/test/Examples/Toy/Ch7/codegen.toy +++ b/mlir/test/Examples/Toy/Ch7/codegen.toy @@ -13,7 +13,7 @@ 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 --- 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 --- a/mlir/test/Examples/Toy/Ch7/struct-codegen.toy +++ b/mlir/test/Examples/Toy/Ch7/struct-codegen.toy @@ -21,9 +21,8 @@ print(c); } -# CHECK-LABEL: func @multiply_transpose( +# CHECK-LABEL: func private @multiply_transpose( # CHECK-SAME: [[VAL_0:%.*]]: !toy.struct, 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> # 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> diff --git a/mlir/test/IR/core-ops.mlir b/mlir/test/IR/core-ops.mlir --- a/mlir/test/IR/core-ops.mlir +++ b/mlir/test/IR/core-ops.mlir @@ -969,3 +969,7 @@ 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 --- 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_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 @@ } // 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 @@ 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 --- 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 @@ /// 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 @@ // 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 @@ /// 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 @@ /// 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 @@ /// 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 @@ /// 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 @@ /// 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 @@ /// 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_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 --- 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.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.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 { - func @private_symbol() attributes { sym_visibility = "private" } + func private @private_symbol() // expected-error@+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 --- 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" () : () -> ()