[Mlir-commits] [mlir] [mlir][ODS] Share generated legacy property splitting (NFC) (PR #226085)
Mehdi Amini
llvmlistbot at llvm.org
Thu Sep 24 14:52:33 PDT 2026
https://github.com/joker-eph updated https://github.com/llvm/llvm-project/pull/226085
>From 113c9238771a43dfac490348817dbc904a4bd84a Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Wed, 23 Sep 2026 17:03:41 -0700
Subject: [PATCH] [mlir][ODS] Share generated legacy property splitting
Route generated legacy builder attributes through an out-of-line helper that
partitions inherent and discardable attributes before converting properties.
This avoids compiling the same loop and error path for every operation.
Assisted-by: Codex
---
mlir/include/mlir/IR/OperationSupport.h | 8 ++++
mlir/lib/IR/OperationSupport.cpp | 20 ++++++++++
mlir/test/mlir-tblgen/op-decl-and-defs.td | 8 ++--
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp | 43 ++++++++-------------
4 files changed, 48 insertions(+), 31 deletions(-)
diff --git a/mlir/include/mlir/IR/OperationSupport.h b/mlir/include/mlir/IR/OperationSupport.h
index 0a38631fdce03e..991d9847672e2e 100644
--- a/mlir/include/mlir/IR/OperationSupport.h
+++ b/mlir/include/mlir/IR/OperationSupport.h
@@ -69,6 +69,14 @@ namespace detail {
void appendAttributeProperty(llvm::SmallVectorImpl<NamedAttribute> &attrs,
StringRef name, Attribute attr);
+/// Route legacy builder attributes to either the operation's properties or
+/// its discardable attribute dictionary. The callback handles conversion and
+/// diagnostics for the operation-specific properties.
+void splitPropertiesAndDiscardableAttributes(
+ OperationState &state, ArrayRef<NamedAttribute> attributes,
+ ArrayRef<StringRef> inherentNames,
+ llvm::function_ref<LogicalResult(DictionaryAttr)> setProperties);
+
/// Assign a generated attribute-backed property after checking its type.
/// Keep the conversion out of each operation's generated property setter.
template <typename AttrT>
diff --git a/mlir/lib/IR/OperationSupport.cpp b/mlir/lib/IR/OperationSupport.cpp
index 5b8eeb4f789a86..545791df641fef 100644
--- a/mlir/lib/IR/OperationSupport.cpp
+++ b/mlir/lib/IR/OperationSupport.cpp
@@ -16,6 +16,7 @@
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/OpImplementation.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/SHA1.h"
#include <numeric>
#include <optional>
@@ -54,6 +55,25 @@ ParseResult mlir::detail::parseOptionalTypeInto(AsmParser &parser,
return success();
}
+void mlir::detail::splitPropertiesAndDiscardableAttributes(
+ OperationState &state, ArrayRef<NamedAttribute> attributes,
+ ArrayRef<StringRef> inherentNames,
+ llvm::function_ref<LogicalResult(DictionaryAttr)> setProperties) {
+ SmallVector<NamedAttribute> inherentAttributes;
+ for (const NamedAttribute &attr : attributes) {
+ StringRef name = attr.getName().getValue();
+ if (llvm::is_contained(inherentNames, name))
+ inherentAttributes.push_back(attr);
+ else
+ state.addAttribute(attr.getName(), attr.getValue());
+ }
+ if (inherentAttributes.empty())
+ return;
+ if (failed(setProperties(
+ DictionaryAttr::get(state.getContext(), inherentAttributes))))
+ llvm::report_fatal_error("Property conversion failed.");
+}
+
//===----------------------------------------------------------------------===//
// NamedAttrList
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/mlir-tblgen/op-decl-and-defs.td b/mlir/test/mlir-tblgen/op-decl-and-defs.td
index bcc81cd74d9768..36b8ebc78bf596 100644
--- a/mlir/test/mlir-tblgen/op-decl-and-defs.td
+++ b/mlir/test/mlir-tblgen/op-decl-and-defs.td
@@ -169,10 +169,10 @@ def NS_AOp : NS_Op<"a_op", [IsolatedFromAbove, IsolatedFromAbove]> {
// DEFS-LABEL: void AOp::buildPropertiesAndDiscardableAttributes
// DEFS: Properties &properties = odsState.getOrAddProperties<Properties>();
// DEFS-NEXT: populateDefaultProperties(odsState.name, properties);
-// DEFS: if (name == "attr1" || name == "some_attr2")
-// DEFS: inherentAttributes.push_back(attr);
-// DEFS: odsState.addAttribute(attr.getName(), attr.getValue());
-// DEFS: if (::mlir::failed(setPropertiesFromAttr(
+// DEFS: const ::llvm::StringRef inherentNames[] = {"attr1", "some_attr2"};
+// DEFS: ::mlir::detail::splitPropertiesAndDiscardableAttributes(
+// DEFS: return setPropertiesFromAttr(properties, inherentAttrs,
+
// Check that `getAttrDictionary()` is used when not using properties.
diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
index f963d706301365..07070ab91387ce 100644
--- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
@@ -2587,33 +2587,22 @@ void OpEmitter::genLegacyPropertiesBuilderHelper() {
MethodBody &body = method->body();
body << " Properties &properties = " << builderOpStateProperties << ";\n"
<< " populateDefaultProperties(" << builderOpState
- << ".name, properties);\n"
- << " ::llvm::SmallVector<::mlir::NamedAttribute> "
- "inherentAttributes;\n"
- << " for (const ::mlir::NamedAttribute &attr : attributes) {\n"
- << " ::llvm::StringRef name = attr.getName().getValue();\n"
- << " if (";
- llvm::interleave(
- inherentNames,
- [&](StringRef name) { body << "name == \"" << name << "\""; },
- [&] { body << " || "; });
- body << ")\n"
- << " inherentAttributes.push_back(attr);\n"
- << " else\n"
- << " " << builderOpState << ".addAttribute(attr.getName(), "
- << "attr.getValue());\n"
- << " }\n"
- << " if (inherentAttributes.empty())\n"
- << " return;\n";
- // TODO: Use `PropertyKind<T>::unfreeze` to populate properties directly once
- // it is available systematically, avoiding the DictionaryAttr conversion.
- body << " if (::mlir::failed(setPropertiesFromAttr(\n"
- << " properties,\n"
- << " ::mlir::DictionaryAttr::get(" << builderOpState
- << ".getContext(), inherentAttributes),\n"
- << " [&]() { return ::mlir::emitError(" << builderOpState
- << ".location); })))\n"
- << " ::llvm::report_fatal_error(\"Property conversion failed.\");\n";
+ << ".name, properties);\n";
+ if (!inherentNames.empty()) {
+ body << " const ::llvm::StringRef inherentNames[] = {";
+ llvm::interleaveComma(inherentNames, body,
+ [&](StringRef name) { body << '"' << name << '"'; });
+ body << "};\n";
+ }
+ body << " ::mlir::detail::splitPropertiesAndDiscardableAttributes(\n"
+ << " " << builderOpState << ", attributes, "
+ << (inherentNames.empty() ? "::llvm::ArrayRef<::llvm::StringRef>{}"
+ : "inherentNames")
+ << ", [&](::mlir::DictionaryAttr inherentAttrs) {\n"
+ << " return setPropertiesFromAttr(properties, inherentAttrs,\n"
+ << " [&]() { return ::mlir::emitError(" << builderOpState
+ << ".location); });\n"
+ << " });\n";
}
void OpEmitter::genCodeForAddingPropertiesAndAttributes(
More information about the Mlir-commits
mailing list