Skip to content

Commit a60e83f

Browse files
committed
[mlir][Interfaces] Add a extraSharedClassDeclaration field
This field allows for defining a code block that is placed in both the interface and trait declarations. This is very useful when defining a set of utilities to expose on both the Interface class and the derived attribute/operation/type. In non-static methods, `$_attr`/`$_op`/`$_type` (depending on the type of interface) may be used to refer to an instance of the IR entity. In the interface declaration, this is an instance of the interface class. In the trait declaration, this is an instance of the concrete entity class (e.g. `IntegerAttr`, `FuncOp`, etc.). Differential Revision: https://reviews.llvm.org/D116961
1 parent aa1c533 commit a60e83f

File tree

6 files changed

+53
-0
lines changed

6 files changed

+53
-0
lines changed

mlir/docs/Interfaces.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,18 @@ comprised of the following components:
393393
These declarations are _not_ implicitly visible in default
394394
implementations of interface methods, but static declarations may be
395395
accessed with full name qualification.
396+
* Extra Shared Class Declarations (Optional: `extraSharedClassDeclaration`)
397+
- Additional C++ code that is injected into the declarations of both the
398+
interface and trait class. This allows for defining methods and more
399+
that are exposed on both the interface and trait class, e.g. to inject
400+
utilties on both the interface and the derived entity implementing the
401+
interface (e.g. attribute, operation, etc.).
402+
- In non-static methods, `$_attr`/`$_op`/`$_type`
403+
(depending on the type of interface) may be used to refer to an
404+
instance of the IR entity. In the interface declaration, the type of
405+
the instance is the interface class. In the trait declaration, the
406+
type of the instance is the concrete entity class
407+
(e.g. `IntegerAttr`, `FuncOp`, etc.).
396408

397409
`OpInterface` classes may additionally contain the following:
398410

mlir/include/mlir/IR/OpBase.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2226,6 +2226,10 @@ class Interface<string name> {
22262226
// An optional code block containing extra declarations to place in the
22272227
// interface declaration.
22282228
code extraClassDeclaration = "";
2229+
2230+
// An optional code block containing extra declarations to place in both
2231+
// the interface and trait declaration.
2232+
code extraSharedClassDeclaration = "";
22292233
}
22302234

22312235
// AttrInterface represents an interface registered to an attribute.

mlir/include/mlir/TableGen/Interfaces.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ class Interface {
9191
// Return the traits extra class declaration code.
9292
llvm::Optional<StringRef> getExtraTraitClassDeclaration() const;
9393

94+
// Return the extra class declaration code shared between the interface and
95+
// trait classes.
96+
llvm::Optional<StringRef> getExtraSharedClassDeclaration() const;
97+
9498
// Return the verify method body if it has one.
9599
llvm::Optional<StringRef> getVerify() const;
96100

mlir/lib/TableGen/Interfaces.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,12 @@ llvm::Optional<StringRef> Interface::getExtraTraitClassDeclaration() const {
110110
return value.empty() ? llvm::Optional<StringRef>() : value;
111111
}
112112

113+
// Return the shared extra class declaration code.
114+
llvm::Optional<StringRef> Interface::getExtraSharedClassDeclaration() const {
115+
auto value = def->getValueAsString("extraSharedClassDeclaration");
116+
return value.empty() ? llvm::Optional<StringRef>() : value;
117+
}
118+
113119
// Return the body for this method if it has one.
114120
llvm::Optional<StringRef> Interface::getVerify() const {
115121
// Only OpInterface supports the verify method.

mlir/test/mlir-tblgen/op-interface.td

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,24 @@
33

44
include "mlir/IR/OpBase.td"
55

6+
def ExtraShardDeclsInterface : OpInterface<"ExtraShardDeclsInterface"> {
7+
let extraSharedClassDeclaration = [{
8+
bool sharedMethodDeclaration() {
9+
return $_op.someOtherMethod();
10+
}
11+
}];
12+
}
13+
14+
// DECL: class ExtraShardDeclsInterface
15+
// DECL: bool sharedMethodDeclaration() {
16+
// DECL-NEXT: return (*this).someOtherMethod();
17+
// DECL-NEXT: }
18+
19+
// DECL: struct ExtraShardDeclsInterfaceTrait
20+
// DECL: bool sharedMethodDeclaration() {
21+
// DECL-NEXT: return (*static_cast<ConcreteOp *>(this)).someOtherMethod();
22+
// DECL-NEXT: }
23+
624
def TestOpInterface : OpInterface<"TestOpInterface"> {
725
let description = [{some op interface description}];
826

mlir/tools/mlir-tblgen/OpInterfacesGen.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class InterfaceGenerator {
104104
/// The format context to use for methods.
105105
tblgen::FmtContext nonStaticMethodFmt;
106106
tblgen::FmtContext traitMethodFmt;
107+
tblgen::FmtContext extraDeclsFmt;
107108
};
108109

109110
/// A specialized generator for attribute interfaces.
@@ -118,6 +119,7 @@ struct AttrInterfaceGenerator : public InterfaceGenerator {
118119
nonStaticMethodFmt.addSubst("_attr", castCode).withSelf(castCode);
119120
traitMethodFmt.addSubst("_attr",
120121
"(*static_cast<const ConcreteAttr *>(this))");
122+
extraDeclsFmt.addSubst("_attr", "(*this)");
121123
}
122124
};
123125
/// A specialized generator for operation interfaces.
@@ -132,6 +134,7 @@ struct OpInterfaceGenerator : public InterfaceGenerator {
132134
.withOp(castCode)
133135
.withSelf(castCode);
134136
traitMethodFmt.withOp("(*static_cast<ConcreteOp *>(this))");
137+
extraDeclsFmt.withOp("(*this)");
135138
}
136139
};
137140
/// A specialized generator for type interfaces.
@@ -146,6 +149,7 @@ struct TypeInterfaceGenerator : public InterfaceGenerator {
146149
nonStaticMethodFmt.addSubst("_type", castCode).withSelf(castCode);
147150
traitMethodFmt.addSubst("_type",
148151
"(*static_cast<const ConcreteType *>(this))");
152+
extraDeclsFmt.addSubst("_type", "(*this)");
149153
}
150154
};
151155
} // namespace
@@ -415,6 +419,8 @@ void InterfaceGenerator::emitTraitDecl(Interface &interface,
415419
}
416420
if (auto extraTraitDecls = interface.getExtraTraitClassDeclaration())
417421
os << tblgen::tgfmt(*extraTraitDecls, &traitMethodFmt) << "\n";
422+
if (auto extraTraitDecls = interface.getExtraSharedClassDeclaration())
423+
os << tblgen::tgfmt(*extraTraitDecls, &traitMethodFmt) << "\n";
418424

419425
os << " };\n";
420426
}
@@ -469,6 +475,9 @@ void InterfaceGenerator::emitInterfaceDecl(Interface interface) {
469475
// Emit any extra declarations.
470476
if (Optional<StringRef> extraDecls = interface.getExtraClassDeclaration())
471477
os << *extraDecls << "\n";
478+
if (Optional<StringRef> extraDecls =
479+
interface.getExtraSharedClassDeclaration())
480+
os << tblgen::tgfmt(*extraDecls, &extraDeclsFmt);
472481

473482
os << "};\n";
474483

0 commit comments

Comments
 (0)