Skip to content

[mlir][SymbolOpInterface] Easier visibility overriding #151036

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions mlir/include/mlir/IR/SymbolInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,19 @@ def Symbol : OpInterface<"SymbolOpInterface"> {
InterfaceMethod<"Returns true if this symbol has nested visibility.",
"bool", "isNested", (ins), [{}],
/*defaultImplementation=*/[{
return getVisibility() == mlir::SymbolTable::Visibility::Nested;
return $_op.getVisibility() == mlir::SymbolTable::Visibility::Nested;
}]
>,
InterfaceMethod<"Returns true if this symbol has private visibility.",
"bool", "isPrivate", (ins), [{}],
/*defaultImplementation=*/[{
return getVisibility() == mlir::SymbolTable::Visibility::Private;
return $_op.getVisibility() == mlir::SymbolTable::Visibility::Private;
}]
>,
InterfaceMethod<"Returns true if this symbol has public visibility.",
"bool", "isPublic", (ins), [{}],
/*defaultImplementation=*/[{
return getVisibility() == mlir::SymbolTable::Visibility::Public;
return $_op.getVisibility() == mlir::SymbolTable::Visibility::Public;
}]
>,
InterfaceMethod<"Sets the visibility of this symbol.",
Expand All @@ -79,19 +79,19 @@ def Symbol : OpInterface<"SymbolOpInterface"> {
InterfaceMethod<"Sets the visibility of this symbol to be nested.",
"void", "setNested", (ins), [{}],
/*defaultImplementation=*/[{
setVisibility(mlir::SymbolTable::Visibility::Nested);
$_op.setVisibility(mlir::SymbolTable::Visibility::Nested);
}]
>,
InterfaceMethod<"Sets the visibility of this symbol to be private.",
"void", "setPrivate", (ins), [{}],
/*defaultImplementation=*/[{
setVisibility(mlir::SymbolTable::Visibility::Private);
$_op.setVisibility(mlir::SymbolTable::Visibility::Private);
}]
>,
InterfaceMethod<"Sets the visibility of this symbol to be public.",
"void", "setPublic", (ins), [{}],
/*defaultImplementation=*/[{
setVisibility(mlir::SymbolTable::Visibility::Public);
$_op.setVisibility(mlir::SymbolTable::Visibility::Public);
}]
>,
InterfaceMethod<[{
Expand Down Expand Up @@ -144,7 +144,7 @@ def Symbol : OpInterface<"SymbolOpInterface"> {
// By default, base this on the visibility alone. A symbol can be
// discarded as long as it is not public. Only public symbols may be
// visible from outside of the IR.
return getVisibility() != ::mlir::SymbolTable::Visibility::Public;
return $_op.getVisibility() != ::mlir::SymbolTable::Visibility::Public;
}]
>,
InterfaceMethod<[{
Expand Down
26 changes: 26 additions & 0 deletions mlir/test/lib/Dialect/Test/TestOpDefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,32 @@
using namespace mlir;
using namespace test;

//===----------------------------------------------------------------------===//
// OverridenSymbolVisibilityOp
//===----------------------------------------------------------------------===//

SymbolTable::Visibility OverriddenSymbolVisibilityOp::getVisibility() {
return SymbolTable::Visibility::Private;
}

static StringLiteral getVisibilityString(SymbolTable::Visibility visibility) {
switch (visibility) {
case SymbolTable::Visibility::Private:
return "private";
case SymbolTable::Visibility::Nested:
return "nested";
case SymbolTable::Visibility::Public:
return "public";
}
}

void OverriddenSymbolVisibilityOp::setVisibility(
SymbolTable::Visibility visibility) {

emitOpError("cannot change visibility of symbol to ")
<< getVisibilityString(visibility);
}

//===----------------------------------------------------------------------===//
// TestBranchOp
//===----------------------------------------------------------------------===//
Expand Down
7 changes: 7 additions & 0 deletions mlir/test/lib/Dialect/Test/TestOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ def SymbolOp : TEST_Op<"symbol", [NoMemoryEffect, Symbol]> {
OptionalAttr<StrAttr>:$sym_visibility);
}

def OverriddenSymbolVisibilityOp : TEST_Op<"overridden_symbol_visibility", [
DeclareOpInterfaceMethods<Symbol, ["getVisibility", "setVisibility"]>,
]> {
let summary = "operation overridden symbol visibility accessors";
let arguments = (ins StrAttr:$sym_name);
}

def SymbolScopeOp : TEST_Op<"symbol_scope",
[SymbolTable, SingleBlockImplicitTerminator<"TerminatorOp">]> {
let summary = "operation which defines a new symbol table";
Expand Down
34 changes: 34 additions & 0 deletions mlir/unittests/IR/SymbolTableTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,38 @@ TEST_F(ReplaceAllSymbolUsesTest, StringAttrInFuncOp) {
});
}

TEST(SymbolOpInterface, Visibility) {
DialectRegistry registry;
::test::registerTestDialect(registry);
MLIRContext context(registry);

constexpr static StringLiteral kInput = R"MLIR(
"test.overridden_symbol_visibility"() {sym_name = "symbol_name"} : () -> ()
)MLIR";
OwningOpRef<ModuleOp> module = parseSourceString<ModuleOp>(kInput, &context);
auto symOp = cast<SymbolOpInterface>(module->getBody()->front());

ASSERT_TRUE(symOp.isPrivate());
ASSERT_FALSE(symOp.isPublic());
ASSERT_FALSE(symOp.isNested());
ASSERT_TRUE(symOp.canDiscardOnUseEmpty());

std::string diagStr;
context.getDiagEngine().registerHandler(
[&](Diagnostic &diag) { diagStr += diag.str(); });

std::string expectedDiag;
symOp.setPublic();
expectedDiag += "'test.overridden_symbol_visibility' op cannot change "
"visibility of symbol to public";
symOp.setNested();
expectedDiag += "'test.overridden_symbol_visibility' op cannot change "
"visibility of symbol to nested";
symOp.setPrivate();
expectedDiag += "'test.overridden_symbol_visibility' op cannot change "
"visibility of symbol to private";

ASSERT_EQ(diagStr, expectedDiag);
}

} // namespace