[Mlir-commits] [mlir] [MLIR][Python] Remove partial LLVM APIs in python bindings (3/n) (PR #178984)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Feb 2 08:26:55 PST 2026
https://github.com/RattataKing updated https://github.com/llvm/llvm-project/pull/178984
>From c464c34a1362ea0232572a33719d298bdcc536ce Mon Sep 17 00:00:00 2001
From: Amily Wu <amilywu2 at amd.com>
Date: Fri, 30 Jan 2026 18:57:34 +0000
Subject: [PATCH 1/9] Remove stringRef
---
mlir/include/mlir/Bindings/Python/Globals.h | 7 ++++---
mlir/lib/Bindings/Python/Globals.cpp | 12 ++++++------
2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/mlir/include/mlir/Bindings/Python/Globals.h b/mlir/include/mlir/Bindings/Python/Globals.h
index 6a722575c4e48..42c38f020d7b5 100644
--- a/mlir/include/mlir/Bindings/Python/Globals.h
+++ b/mlir/include/mlir/Bindings/Python/Globals.h
@@ -12,6 +12,7 @@
#include <optional>
#include <regex>
#include <string>
+#include <string_view>
#include <unordered_set>
#include <vector>
@@ -60,7 +61,7 @@ class MLIR_PYTHON_API_EXPORTED PyGlobals {
/// Note that this returns void because it is expected that the module
/// contains calls to decorators and helpers that register the salient
/// entities. Returns true if dialect is successfully loaded.
- bool loadDialectModule(llvm::StringRef dialectNamespace);
+ bool loadDialectModule(std::string_view dialectNamespace);
/// Adds a user-friendly Attribute builder.
/// Raises an exception if the mapping already exists and replace == false.
@@ -121,7 +122,7 @@ class MLIR_PYTHON_API_EXPORTED PyGlobals {
/// name. Note that this may trigger a load of the dialect, which can
/// arbitrarily re-enter.
std::optional<nanobind::object>
- lookupOperationClass(llvm::StringRef operationName);
+ lookupOperationClass(std::string_view operationName);
/// Looks up a registered operation adaptor class by operation
/// name. Note that this may trigger a load of the dialect, which can
@@ -143,7 +144,7 @@ class MLIR_PYTHON_API_EXPORTED PyGlobals {
void registerTracebackFileExclusion(const std::string &file);
- bool isUserTracebackFilename(llvm::StringRef file);
+ bool isUserTracebackFilename(std::string_view file);
static constexpr size_t kMaxFrames = 512;
diff --git a/mlir/lib/Bindings/Python/Globals.cpp b/mlir/lib/Bindings/Python/Globals.cpp
index 3d7ee3d30656e..5c1c767e95b4d 100644
--- a/mlir/lib/Bindings/Python/Globals.cpp
+++ b/mlir/lib/Bindings/Python/Globals.cpp
@@ -46,7 +46,7 @@ PyGlobals &PyGlobals::get() {
return *instance;
}
-bool PyGlobals::loadDialectModule(llvm::StringRef dialectNamespace) {
+bool PyGlobals::loadDialectModule(std::string_view dialectNamespace) {
{
nb::ft_lock_guard lock(mutex);
if (loadedDialectModules.contains(dialectNamespace))
@@ -202,10 +202,10 @@ PyGlobals::lookupDialectClass(const std::string &dialectNamespace) {
}
std::optional<nb::object>
-PyGlobals::lookupOperationClass(llvm::StringRef operationName) {
+PyGlobals::lookupOperationClass(std::string_view operationName) {
// Make sure dialect module is loaded.
- auto split = operationName.split('.');
- llvm::StringRef dialectNamespace = split.first;
+ size_t splitPos = operationName.find('.');
+ std::string_view dialectNamespace = operationName.substr(0, splitPos);
if (!loadDialectModule(dialectNamespace))
return std::nullopt;
@@ -282,7 +282,7 @@ void PyGlobals::TracebackLoc::registerTracebackFileExclusion(
}
bool PyGlobals::TracebackLoc::isUserTracebackFilename(
- const llvm::StringRef file) {
+ const std::string_view file) {
nanobind::ft_lock_guard lock(mutex);
if (rebuildUserTracebackIncludeRegex) {
userTracebackIncludeRegex.assign(
@@ -297,7 +297,7 @@ bool PyGlobals::TracebackLoc::isUserTracebackFilename(
isUserTracebackFilenameCache.clear();
}
if (!isUserTracebackFilenameCache.contains(file)) {
- std::string fileStr = file.str();
+ std::string fileStr(file);
bool include = std::regex_search(fileStr, userTracebackIncludeRegex);
bool exclude = std::regex_search(fileStr, userTracebackExcludeRegex);
isUserTracebackFilenameCache[file] = include || !exclude;
>From fb173d0039e822a22b33771d10b43ee0ae4bb921 Mon Sep 17 00:00:00 2001
From: Amily Wu <amilywu2 at amd.com>
Date: Fri, 30 Jan 2026 19:34:19 +0000
Subject: [PATCH 2/9] Replace raw_string_ostream
---
mlir/include/mlir/Bindings/Python/Diagnostics.h | 15 +++++++++------
mlir/lib/Bindings/Python/DialectLLVM.cpp | 3 +--
2 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/mlir/include/mlir/Bindings/Python/Diagnostics.h b/mlir/include/mlir/Bindings/Python/Diagnostics.h
index 167002d561931..e30bbd639aade 100644
--- a/mlir/include/mlir/Bindings/Python/Diagnostics.h
+++ b/mlir/include/mlir/Bindings/Python/Diagnostics.h
@@ -11,10 +11,10 @@
#include "mlir-c/Diagnostics.h"
#include "mlir-c/IR.h"
-#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdint>
+#include <sstream>
#include <string>
namespace mlir {
@@ -35,6 +35,9 @@ class CollectDiagnosticsToStringScope {
}
[[nodiscard]] std::string takeMessage() {
+ message = messageStream.str();
+ messageStream.str("");
+ messageStream.clear();
std::string newMessage;
std::swap(message, newMessage);
return newMessage;
@@ -43,16 +46,16 @@ class CollectDiagnosticsToStringScope {
private:
static MlirLogicalResult handler(MlirDiagnostic diag, void *data) {
auto printer = +[](MlirStringRef message, void *data) {
- *static_cast<llvm::raw_string_ostream *>(data)
+ *static_cast<std::ostringstream *>(data)
<< std::string_view(message.data, message.length);
};
MlirLocation loc = mlirDiagnosticGetLocation(diag);
- *static_cast<llvm::raw_string_ostream *>(data) << "at ";
+ *static_cast<std::ostringstream *>(data) << "at ";
mlirLocationPrint(loc, printer, data);
- *static_cast<llvm::raw_string_ostream *>(data) << ": ";
+ *static_cast<std::ostringstream *>(data) << ": ";
mlirDiagnosticPrint(diag, printer, data);
for (intptr_t i = 0; i < mlirDiagnosticGetNumNotes(diag); i++) {
- *static_cast<llvm::raw_string_ostream *>(data) << "\n";
+ *static_cast<std::ostringstream *>(data) << "\n";
MlirDiagnostic note = mlirDiagnosticGetNote(diag, i);
handler(note, data);
}
@@ -63,7 +66,7 @@ class CollectDiagnosticsToStringScope {
MlirDiagnosticHandlerID handlerID;
std::string message;
- llvm::raw_string_ostream messageStream{message};
+ std::ostringstream messageStream;
};
} // namespace python
diff --git a/mlir/lib/Bindings/Python/DialectLLVM.cpp b/mlir/lib/Bindings/Python/DialectLLVM.cpp
index 0c579cf261eca..dc06d0a3bf671 100644
--- a/mlir/lib/Bindings/Python/DialectLLVM.cpp
+++ b/mlir/lib/Bindings/Python/DialectLLVM.cpp
@@ -20,7 +20,6 @@
namespace nb = nanobind;
using namespace nanobind::literals;
-using namespace llvm;
using namespace mlir;
using namespace mlir::python::nanobind_adaptors;
@@ -135,7 +134,7 @@ struct StructType : PyConcreteType<StructType> {
return std::nullopt;
MlirStringRef stringRef = mlirLLVMStructTypeGetIdentifier(type);
- return StringRef(stringRef.data, stringRef.length).str();
+ return std::string(stringRef.data, stringRef.length);
});
c.def_prop_ro("body", [](const StructType &type) -> nb::object {
>From 6be3f2b9e7b936e924f93bd1500af2b253dd7670 Mon Sep 17 00:00:00 2001
From: Amily Wu <amilywu2 at amd.com>
Date: Fri, 30 Jan 2026 20:13:43 +0000
Subject: [PATCH 3/9] Replace densemap
---
mlir/include/mlir/Bindings/Python/Globals.h | 22 ++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/mlir/include/mlir/Bindings/Python/Globals.h b/mlir/include/mlir/Bindings/Python/Globals.h
index 42c38f020d7b5..aaf747e183207 100644
--- a/mlir/include/mlir/Bindings/Python/Globals.h
+++ b/mlir/include/mlir/Bindings/Python/Globals.h
@@ -13,6 +13,7 @@
#include <regex>
#include <string>
#include <string_view>
+#include <unordered_map>
#include <unordered_set>
#include <vector>
@@ -21,7 +22,6 @@
#include "mlir/Bindings/Python/NanobindUtils.h"
#include "mlir/CAPI/Support.h"
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
@@ -30,6 +30,18 @@
namespace mlir {
namespace python {
namespace MLIR_BINDINGS_PYTHON_DOMAIN {
+struct MlirTypeIDHash {
+ size_t operator()(MlirTypeID typeID) const {
+ return mlirTypeIDHashValue(typeID);
+ }
+};
+
+struct MlirTypeIDEqual {
+ bool operator()(MlirTypeID lhs, MlirTypeID rhs) const {
+ return mlirTypeIDEqual(lhs, rhs);
+ }
+};
+
/// Globals that are always accessible once the extension has been initialized.
/// Methods of this class are thread-safe.
class MLIR_PYTHON_API_EXPORTED PyGlobals {
@@ -202,9 +214,13 @@ class MLIR_PYTHON_API_EXPORTED PyGlobals {
/// Map of attribute ODS name to custom builder.
llvm::StringMap<nanobind::callable> attributeBuilderMap;
/// Map of MlirTypeID to custom type caster.
- llvm::DenseMap<MlirTypeID, nanobind::callable> typeCasterMap;
+ std::unordered_map<MlirTypeID, nanobind::callable, MlirTypeIDHash,
+ MlirTypeIDEqual>
+ typeCasterMap;
/// Map of MlirTypeID to custom value caster.
- llvm::DenseMap<MlirTypeID, nanobind::callable> valueCasterMap;
+ std::unordered_map<MlirTypeID, nanobind::callable, MlirTypeIDHash,
+ MlirTypeIDEqual>
+ valueCasterMap;
/// Set of dialect namespaces that we have attempted to import implementation
/// modules for.
llvm::StringSet<> loadedDialectModules;
>From ed5d2016e141a81cd77d7246d9a79c9a9e8fc9c8 Mon Sep 17 00:00:00 2001
From: Amily Wu <amilywu2 at amd.com>
Date: Fri, 30 Jan 2026 21:02:15 +0000
Subject: [PATCH 4/9] Replace stringmap
---
mlir/include/mlir/Bindings/Python/Globals.h | 10 +++++-----
mlir/lib/Bindings/Python/Globals.cpp | 15 +++++++++------
2 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/mlir/include/mlir/Bindings/Python/Globals.h b/mlir/include/mlir/Bindings/Python/Globals.h
index aaf747e183207..c51652f708725 100644
--- a/mlir/include/mlir/Bindings/Python/Globals.h
+++ b/mlir/include/mlir/Bindings/Python/Globals.h
@@ -170,7 +170,7 @@ class MLIR_PYTHON_API_EXPORTED PyGlobals {
bool rebuildUserTracebackIncludeRegex = false;
std::regex userTracebackExcludeRegex;
bool rebuildUserTracebackExcludeRegex = false;
- llvm::StringMap<bool> isUserTracebackFilenameCache;
+ std::unordered_map<std::string, bool> isUserTracebackFilenameCache;
};
TracebackLoc &getTracebackLoc() { return tracebackLoc; }
@@ -206,13 +206,13 @@ class MLIR_PYTHON_API_EXPORTED PyGlobals {
/// Module name prefixes to search under for dialect implementation modules.
std::vector<std::string> dialectSearchPrefixes;
/// Map of dialect namespace to external dialect class object.
- llvm::StringMap<nanobind::object> dialectClassMap;
+ std::unordered_map<std::string, nanobind::object> dialectClassMap;
/// Map of full operation name to external operation class object.
- llvm::StringMap<nanobind::object> operationClassMap;
+ std::unordered_map<std::string, nanobind::object> operationClassMap;
/// Map of full operation name to external operation adaptor class object.
- llvm::StringMap<nanobind::object> opAdaptorClassMap;
+ std::unordered_map<std::string, nanobind::object> opAdaptorClassMap;
/// Map of attribute ODS name to custom builder.
- llvm::StringMap<nanobind::callable> attributeBuilderMap;
+ std::unordered_map<std::string, nanobind::callable> attributeBuilderMap;
/// Map of MlirTypeID to custom type caster.
std::unordered_map<MlirTypeID, nanobind::callable, MlirTypeIDHash,
MlirTypeIDEqual>
diff --git a/mlir/lib/Bindings/Python/Globals.cpp b/mlir/lib/Bindings/Python/Globals.cpp
index 5c1c767e95b4d..58586ddf576c2 100644
--- a/mlir/lib/Bindings/Python/Globals.cpp
+++ b/mlir/lib/Bindings/Python/Globals.cpp
@@ -210,7 +210,8 @@ PyGlobals::lookupOperationClass(std::string_view operationName) {
return std::nullopt;
nb::ft_lock_guard lock(mutex);
- auto foundIt = operationClassMap.find(operationName);
+ std::string operationNameStr(operationName);
+ auto foundIt = operationClassMap.find(operationNameStr);
if (foundIt != operationClassMap.end()) {
assert(foundIt->second && "OpView is defined");
return foundIt->second;
@@ -228,7 +229,8 @@ PyGlobals::lookupOpAdaptorClass(llvm::StringRef operationName) {
return std::nullopt;
nb::ft_lock_guard lock(mutex);
- auto foundIt = opAdaptorClassMap.find(operationName);
+ std::string operationNameStr(operationName);
+ auto foundIt = opAdaptorClassMap.find(operationNameStr);
if (foundIt != opAdaptorClassMap.end()) {
assert(foundIt->second && "OpAdaptor is defined");
return foundIt->second;
@@ -296,13 +298,14 @@ bool PyGlobals::TracebackLoc::isUserTracebackFilename(
rebuildUserTracebackExcludeRegex = false;
isUserTracebackFilenameCache.clear();
}
- if (!isUserTracebackFilenameCache.contains(file)) {
- std::string fileStr(file);
+ std::string fileStr(file);
+ const auto foundIt = isUserTracebackFilenameCache.find(fileStr);
+ if (foundIt == isUserTracebackFilenameCache.end()) {
bool include = std::regex_search(fileStr, userTracebackIncludeRegex);
bool exclude = std::regex_search(fileStr, userTracebackExcludeRegex);
- isUserTracebackFilenameCache[file] = include || !exclude;
+ isUserTracebackFilenameCache[fileStr] = include || !exclude;
}
- return isUserTracebackFilenameCache[file];
+ return isUserTracebackFilenameCache[fileStr];
}
} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
} // namespace python
>From c43d9f8cb9a0f438f2517f27ebb641d9e8edaa1f Mon Sep 17 00:00:00 2001
From: Amily Wu <amilywu2 at amd.com>
Date: Fri, 30 Jan 2026 21:05:30 +0000
Subject: [PATCH 5/9] Replace stringset
---
mlir/include/mlir/Bindings/Python/Globals.h | 3 +--
mlir/lib/Bindings/Python/Globals.cpp | 6 ++++--
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/mlir/include/mlir/Bindings/Python/Globals.h b/mlir/include/mlir/Bindings/Python/Globals.h
index c51652f708725..fa1eb0bc13d20 100644
--- a/mlir/include/mlir/Bindings/Python/Globals.h
+++ b/mlir/include/mlir/Bindings/Python/Globals.h
@@ -24,7 +24,6 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Regex.h"
namespace mlir {
@@ -223,7 +222,7 @@ class MLIR_PYTHON_API_EXPORTED PyGlobals {
valueCasterMap;
/// Set of dialect namespaces that we have attempted to import implementation
/// modules for.
- llvm::StringSet<> loadedDialectModules;
+ std::unordered_set<std::string> loadedDialectModules;
TracebackLoc tracebackLoc;
TypeIDAllocator typeIDAllocator;
diff --git a/mlir/lib/Bindings/Python/Globals.cpp b/mlir/lib/Bindings/Python/Globals.cpp
index 58586ddf576c2..2838e74823d83 100644
--- a/mlir/lib/Bindings/Python/Globals.cpp
+++ b/mlir/lib/Bindings/Python/Globals.cpp
@@ -49,7 +49,9 @@ PyGlobals &PyGlobals::get() {
bool PyGlobals::loadDialectModule(std::string_view dialectNamespace) {
{
nb::ft_lock_guard lock(mutex);
- if (loadedDialectModules.contains(dialectNamespace))
+ std::string dialectNamespaceStr(dialectNamespace);
+ if (loadedDialectModules.find(dialectNamespaceStr) !=
+ loadedDialectModules.end())
return true;
}
// Since re-entrancy is possible, make a copy of the search prefixes.
@@ -75,7 +77,7 @@ bool PyGlobals::loadDialectModule(std::string_view dialectNamespace) {
// Note: Iterator cannot be shared from prior to loading, since re-entrancy
// may have occurred, which may do anything.
nb::ft_lock_guard lock(mutex);
- loadedDialectModules.insert(dialectNamespace);
+ loadedDialectModules.insert(std::string(dialectNamespace));
return true;
}
>From 88e1129cc079ca58ee20565f95ff7e1c09841aa0 Mon Sep 17 00:00:00 2001
From: Amily Wu <amilywu2 at amd.com>
Date: Fri, 30 Jan 2026 21:34:17 +0000
Subject: [PATCH 6/9] Replace raw_fd_ostream
---
.../mlir/Bindings/Python/NanobindUtils.h | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/mlir/include/mlir/Bindings/Python/NanobindUtils.h b/mlir/include/mlir/Bindings/Python/NanobindUtils.h
index 215daf245b902..71a5c4515920a 100644
--- a/mlir/include/mlir/Bindings/Python/NanobindUtils.h
+++ b/mlir/include/mlir/Bindings/Python/NanobindUtils.h
@@ -16,8 +16,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/raw_ostream.h"
-
+#include <fstream>
#include <string>
#include <typeinfo>
#include <variant>
@@ -142,11 +141,14 @@ class PyFileAccumulator {
: binary(binary) {
std::string filePath;
if (nanobind::try_cast<std::string>(fileOrStringObject, filePath)) {
- std::error_code ec;
- writeTarget.emplace<llvm::raw_fd_ostream>(filePath, ec);
- if (ec) {
+ std::ios::openmode openMode = std::ios::out;
+ if (binary)
+ openMode |= std::ios::binary;
+ writeTarget.emplace<std::ofstream>(filePath, openMode);
+ auto &stream = std::get<std::ofstream>(writeTarget);
+ if (!stream) {
throw nanobind::value_error(
- (std::string("Unable to open file for writing: ") + ec.message())
+ (std::string("Unable to open file for writing: ") + filePath)
.c_str());
}
} else {
@@ -181,12 +183,11 @@ class PyFileAccumulator {
MlirStringCallback getOstreamCallback() {
return [](MlirStringRef part, void *userData) {
PyFileAccumulator *accum = static_cast<PyFileAccumulator *>(userData);
- std::get<llvm::raw_fd_ostream>(accum->writeTarget)
- .write(part.data, part.length);
+ std::get<std::ofstream>(accum->writeTarget).write(part.data, part.length);
};
}
- std::variant<nanobind::object, llvm::raw_fd_ostream> writeTarget;
+ std::variant<nanobind::object, std::ofstream> writeTarget;
bool binary;
};
>From 0315fe3c7e6d4d3f9a3e6e6e446bc1185c83d785 Mon Sep 17 00:00:00 2001
From: Amily Wu <amilywu2 at amd.com>
Date: Fri, 30 Jan 2026 21:50:53 +0000
Subject: [PATCH 7/9] Move join to util and replace twine
---
mlir/include/mlir/Bindings/Python/Globals.h | 12 ------
.../mlir/Bindings/Python/NanobindAdaptors.h | 23 +++++-----
.../mlir/Bindings/Python/NanobindUtils.h | 42 +++++++++----------
mlir/lib/Bindings/Python/IRCore.cpp | 9 ----
4 files changed, 31 insertions(+), 55 deletions(-)
diff --git a/mlir/include/mlir/Bindings/Python/Globals.h b/mlir/include/mlir/Bindings/Python/Globals.h
index fa1eb0bc13d20..bdcabea76cd3c 100644
--- a/mlir/include/mlir/Bindings/Python/Globals.h
+++ b/mlir/include/mlir/Bindings/Python/Globals.h
@@ -29,18 +29,6 @@
namespace mlir {
namespace python {
namespace MLIR_BINDINGS_PYTHON_DOMAIN {
-struct MlirTypeIDHash {
- size_t operator()(MlirTypeID typeID) const {
- return mlirTypeIDHashValue(typeID);
- }
-};
-
-struct MlirTypeIDEqual {
- bool operator()(MlirTypeID lhs, MlirTypeID rhs) const {
- return mlirTypeIDEqual(lhs, rhs);
- }
-};
-
/// Globals that are always accessible once the extension has been initialized.
/// Methods of this class are thread-safe.
class MLIR_PYTHON_API_EXPORTED PyGlobals {
diff --git a/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h b/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
index 6594670abaaa7..a9fd7a5d6ef71 100644
--- a/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
+++ b/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
@@ -30,7 +30,7 @@
#include "mlir/Bindings/Python/Nanobind.h"
#include "mlir-c/Bindings/Python/Interop.h" // This is expected after nanobind.
// clang-format on
-#include "llvm/ADT/Twine.h"
+#include "mlir/Bindings/Python/NanobindUtils.h"
namespace mlir {
namespace python {
@@ -550,10 +550,9 @@ class mlir_attribute_subclass : public pure_subclass {
!isaFunction(rawAttribute)) {
auto origRepr =
nanobind::cast<std::string>(nanobind::repr(otherAttribute));
- throw std::invalid_argument(
- (llvm::Twine("Cannot cast attribute to ") + captureTypeName +
- " (from " + origRepr + ")")
- .str());
+ throw std::invalid_argument(join("Cannot cast attribute to ",
+ captureTypeName, " (from ",
+ origRepr, ")"));
}
nanobind::object self = superCls.attr("__new__")(cls, otherAttribute);
return self;
@@ -633,10 +632,9 @@ class mlir_type_subclass : public pure_subclass {
!isaFunction(rawType)) {
auto origRepr =
nanobind::cast<std::string>(nanobind::repr(otherType));
- throw std::invalid_argument((llvm::Twine("Cannot cast type to ") +
- captureTypeName + " (from " +
- origRepr + ")")
- .str());
+ throw std::invalid_argument(join("Cannot cast type to ",
+ captureTypeName, " (from ",
+ origRepr, ")"));
}
nanobind::object self = superCls.attr("__new__")(cls, otherType);
return self;
@@ -720,10 +718,9 @@ class mlir_value_subclass : public pure_subclass {
!isaFunction(rawValue)) {
auto origRepr =
nanobind::cast<std::string>(nanobind::repr(otherValue));
- throw std::invalid_argument((llvm::Twine("Cannot cast value to ") +
- captureValueName + " (from " +
- origRepr + ")")
- .str());
+ throw std::invalid_argument(join("Cannot cast value to ",
+ captureValueName, " (from ",
+ origRepr, ")"));
}
nanobind::object self = superCls.attr("__new__")(cls, otherValue);
return self;
diff --git a/mlir/include/mlir/Bindings/Python/NanobindUtils.h b/mlir/include/mlir/Bindings/Python/NanobindUtils.h
index 71a5c4515920a..fe7371782e869 100644
--- a/mlir/include/mlir/Bindings/Python/NanobindUtils.h
+++ b/mlir/include/mlir/Bindings/Python/NanobindUtils.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/Support/DataTypes.h"
#include <fstream>
+#include <sstream>
#include <string>
#include <typeinfo>
#include <variant>
@@ -33,6 +34,26 @@ struct std::iterator_traits<nanobind::detail::fast_iterator> {
namespace mlir {
namespace python {
+/// Helper function to concatenate arguments into a `std::string`.
+template <typename... Ts>
+inline std::string join(const Ts &...args) {
+ std::ostringstream oss;
+ (oss << ... << args);
+ return oss.str();
+}
+
+struct MlirTypeIDHash {
+ size_t operator()(MlirTypeID typeID) const {
+ return mlirTypeIDHashValue(typeID);
+ }
+};
+
+struct MlirTypeIDEqual {
+ bool operator()(MlirTypeID lhs, MlirTypeID rhs) const {
+ return mlirTypeIDEqual(lhs, rhs);
+ }
+};
+
/// CRTP template for special wrapper types that are allowed to be passed in as
/// 'None' function arguments and can be resolved by some global mechanic if
/// so. Such types will raise an error if this global resolution fails, and
@@ -413,25 +434,4 @@ class Sliceable {
} // namespace mlir
-namespace llvm {
-
-template <>
-struct DenseMapInfo<MlirTypeID> {
- static inline MlirTypeID getEmptyKey() {
- auto *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
- return mlirTypeIDCreate(pointer);
- }
- static inline MlirTypeID getTombstoneKey() {
- auto *pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
- return mlirTypeIDCreate(pointer);
- }
- static inline unsigned getHashValue(const MlirTypeID &val) {
- return mlirTypeIDHashValue(val);
- }
- static inline bool isEqual(const MlirTypeID &lhs, const MlirTypeID &rhs) {
- return mlirTypeIDEqual(lhs, rhs);
- }
-};
-} // namespace llvm
-
#endif // MLIR_BINDINGS_PYTHON_PYBINDUTILS_H
diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp
index 7f34343eba6c9..b0ae7199b33a2 100644
--- a/mlir/lib/Bindings/Python/IRCore.cpp
+++ b/mlir/lib/Bindings/Python/IRCore.cpp
@@ -21,7 +21,6 @@
#include <functional>
#include <optional>
-#include <sstream>
#include <string>
namespace nb = nanobind;
@@ -49,14 +48,6 @@ operations.
// Utilities.
//------------------------------------------------------------------------------
-/// Local helper to concatenate arguments into a `std::string`.
-template <typename... Ts>
-static std::string join(const Ts &...args) {
- std::ostringstream oss;
- (oss << ... << args);
- return oss.str();
-}
-
/// Local helper to compute std::hash for a value.
template <typename T>
static size_t hash(const T &value) {
>From ccf9f4d6a88e67b66d873ee71079ba3e4e095624 Mon Sep 17 00:00:00 2001
From: Amily Wu <amilywu2 at amd.com>
Date: Fri, 30 Jan 2026 22:30:28 +0000
Subject: [PATCH 8/9] Write helper for check has downcast
---
mlir/include/mlir/Bindings/Python/NanobindUtils.h | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/mlir/include/mlir/Bindings/Python/NanobindUtils.h b/mlir/include/mlir/Bindings/Python/NanobindUtils.h
index fe7371782e869..5d4ee60e3ab04 100644
--- a/mlir/include/mlir/Bindings/Python/NanobindUtils.h
+++ b/mlir/include/mlir/Bindings/Python/NanobindUtils.h
@@ -19,6 +19,7 @@
#include <fstream>
#include <sstream>
#include <string>
+#include <type_traits>
#include <typeinfo>
#include <variant>
@@ -293,8 +294,12 @@ class Sliceable {
/// Trait to check if T provides a `maybeDownCast` method.
/// Note, you need the & to detect inherited members.
- template <typename T, typename... Args>
- using has_maybe_downcast = decltype(&T::maybeDownCast);
+ template <typename T, typename = void>
+ struct has_maybe_downcast : std::false_type {};
+
+ template <typename T>
+ struct has_maybe_downcast<T, std::void_t<decltype(&T::maybeDownCast)>>
+ : std::true_type {};
/// Returns the element at the given slice index. Supports negative indices
/// by taking elements in inverse order. Returns a nullptr object if out
@@ -307,7 +312,7 @@ class Sliceable {
return {};
}
- if constexpr (llvm::is_detected<has_maybe_downcast, ElementTy>::value)
+ if constexpr (has_maybe_downcast<ElementTy>::value)
return static_cast<Derived *>(this)
->getRawElement(linearizeIndex(index))
.maybeDownCast();
>From 1e5061734c403fa0e2b3f01ee100c2b93439810d Mon Sep 17 00:00:00 2001
From: Amily Wu <amilywu2 at amd.com>
Date: Mon, 2 Feb 2026 16:01:43 +0000
Subject: [PATCH 9/9] Remove aux str for ostream
---
mlir/include/mlir/Bindings/Python/Diagnostics.h | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/mlir/include/mlir/Bindings/Python/Diagnostics.h b/mlir/include/mlir/Bindings/Python/Diagnostics.h
index e30bbd639aade..b18f5673f0e3b 100644
--- a/mlir/include/mlir/Bindings/Python/Diagnostics.h
+++ b/mlir/include/mlir/Bindings/Python/Diagnostics.h
@@ -30,16 +30,14 @@ class CollectDiagnosticsToStringScope {
/*deleteUserData=*/nullptr);
}
~CollectDiagnosticsToStringScope() {
- assert(message.empty() && "unchecked error message");
+ assert(messageStream.str().empty() && "unchecked error message");
mlirContextDetachDiagnosticHandler(context, handlerID);
}
[[nodiscard]] std::string takeMessage() {
- message = messageStream.str();
+ std::string newMessage = messageStream.str();
messageStream.str("");
messageStream.clear();
- std::string newMessage;
- std::swap(message, newMessage);
return newMessage;
}
@@ -65,7 +63,6 @@ class CollectDiagnosticsToStringScope {
MlirContext context;
MlirDiagnosticHandlerID handlerID;
- std::string message;
std::ostringstream messageStream;
};
More information about the Mlir-commits
mailing list