[llvm] [mlir] [MLIR] convert OpAsmDialectInterface using ODS (PR #171488)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 18 03:15:43 PST 2025
https://github.com/aidint updated https://github.com/llvm/llvm-project/pull/171488
>From 5f2d23e6c7e18ab6439b934b831840909028da1e Mon Sep 17 00:00:00 2001
From: aidint <at.aidin at gmail.com>
Date: Tue, 9 Dec 2025 18:28:24 +0100
Subject: [PATCH 1/7] convert OpAsmDialectInterface using ODS
---
mlir/include/mlir/IR/CMakeLists.txt | 5 ++
mlir/include/mlir/IR/Interfaces.td | 20 ++++-
mlir/include/mlir/IR/OpAsmDialectInterface.td | 78 +++++++++++++++++++
mlir/include/mlir/IR/OpImplementation.h | 65 ++--------------
mlir/include/mlir/TableGen/Interfaces.h | 9 +++
mlir/lib/IR/CMakeLists.txt | 1 +
mlir/lib/TableGen/Interfaces.cpp | 24 ++++++
.../mlir-tblgen/DialectInterfacesGen.cpp | 37 +++++++--
8 files changed, 175 insertions(+), 64 deletions(-)
create mode 100644 mlir/include/mlir/IR/OpAsmDialectInterface.td
diff --git a/mlir/include/mlir/IR/CMakeLists.txt b/mlir/include/mlir/IR/CMakeLists.txt
index 683e2feaddef2..22358d7b09616 100644
--- a/mlir/include/mlir/IR/CMakeLists.txt
+++ b/mlir/include/mlir/IR/CMakeLists.txt
@@ -57,6 +57,11 @@ mlir_tablegen(TensorEncInterfaces.h.inc -gen-attr-interface-decls)
mlir_tablegen(TensorEncInterfaces.cpp.inc -gen-attr-interface-defs)
add_mlir_generic_tablegen_target(MLIRTensorEncodingIncGen)
+set(LLVM_TARGET_DEFINITIONS OpAsmDialectInterface.td)
+mlir_tablegen(OpAsmDialectInterface.h.inc -gen-dialect-interface-decls)
+add_mlir_generic_tablegen_target(MLIROpAsmDialectInterfaceIncGen)
+
+
add_mlir_doc(BuiltinAttributes BuiltinAttributes Dialects/ -gen-attrdef-doc)
add_mlir_doc(BuiltinLocationAttributes BuiltinLocationAttributes Dialects/ -gen-attrdef-doc)
add_mlir_doc(BuiltinOps BuiltinOps Dialects/ -gen-op-doc)
diff --git a/mlir/include/mlir/IR/Interfaces.td b/mlir/include/mlir/IR/Interfaces.td
index e51bbd5620280..51c5a69fabcd5 100644
--- a/mlir/include/mlir/IR/Interfaces.td
+++ b/mlir/include/mlir/IR/Interfaces.td
@@ -85,6 +85,16 @@ class StaticInterfaceMethod<string desc, string retTy, string methodName,
: InterfaceMethod<desc, retTy, methodName, args, methodBody,
defaultImplementation>;
+// This class represents a pure virtual interface method.
+class PureVirtualInterfaceMethod<string desc, string retTy, string methodName,
+ dag args = (ins)>
+ : InterfaceMethod<desc, retTy, methodName, args>;
+
+// This class represents a interface method declaration.
+class InterfaceMethodDeclaration<string desc, string retTy, string methodName,
+ dag args = (ins)>
+ : InterfaceMethod<desc, retTy, methodName, args>;
+
// Interface represents a base interface.
class Interface<string name, list<Interface> baseInterfacesArg = []> {
// A human-readable description of what this interface does.
@@ -147,9 +157,17 @@ class TypeInterface<string name, list<Interface> baseInterfaces = []>
!if(!empty(cppNamespace),"", cppNamespace # "::") # name
>;
+// AliasDeclaration represents an Alias Declaration in a Dialect Interface
+class AliasDeclaration<string alias, string typeId> {
+ string name = alias;
+ string aliased = typeId;
+}
+
// DialectInterface represents a Dialect Interface.
class DialectInterface<string name, list<Interface> baseInterfaces = []>
- : Interface<name, baseInterfaces>, OpInterfaceTrait<name>;
+ : Interface<name, baseInterfaces>, OpInterfaceTrait<name> {
+ list<AliasDeclaration> aliasDeclarations = [];
+}
// Whether to declare the interface methods in the user entity's header. This
diff --git a/mlir/include/mlir/IR/OpAsmDialectInterface.td b/mlir/include/mlir/IR/OpAsmDialectInterface.td
new file mode 100644
index 0000000000000..892bf6c768be1
--- /dev/null
+++ b/mlir/include/mlir/IR/OpAsmDialectInterface.td
@@ -0,0 +1,78 @@
+#ifndef MLIR_INTERFACES_OPASMDIALECTINTERFACE
+#define MLIR_INTERFACES_OPASMDIALECTINTERFACE
+
+include "mlir/IR/Interfaces.td"
+
+def OpAsmDialectInterface : DialectInterface<"OpAsmDialectInterface"> {
+ let description = [{
+ Dialect OpAsm interface
+ }];
+ let cppNamespace = "::mlir";
+ let aliasDeclarations = [AliasDeclaration<"AliasResult", "OpAsmAliasResult">];
+
+ let methods = [
+ InterfaceMethod<[{
+ Hooks for getting an alias identifier alias for a given symbol, that is
+ not necessarily a part of this dialect. The identifier is used in place of
+ the symbol when printing textual IR. These aliases must not contain `.` or
+ end with a numeric digit([0-9]+).
+ }],
+ "AliasResult", "getAlias",
+ (ins "::mlir::Attribute":$attr, "::llvm::raw_ostream &":$os),
+ [{
+ return AliasResult::NoAlias;
+ }]
+ >,
+ InterfaceMethod<[{}], "AliasResult", "getAlias",
+ (ins "::mlir::Type":$type, "::llvm::raw_ostream &":$os),
+ [{
+ return AliasResult::NoAlias;
+ }]
+ >,
+ InterfaceMethod<[{
+ Declare a resource with the given key, returning a handle to use for any
+ references of this resource key within the IR during parsing. The result
+ of `getResourceKey` on the returned handle is permitted to be different
+ than `key`.
+ }],
+ "::mlir::FailureOr<AsmDialectResourceHandle>", "declareResource",
+ (ins "::mlir::StringRef":$key),
+ [{
+ return failure();
+ }]
+ >,
+ InterfaceMethod<[{
+ Return a key to use for the given resource. This key should uniquely
+ identify this resource within the dialect.
+ }],
+ "std::string", "getResourceKey",
+ (ins "const ::mlir::AsmDialectResourceHandle &":$handle),
+ [{
+ llvm_unreachable(
+ "Dialect must implement `getResourceKey` when defining resources");
+ }]
+ >,
+ InterfaceMethodDeclaration<[{
+ Hook for parsing resource entries. Returns failure if the entry was not
+ valid, or could otherwise not be processed correctly. Any necessary errors
+ can be emitted via the provided entry.
+ }],
+ "::llvm::LogicalResult", "parseResource",
+ (ins "::mlir::AsmParsedResourceEntry &":$entry)
+ >,
+ InterfaceMethod<[{
+ Hook for building resources to use during printing. The given `op` may be
+ inspected to help determine what information to include.
+ `referencedResources` contains all of the resources detected when printing
+ 'op'.
+ }],
+ "void", "buildResources",
+ (ins "::mlir::Operation *":$op,
+ "const ::mlir::SetVector<::mlir::AsmDialectResourceHandle> &":$referencedResources,
+ "::mlir::AsmResourceBuilder &":$builder)
+ >
+ ];
+}
+
+
+#endif
diff --git a/mlir/include/mlir/IR/OpImplementation.h b/mlir/include/mlir/IR/OpImplementation.h
index d70aa346eaa1f..1d2229a402614 100644
--- a/mlir/include/mlir/IR/OpImplementation.h
+++ b/mlir/include/mlir/IR/OpImplementation.h
@@ -1777,64 +1777,6 @@ class OpAsmParser : public AsmParser {
SmallVectorImpl<UnresolvedOperand> &rhs) = 0;
};
-//===--------------------------------------------------------------------===//
-// Dialect OpAsm interface.
-//===--------------------------------------------------------------------===//
-
-class OpAsmDialectInterface
- : public DialectInterface::Base<OpAsmDialectInterface> {
-public:
- OpAsmDialectInterface(Dialect *dialect) : Base(dialect) {}
-
- using AliasResult = OpAsmAliasResult;
-
- /// Hooks for getting an alias identifier alias for a given symbol, that is
- /// not necessarily a part of this dialect. The identifier is used in place of
- /// the symbol when printing textual IR. These aliases must not contain `.` or
- /// end with a numeric digit([0-9]+).
- virtual AliasResult getAlias(Attribute attr, raw_ostream &os) const {
- return AliasResult::NoAlias;
- }
- virtual AliasResult getAlias(Type type, raw_ostream &os) const {
- return AliasResult::NoAlias;
- }
-
- //===--------------------------------------------------------------------===//
- // Resources
- //===--------------------------------------------------------------------===//
-
- /// Declare a resource with the given key, returning a handle to use for any
- /// references of this resource key within the IR during parsing. The result
- /// of `getResourceKey` on the returned handle is permitted to be different
- /// than `key`.
- virtual FailureOr<AsmDialectResourceHandle>
- declareResource(StringRef key) const {
- return failure();
- }
-
- /// Return a key to use for the given resource. This key should uniquely
- /// identify this resource within the dialect.
- virtual std::string
- getResourceKey(const AsmDialectResourceHandle &handle) const {
- llvm_unreachable(
- "Dialect must implement `getResourceKey` when defining resources");
- }
-
- /// Hook for parsing resource entries. Returns failure if the entry was not
- /// valid, or could otherwise not be processed correctly. Any necessary errors
- /// can be emitted via the provided entry.
- virtual LogicalResult parseResource(AsmParsedResourceEntry &entry) const;
-
- /// Hook for building resources to use during printing. The given `op` may be
- /// inspected to help determine what information to include.
- /// `referencedResources` contains all of the resources detected when printing
- /// 'op'.
- virtual void
- buildResources(Operation *op,
- const SetVector<AsmDialectResourceHandle> &referencedResources,
- AsmResourceBuilder &builder) const {}
-};
-
//===--------------------------------------------------------------------===//
// Custom printers and parsers.
//===--------------------------------------------------------------------===//
@@ -1854,6 +1796,13 @@ ParseResult parseDimensionList(OpAsmParser &parser,
/// The OpAsmOpInterface, see OpAsmInterface.td for more details.
#include "mlir/IR/OpAsmOpInterface.h.inc"
+//===--------------------------------------------------------------------===//
+// Dialect OpAsm interface.
+//===--------------------------------------------------------------------===//
+
+/// The OpAsmDialectInterface, see OpAsmDialectInterface.td
+#include "mlir/IR/OpAsmDialectInterface.h.inc"
+
namespace llvm {
template <>
struct DenseMapInfo<mlir::AsmDialectResourceHandle> {
diff --git a/mlir/include/mlir/TableGen/Interfaces.h b/mlir/include/mlir/TableGen/Interfaces.h
index f62d21da467a1..28b2844a91470 100644
--- a/mlir/include/mlir/TableGen/Interfaces.h
+++ b/mlir/include/mlir/TableGen/Interfaces.h
@@ -46,6 +46,12 @@ class InterfaceMethod {
// Return if this method is static.
bool isStatic() const;
+ // Return if the method is a pure virtual one.
+ bool isPureVirtual() const;
+
+ // Return if the method is only a declaration.
+ bool isDeclaration() const;
+
// Return the body for this method if it has one.
std::optional<StringRef> getBody() const;
@@ -161,6 +167,9 @@ struct TypeInterface : public Interface {
struct DialectInterface : public Interface {
using Interface::Interface;
+ // Return alias declarations
+ SmallVector<std::pair<StringRef, StringRef>> getAliasDeclarations() const;
+
static bool classof(const Interface *interface);
};
diff --git a/mlir/lib/IR/CMakeLists.txt b/mlir/lib/IR/CMakeLists.txt
index d95bdc957e3c2..563c8c6285ef3 100644
--- a/mlir/lib/IR/CMakeLists.txt
+++ b/mlir/lib/IR/CMakeLists.txt
@@ -67,6 +67,7 @@ add_mlir_library(MLIRIR
MLIRSideEffectInterfacesIncGen
MLIRSymbolInterfacesIncGen
MLIRTensorEncodingIncGen
+ MLIROpAsmDialectInterfaceIncGen
LINK_LIBS PUBLIC
MLIRSupport
diff --git a/mlir/lib/TableGen/Interfaces.cpp b/mlir/lib/TableGen/Interfaces.cpp
index 77a6cecebbeaf..cc888d921cc4c 100644
--- a/mlir/lib/TableGen/Interfaces.cpp
+++ b/mlir/lib/TableGen/Interfaces.cpp
@@ -11,6 +11,7 @@
#include "llvm/ADT/StringSet.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
+#include <utility>
using namespace mlir;
using namespace mlir::tblgen;
@@ -51,6 +52,16 @@ bool InterfaceMethod::isStatic() const {
return def->isSubClassOf("StaticInterfaceMethod");
}
+// Return if the method is a pure virtual one.
+bool InterfaceMethod::isPureVirtual() const {
+ return def->isSubClassOf("PureVirtualInterfaceMethod");
+}
+
+// Return if the method is only a declaration.
+bool InterfaceMethod::isDeclaration() const {
+ return def->isSubClassOf("InterfaceMethodDeclaration");
+}
+
// Return the body for this method if it has one.
std::optional<StringRef> InterfaceMethod::getBody() const {
// Trim leading and trailing spaces from the default implementation.
@@ -216,3 +227,16 @@ bool TypeInterface::classof(const Interface *interface) {
bool DialectInterface::classof(const Interface *interface) {
return interface->getDef().isSubClassOf("DialectInterface");
}
+
+// Return the interfaces extra class declaration code.
+SmallVector<std::pair<StringRef, StringRef>>
+DialectInterface::getAliasDeclarations() const {
+ SmallVector<std::pair<StringRef, StringRef>, 1> aliasDeclarations;
+
+ for (auto &aliasDef : getDef().getValueAsListOfDefs("aliasDeclarations")) {
+ auto alias = aliasDef->getValueAsString("name");
+ auto typeId = aliasDef->getValueAsString("aliased");
+ aliasDeclarations.push_back(std::make_pair(alias, typeId));
+ }
+ return aliasDeclarations;
+}
diff --git a/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp b/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
index 1d3b24a7aee15..963dd24753c5d 100644
--- a/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
+++ b/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
@@ -26,7 +26,7 @@
using namespace mlir;
using llvm::Record;
using llvm::RecordKeeper;
-using mlir::tblgen::Interface;
+using mlir::tblgen::DialectInterface;
using mlir::tblgen::InterfaceMethod;
/// Emit a string corresponding to a C++ type, followed by a space if necessary.
@@ -74,7 +74,7 @@ class DialectInterfaceGenerator {
bool emitInterfaceDecls();
protected:
- void emitInterfaceDecl(const Interface &interface);
+ void emitInterfaceDecl(const DialectInterface &interface);
/// The set of interface records to emit.
std::vector<const Record *> defs;
@@ -91,9 +91,11 @@ static void emitInterfaceMethodDoc(const InterfaceMethod &method,
raw_ostream &os, StringRef prefix = "") {
if (std::optional<StringRef> description = method.getDescription())
tblgen::emitDescriptionComment(*description, os, prefix);
+ else
+ os << "\n";
}
-static void emitInterfaceMethodsDef(const Interface &interface,
+static void emitInterfaceMethodsDef(const DialectInterface &interface,
raw_ostream &os) {
raw_indented_ostream ios(os);
@@ -104,6 +106,18 @@ static void emitInterfaceMethodsDef(const Interface &interface,
ios << "virtual ";
emitCPPType(method.getReturnType(), ios);
emitMethodNameAndArgs(method, method.getName(), ios);
+
+ if (method.isDeclaration()) {
+ ios << ";\n";
+ continue;
+ }
+
+ if (method.isPureVirtual()) {
+ ios << " = 0;\n";
+ continue;
+ }
+
+ // Otherwise it's a normal interface method
ios << " {";
if (auto body = method.getBody()) {
@@ -116,7 +130,18 @@ static void emitInterfaceMethodsDef(const Interface &interface,
}
}
-void DialectInterfaceGenerator::emitInterfaceDecl(const Interface &interface) {
+static void emitInterfaceAliasDeclarations(const DialectInterface &interface,
+ raw_ostream &os) {
+ raw_indented_ostream ios(os);
+ ios.indent(2);
+
+ for (auto [alias, typeId] : interface.getAliasDeclarations()) {
+ ios << "using " << alias << " = " << typeId << ";\n";
+ }
+}
+
+void DialectInterfaceGenerator::emitInterfaceDecl(
+ const DialectInterface &interface) {
llvm::NamespaceEmitter ns(os, interface.getCppNamespace());
StringRef interfaceName = interface.getName();
@@ -131,6 +156,8 @@ void DialectInterfaceGenerator::emitInterfaceDecl(const Interface &interface) {
" {0}(::mlir::Dialect *dialect) : Base(dialect) {{}\n",
interfaceName);
+ emitInterfaceAliasDeclarations(interface, os);
+
emitInterfaceMethodsDef(interface, os);
os << "};\n";
@@ -148,7 +175,7 @@ bool DialectInterfaceGenerator::emitInterfaceDecls() {
});
for (const Record *def : sortedDefs)
- emitInterfaceDecl(Interface(def));
+ emitInterfaceDecl(DialectInterface(def));
return false;
}
>From 38891edd28f417dafc39b087e4f8dda2211ba77a Mon Sep 17 00:00:00 2001
From: Jacques Pienaar <jacques+gh at japienaar.info>
Date: Thu, 11 Dec 2025 13:27:58 +0000
Subject: [PATCH 2/7] Add corresponding bazel changes
---
utils/bazel/llvm-project-overlay/mlir/BUILD.bazel | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
index 9967aa8e08fd9..82bfd2cb08223 100644
--- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
@@ -111,6 +111,16 @@ gentbl_cc_library(
deps = [":OpBaseTdFiles"],
)
+gentbl_cc_library(
+ name = "OpAsmDialectInterfaceIncGen",
+ tbl_outs = {
+ "include/mlir/IR/OpAsmDialectInterface.h.inc": ["-gen-dialect-interface-decls"],
+ },
+ tblgen = ":mlir-tblgen",
+ td_file = "include/mlir/IR/OpAsmDialectInterface.td",
+ deps = [":OpBaseTdFiles"],
+)
+
gentbl_cc_library(
name = "TensorEncodingIncGen",
tbl_outs = {
@@ -395,6 +405,7 @@ cc_library(
"lib/Bytecode/Writer/*.h",
"include/mlir/Bytecode/*.h",
]) + [
+ "include/mlir/IR/OpAsmDialectInterface.h.inc",
"include/mlir/IR/OpAsmOpInterface.h.inc",
"include/mlir/Interfaces/DataLayoutInterfaces.h",
"include/mlir/Interfaces/InferIntRangeInterface.h",
>From fd498a6ecedfcb2b7a65959c8d99cd0b3704573e Mon Sep 17 00:00:00 2001
From: aidint <at.aidin at gmail.com>
Date: Sat, 13 Dec 2025 01:34:10 +0100
Subject: [PATCH 3/7] change aliasDeclarations to StringMap
---
mlir/include/mlir/IR/Interfaces.td | 4 ++--
mlir/include/mlir/IR/OpAsmDialectInterface.td | 4 ++--
mlir/include/mlir/TableGen/Interfaces.h | 3 ++-
mlir/lib/TableGen/Interfaces.cpp | 6 +++---
mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp | 5 +++--
5 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/mlir/include/mlir/IR/Interfaces.td b/mlir/include/mlir/IR/Interfaces.td
index 51c5a69fabcd5..966854bf5cf29 100644
--- a/mlir/include/mlir/IR/Interfaces.td
+++ b/mlir/include/mlir/IR/Interfaces.td
@@ -157,9 +157,9 @@ class TypeInterface<string name, list<Interface> baseInterfaces = []>
!if(!empty(cppNamespace),"", cppNamespace # "::") # name
>;
-// AliasDeclaration represents an Alias Declaration in a Dialect Interface
+// AliasDeclaration represents an Alias Declaration in a Dialect Interface.
class AliasDeclaration<string alias, string typeId> {
- string name = alias;
+ string name = alias;
string aliased = typeId;
}
diff --git a/mlir/include/mlir/IR/OpAsmDialectInterface.td b/mlir/include/mlir/IR/OpAsmDialectInterface.td
index 892bf6c768be1..d29b94453fe67 100644
--- a/mlir/include/mlir/IR/OpAsmDialectInterface.td
+++ b/mlir/include/mlir/IR/OpAsmDialectInterface.td
@@ -15,7 +15,7 @@ def OpAsmDialectInterface : DialectInterface<"OpAsmDialectInterface"> {
Hooks for getting an alias identifier alias for a given symbol, that is
not necessarily a part of this dialect. The identifier is used in place of
the symbol when printing textual IR. These aliases must not contain `.` or
- end with a numeric digit([0-9]+).
+ end with a numeric digit ([0-9]+).
}],
"AliasResult", "getAlias",
(ins "::mlir::Attribute":$attr, "::llvm::raw_ostream &":$os),
@@ -35,7 +35,7 @@ def OpAsmDialectInterface : DialectInterface<"OpAsmDialectInterface"> {
of `getResourceKey` on the returned handle is permitted to be different
than `key`.
}],
- "::mlir::FailureOr<AsmDialectResourceHandle>", "declareResource",
+ "::mlir::FailureOr<::mlir::AsmDialectResourceHandle>", "declareResource",
(ins "::mlir::StringRef":$key),
[{
return failure();
diff --git a/mlir/include/mlir/TableGen/Interfaces.h b/mlir/include/mlir/TableGen/Interfaces.h
index 28b2844a91470..03b11dc02e4dd 100644
--- a/mlir/include/mlir/TableGen/Interfaces.h
+++ b/mlir/include/mlir/TableGen/Interfaces.h
@@ -11,6 +11,7 @@
#include "mlir/Support/LLVM.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
@@ -168,7 +169,7 @@ struct DialectInterface : public Interface {
using Interface::Interface;
// Return alias declarations
- SmallVector<std::pair<StringRef, StringRef>> getAliasDeclarations() const;
+ llvm::StringMap<StringRef> getAliasDeclarations() const;
static bool classof(const Interface *interface);
};
diff --git a/mlir/lib/TableGen/Interfaces.cpp b/mlir/lib/TableGen/Interfaces.cpp
index cc888d921cc4c..f93ef375131dc 100644
--- a/mlir/lib/TableGen/Interfaces.cpp
+++ b/mlir/lib/TableGen/Interfaces.cpp
@@ -229,14 +229,14 @@ bool DialectInterface::classof(const Interface *interface) {
}
// Return the interfaces extra class declaration code.
-SmallVector<std::pair<StringRef, StringRef>>
+llvm::StringMap<StringRef>
DialectInterface::getAliasDeclarations() const {
- SmallVector<std::pair<StringRef, StringRef>, 1> aliasDeclarations;
+ llvm::StringMap<StringRef> aliasDeclarations;
for (auto &aliasDef : getDef().getValueAsListOfDefs("aliasDeclarations")) {
auto alias = aliasDef->getValueAsString("name");
auto typeId = aliasDef->getValueAsString("aliased");
- aliasDeclarations.push_back(std::make_pair(alias, typeId));
+ aliasDeclarations[alias] = typeId;
}
return aliasDeclarations;
}
diff --git a/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp b/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
index 963dd24753c5d..a2b91c2dd8958 100644
--- a/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
+++ b/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
@@ -135,8 +135,9 @@ static void emitInterfaceAliasDeclarations(const DialectInterface &interface,
raw_indented_ostream ios(os);
ios.indent(2);
- for (auto [alias, typeId] : interface.getAliasDeclarations()) {
- ios << "using " << alias << " = " << typeId << ";\n";
+
+ for (auto &alias : interface.getAliasDeclarations()) {
+ ios << "using " << alias.getKey() << " = " << alias.getValue() << ";\n";
}
}
>From f7651965c734a0ddddf9972f471b3595f608fb5a Mon Sep 17 00:00:00 2001
From: aidint <at.aidin at gmail.com>
Date: Sat, 13 Dec 2025 01:38:17 +0100
Subject: [PATCH 4/7] resolve clang-format issue
---
mlir/lib/TableGen/Interfaces.cpp | 3 +--
mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp | 1 -
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/mlir/lib/TableGen/Interfaces.cpp b/mlir/lib/TableGen/Interfaces.cpp
index f93ef375131dc..e20cdba5f7e0c 100644
--- a/mlir/lib/TableGen/Interfaces.cpp
+++ b/mlir/lib/TableGen/Interfaces.cpp
@@ -229,8 +229,7 @@ bool DialectInterface::classof(const Interface *interface) {
}
// Return the interfaces extra class declaration code.
-llvm::StringMap<StringRef>
-DialectInterface::getAliasDeclarations() const {
+llvm::StringMap<StringRef> DialectInterface::getAliasDeclarations() const {
llvm::StringMap<StringRef> aliasDeclarations;
for (auto &aliasDef : getDef().getValueAsListOfDefs("aliasDeclarations")) {
diff --git a/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp b/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
index a2b91c2dd8958..0c16514179c32 100644
--- a/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
+++ b/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
@@ -135,7 +135,6 @@ static void emitInterfaceAliasDeclarations(const DialectInterface &interface,
raw_indented_ostream ios(os);
ios.indent(2);
-
for (auto &alias : interface.getAliasDeclarations()) {
ios << "using " << alias.getKey() << " = " << alias.getValue() << ";\n";
}
>From d784b8535a055eea0b2b348e68372d44a90f8c39 Mon Sep 17 00:00:00 2001
From: aidint <at.aidin at gmail.com>
Date: Wed, 17 Dec 2025 12:50:58 +0100
Subject: [PATCH 5/7] change to protected constructor for pure virtual methods
---
mlir/test/mlir-tblgen/dialect-interface.td | 53 ++++++++++++++++---
.../mlir-tblgen/DialectInterfacesGen.cpp | 36 ++++++++++---
2 files changed, 77 insertions(+), 12 deletions(-)
diff --git a/mlir/test/mlir-tblgen/dialect-interface.td b/mlir/test/mlir-tblgen/dialect-interface.td
index ff39fd941f300..c24dfe6ed140d 100644
--- a/mlir/test/mlir-tblgen/dialect-interface.td
+++ b/mlir/test/mlir-tblgen/dialect-interface.td
@@ -10,7 +10,7 @@ def NoDefaultMethod : DialectInterface<"NoDefaultMethod"> {
let cppNamespace = "::mlir::example";
let methods = [
- InterfaceMethod<
+ InterfaceMethod<
/*desc=*/ "Check if it's an example dialect",
/*returnType=*/ "bool",
/*methodName=*/ "isExampleDialect",
@@ -28,9 +28,9 @@ def NoDefaultMethod : DialectInterface<"NoDefaultMethod"> {
// DECL: class NoDefaultMethod : public {{.*}}DialectInterface::Base<NoDefaultMethod>
// DECL: public:
-// DECL-NEXT: NoDefaultMethod(::mlir::Dialect *dialect) : Base(dialect) {}
// DECL: virtual bool isExampleDialect() const {}
// DECL: virtual unsigned supportSecondMethod(::mlir::Type type) const {}
+// DECL: NoDefaultMethod(::mlir::Dialect *dialect) : Base(dialect) {}
def WithDefaultMethodInterface : DialectInterface<"WithDefaultMethodInterface"> {
let description = [{
@@ -40,7 +40,7 @@ def WithDefaultMethodInterface : DialectInterface<"WithDefaultMethodInterface">
let cppNamespace = "::mlir::example";
let methods = [
- InterfaceMethod<
+ InterfaceMethod<
/*desc=*/ "Check if it's an example dialect",
/*returnType=*/ "bool",
/*methodName=*/ "isExampleDialect",
@@ -59,7 +59,48 @@ def WithDefaultMethodInterface : DialectInterface<"WithDefaultMethodInterface">
];
}
-// DECL: virtual bool isExampleDialect() const {
-// DECL-NEXT: return true;
-// DECL-NEXT: }
+// DECL: virtual bool isExampleDialect() const {
+// DECL-NEXT: return true;
+// DECL-NEXT: }
+
+def PureVirtualInterface : DialectInterface<"PureVirtualInterface"> {
+ let description = [{
+ This is an example dialect interface with pure virtual methods.
+ }];
+
+ let cppNamespace = "::mlir::example";
+
+ let aliasDeclarations = [
+ AliasDeclaration<"FirstAlias", "unsigned">];
+
+ let methods = [
+ PureVirtualInterfaceMethod<
+ /*desc=*/ "Check if it's an example dialect",
+ /*returnType=*/ "bool",
+ /*methodName=*/ "isExampleDialect",
+ /*args=*/ (ins)
+ >,
+ InterfaceMethod<
+ /*desc=*/ "second method to check if multiple methods supported",
+ /*returnType=*/ "FirstAlias",
+ /*methodName=*/ "supportSecondMethod",
+ /*args=*/ (ins "::mlir::Type":$type)
+ >,
+ InterfaceMethodDeclaration<
+ /*desc=*/ "a method declaration",
+ /*returnType=*/ "::mlir::Type",
+ /*methodName=*/ "exampleMethodDeclaration",
+ /*args=*/ (ins "::mlir::Type":$type)
+ >
+ ];
+}
+
+// DECL: class PureVirtualInterface : public {{.*}}DialectInterface::Base<PureVirtualInterface>
+// DECL: public:
+// DECL: using FirstAlias = unsigned;
+// DECL: virtual bool isExampleDialect() const = 0;
+// DECL: virtual FirstAlias supportSecondMethod(::mlir::Type type) const {}
+// DECL: virtual ::mlir::Type exampleMethodDeclaration(::mlir::Type type) const;
+// DECL: protected:
+// DECL-NEXT: PureVirtualInterface(::mlir::Dialect *dialect) : Base(dialect) {}
diff --git a/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp b/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
index 0c16514179c32..c14ca9e6fe058 100644
--- a/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
+++ b/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
@@ -15,6 +15,8 @@
#include "mlir/Support/IndentedOstream.h"
#include "mlir/TableGen/GenInfo.h"
#include "mlir/TableGen/Interfaces.h"
+#include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
@@ -140,26 +142,48 @@ static void emitInterfaceAliasDeclarations(const DialectInterface &interface,
}
}
+static void emitConstructor(const DialectInterface &interface,
+ raw_ostream &os) {
+
+ raw_indented_ostream ios(os);
+
+ // We consider a constructor protected if interface has at least one pure
+ // virtual method
+ auto hasProtectedConstructor =
+ llvm::any_of(interface.getMethods(), [](const InterfaceMethod &method) {
+ return method.isPureVirtual();
+ });
+
+ ios.indent(0);
+ if (hasProtectedConstructor)
+ ios << "protected:\n";
+
+ ios.indent(2);
+ ios << llvm::formatv("{0}(::mlir::Dialect *dialect) : Base(dialect) {{}\n",
+ interface.getName());
+}
+
void DialectInterfaceGenerator::emitInterfaceDecl(
const DialectInterface &interface) {
llvm::NamespaceEmitter ns(os, interface.getCppNamespace());
- StringRef interfaceName = interface.getName();
-
tblgen::emitSummaryAndDescComments(os, "",
interface.getDescription().value_or(""));
// Emit the main interface class declaration.
os << llvm::formatv(
- "class {0} : public ::mlir::DialectInterface::Base<{0}> {\n"
- "public:\n"
- " {0}(::mlir::Dialect *dialect) : Base(dialect) {{}\n",
- interfaceName);
+ "class {0} : public ::mlir::DialectInterface::Base<{0}> {{\n"
+ "public:\n",
+ interface.getName());
emitInterfaceAliasDeclarations(interface, os);
emitInterfaceMethodsDef(interface, os);
+ os << "\n";
+
+ emitConstructor(interface, os);
+
os << "};\n";
}
>From c5a2c3cb4132509f1a13057b0528076c4b9f3286 Mon Sep 17 00:00:00 2001
From: aidint <at.aidin at gmail.com>
Date: Wed, 17 Dec 2025 12:53:45 +0100
Subject: [PATCH 6/7] resolve clang-format issue
---
mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp b/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
index c14ca9e6fe058..884a5bee15441 100644
--- a/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
+++ b/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
@@ -160,7 +160,7 @@ static void emitConstructor(const DialectInterface &interface,
ios.indent(2);
ios << llvm::formatv("{0}(::mlir::Dialect *dialect) : Base(dialect) {{}\n",
- interface.getName());
+ interface.getName());
}
void DialectInterfaceGenerator::emitInterfaceDecl(
>From 048d3a3fbbdf3e596d7817880919a3774e9350b4 Mon Sep 17 00:00:00 2001
From: aidint <at.aidin at gmail.com>
Date: Thu, 18 Dec 2025 12:15:22 +0100
Subject: [PATCH 7/7] remove pure virtual methods support
---
mlir/include/mlir/TableGen/Interfaces.h | 3 -
mlir/lib/TableGen/Interfaces.cpp | 5 --
mlir/test/mlir-tblgen/dialect-interface.td | 68 +++++--------------
.../mlir-tblgen/DialectInterfacesGen.cpp | 35 +---------
4 files changed, 21 insertions(+), 90 deletions(-)
diff --git a/mlir/include/mlir/TableGen/Interfaces.h b/mlir/include/mlir/TableGen/Interfaces.h
index 03b11dc02e4dd..f70a74fccb0bb 100644
--- a/mlir/include/mlir/TableGen/Interfaces.h
+++ b/mlir/include/mlir/TableGen/Interfaces.h
@@ -47,9 +47,6 @@ class InterfaceMethod {
// Return if this method is static.
bool isStatic() const;
- // Return if the method is a pure virtual one.
- bool isPureVirtual() const;
-
// Return if the method is only a declaration.
bool isDeclaration() const;
diff --git a/mlir/lib/TableGen/Interfaces.cpp b/mlir/lib/TableGen/Interfaces.cpp
index e20cdba5f7e0c..08c0f43213c27 100644
--- a/mlir/lib/TableGen/Interfaces.cpp
+++ b/mlir/lib/TableGen/Interfaces.cpp
@@ -52,11 +52,6 @@ bool InterfaceMethod::isStatic() const {
return def->isSubClassOf("StaticInterfaceMethod");
}
-// Return if the method is a pure virtual one.
-bool InterfaceMethod::isPureVirtual() const {
- return def->isSubClassOf("PureVirtualInterfaceMethod");
-}
-
// Return if the method is only a declaration.
bool InterfaceMethod::isDeclaration() const {
return def->isSubClassOf("InterfaceMethodDeclaration");
diff --git a/mlir/test/mlir-tblgen/dialect-interface.td b/mlir/test/mlir-tblgen/dialect-interface.td
index c24dfe6ed140d..f11fbb26d40cc 100644
--- a/mlir/test/mlir-tblgen/dialect-interface.td
+++ b/mlir/test/mlir-tblgen/dialect-interface.td
@@ -10,27 +10,21 @@ def NoDefaultMethod : DialectInterface<"NoDefaultMethod"> {
let cppNamespace = "::mlir::example";
let methods = [
- InterfaceMethod<
- /*desc=*/ "Check if it's an example dialect",
- /*returnType=*/ "bool",
- /*methodName=*/ "isExampleDialect",
- /*args=*/ (ins)
- >,
- InterfaceMethod<
- /*desc=*/ "second method to check if multiple methods supported",
- /*returnType=*/ "unsigned",
- /*methodName=*/ "supportSecondMethod",
- /*args=*/ (ins "::mlir::Type":$type)
+ InterfaceMethod<
+ "Check if it's an example dialect", "bool", "isExampleDialect", (ins)
+ >,
+ InterfaceMethod<
+ "second method to check if multiple methods supported",
+ "unsigned", "supportSecondMethod", (ins "::mlir::Type":$type)
>
-
];
}
// DECL: class NoDefaultMethod : public {{.*}}DialectInterface::Base<NoDefaultMethod>
// DECL: public:
+/// DECL: NoDefaultMethod(::mlir::Dialect *dialect) : Base(dialect) {}
// DECL: virtual bool isExampleDialect() const {}
// DECL: virtual unsigned supportSecondMethod(::mlir::Type type) const {}
-// DECL: NoDefaultMethod(::mlir::Dialect *dialect) : Base(dialect) {}
def WithDefaultMethodInterface : DialectInterface<"WithDefaultMethodInterface"> {
let description = [{
@@ -41,21 +35,15 @@ def WithDefaultMethodInterface : DialectInterface<"WithDefaultMethodInterface">
let methods = [
InterfaceMethod<
- /*desc=*/ "Check if it's an example dialect",
- /*returnType=*/ "bool",
- /*methodName=*/ "isExampleDialect",
- /*args=*/ (ins),
- /*methodBody=*/ [{
+ "Check if it's an example dialect", "bool", "isExampleDialect", (ins),
+ [{
return true;
- }]
+ }]
>,
InterfaceMethod<
- /*desc=*/ "second method to check if multiple methods supported",
- /*returnType=*/ "unsigned",
- /*methodName=*/ "supportSecondMethod",
- /*args=*/ (ins "::mlir::Type":$type)
+ "second method to check if multiple methods supported",
+ "unsigned", "supportSecondMethod", (ins "::mlir::Type":$type)
>
-
];
}
@@ -63,9 +51,9 @@ def WithDefaultMethodInterface : DialectInterface<"WithDefaultMethodInterface">
// DECL-NEXT: return true;
// DECL-NEXT: }
-def PureVirtualInterface : DialectInterface<"PureVirtualInterface"> {
+def OnlyDeclarationInterface : DialectInterface<"OnlyDeclarationInterface"> {
let description = [{
- This is an example dialect interface with pure virtual methods.
+ This is an example dialect interface with only declarations.
}];
let cppNamespace = "::mlir::example";
@@ -74,33 +62,13 @@ def PureVirtualInterface : DialectInterface<"PureVirtualInterface"> {
AliasDeclaration<"FirstAlias", "unsigned">];
let methods = [
- PureVirtualInterfaceMethod<
- /*desc=*/ "Check if it's an example dialect",
- /*returnType=*/ "bool",
- /*methodName=*/ "isExampleDialect",
- /*args=*/ (ins)
- >,
- InterfaceMethod<
- /*desc=*/ "second method to check if multiple methods supported",
- /*returnType=*/ "FirstAlias",
- /*methodName=*/ "supportSecondMethod",
- /*args=*/ (ins "::mlir::Type":$type)
- >,
InterfaceMethodDeclaration<
- /*desc=*/ "a method declaration",
- /*returnType=*/ "::mlir::Type",
- /*methodName=*/ "exampleMethodDeclaration",
- /*args=*/ (ins "::mlir::Type":$type)
+ "a method declaration", "FirstAlias", "exampleMethodDeclaration",
+ (ins "::mlir::Type":$type)
>
];
}
-// DECL: class PureVirtualInterface : public {{.*}}DialectInterface::Base<PureVirtualInterface>
-// DECL: public:
+// DECL: class OnlyDeclarationInterface : public {{.*}}DialectInterface::Base<OnlyDeclarationInterface>
// DECL: using FirstAlias = unsigned;
-// DECL: virtual bool isExampleDialect() const = 0;
-// DECL: virtual FirstAlias supportSecondMethod(::mlir::Type type) const {}
-// DECL: virtual ::mlir::Type exampleMethodDeclaration(::mlir::Type type) const;
-// DECL: protected:
-// DECL-NEXT: PureVirtualInterface(::mlir::Dialect *dialect) : Base(dialect) {}
-
+// DECL: virtual FirstAlias exampleMethodDeclaration(::mlir::Type type) const;
diff --git a/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp b/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
index 884a5bee15441..91006f135f10d 100644
--- a/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
+++ b/mlir/tools/mlir-tblgen/DialectInterfacesGen.cpp
@@ -114,11 +114,6 @@ static void emitInterfaceMethodsDef(const DialectInterface &interface,
continue;
}
- if (method.isPureVirtual()) {
- ios << " = 0;\n";
- continue;
- }
-
// Otherwise it's a normal interface method
ios << " {";
@@ -142,27 +137,6 @@ static void emitInterfaceAliasDeclarations(const DialectInterface &interface,
}
}
-static void emitConstructor(const DialectInterface &interface,
- raw_ostream &os) {
-
- raw_indented_ostream ios(os);
-
- // We consider a constructor protected if interface has at least one pure
- // virtual method
- auto hasProtectedConstructor =
- llvm::any_of(interface.getMethods(), [](const InterfaceMethod &method) {
- return method.isPureVirtual();
- });
-
- ios.indent(0);
- if (hasProtectedConstructor)
- ios << "protected:\n";
-
- ios.indent(2);
- ios << llvm::formatv("{0}(::mlir::Dialect *dialect) : Base(dialect) {{}\n",
- interface.getName());
-}
-
void DialectInterfaceGenerator::emitInterfaceDecl(
const DialectInterface &interface) {
llvm::NamespaceEmitter ns(os, interface.getCppNamespace());
@@ -172,18 +146,15 @@ void DialectInterfaceGenerator::emitInterfaceDecl(
// Emit the main interface class declaration.
os << llvm::formatv(
- "class {0} : public ::mlir::DialectInterface::Base<{0}> {{\n"
- "public:\n",
+ "class {0} : public ::mlir::DialectInterface::Base<{0}> {\n"
+ "public:\n"
+ " {0}(::mlir::Dialect *dialect) : Base(dialect) {{}\n",
interface.getName());
emitInterfaceAliasDeclarations(interface, os);
emitInterfaceMethodsDef(interface, os);
- os << "\n";
-
- emitConstructor(interface, os);
-
os << "};\n";
}
More information about the llvm-commits
mailing list