[Mlir-commits] [mlir] b20fca8 - [MLIR][Python] Remove partial LLVM APIs in python bindings (3/n) (#178984)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Feb 4 10:18:37 PST 2026
Author: RattataKing
Date: 2026-02-04T13:18:32-05:00
New Revision: b20fca82ab0c4754e838a8e1eba3a7f49a2dbab0
URL: https://github.com/llvm/llvm-project/commit/b20fca82ab0c4754e838a8e1eba3a7f49a2dbab0
DIFF: https://github.com/llvm/llvm-project/commit/b20fca82ab0c4754e838a8e1eba3a7f49a2dbab0.diff
LOG: [MLIR][Python] Remove partial LLVM APIs in python bindings (3/n) (#178984)
This PR continues work from #178290
It cleans up multiple LLVM utilities in *.h files under
`mlir/Bindings/python`, along with the corresponding *.cpp files.
Added:
Modified:
mlir/include/mlir/Bindings/Python/Diagnostics.h
mlir/include/mlir/Bindings/Python/Globals.h
mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
mlir/include/mlir/Bindings/Python/NanobindUtils.h
mlir/lib/Bindings/Python/DialectLLVM.cpp
mlir/lib/Bindings/Python/Globals.cpp
mlir/lib/Bindings/Python/IRCore.cpp
Removed:
################################################################################
diff --git a/mlir/include/mlir/Bindings/Python/Diagnostics.h b/mlir/include/mlir/Bindings/Python/Diagnostics.h
index 167002d561931..b18f5673f0e3b 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 {
@@ -30,29 +30,30 @@ 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() {
- std::string newMessage;
- std::swap(message, newMessage);
+ std::string newMessage = messageStream.str();
+ messageStream.str("");
+ messageStream.clear();
return newMessage;
}
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);
}
@@ -62,8 +63,7 @@ class CollectDiagnosticsToStringScope {
MlirContext context;
MlirDiagnosticHandlerID handlerID;
- std::string message;
- llvm::raw_string_ostream messageStream{message};
+ std::ostringstream messageStream;
};
} // namespace python
diff --git a/mlir/include/mlir/Bindings/Python/Globals.h b/mlir/include/mlir/Bindings/Python/Globals.h
index 6a722575c4e48..bdcabea76cd3c 100644
--- a/mlir/include/mlir/Bindings/Python/Globals.h
+++ b/mlir/include/mlir/Bindings/Python/Globals.h
@@ -12,6 +12,8 @@
#include <optional>
#include <regex>
#include <string>
+#include <string_view>
+#include <unordered_map>
#include <unordered_set>
#include <vector>
@@ -20,10 +22,8 @@
#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"
#include "llvm/Support/Regex.h"
namespace mlir {
@@ -60,7 +60,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 +121,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 +143,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;
@@ -157,7 +157,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; }
@@ -193,20 +193,24 @@ 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.
- 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;
+ std::unordered_set<std::string> loadedDialectModules;
TracebackLoc tracebackLoc;
TypeIDAllocator typeIDAllocator;
diff --git a/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h b/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
index 6594670abaaa7..918030824c409 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(nanobind::detail::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(
+ nanobind::detail::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(nanobind::detail::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 215daf245b902..9b41f1d8c3642 100644
--- a/mlir/include/mlir/Bindings/Python/NanobindUtils.h
+++ b/mlir/include/mlir/Bindings/Python/NanobindUtils.h
@@ -18,7 +18,10 @@
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/raw_ostream.h"
+#include <fstream>
+#include <sstream>
#include <string>
+#include <type_traits>
#include <typeinfo>
#include <variant>
@@ -34,6 +37,18 @@ struct std::iterator_traits<nanobind::detail::fast_iterator> {
namespace mlir {
namespace python {
+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
@@ -71,6 +86,14 @@ class Defaulting {
namespace nanobind {
namespace detail {
+/// 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();
+}
+
template <typename DefaultingTy>
struct MlirDefaultingCaster {
NB_TYPE_CASTER(DefaultingTy, const_name(DefaultingTy::kTypeDescription))
@@ -271,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
@@ -285,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();
@@ -412,25 +439,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/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 {
diff --git a/mlir/lib/Bindings/Python/Globals.cpp b/mlir/lib/Bindings/Python/Globals.cpp
index eb31bc29021ff..1fcd83c15c6ce 100644
--- a/mlir/lib/Bindings/Python/Globals.cpp
+++ b/mlir/lib/Bindings/Python/Globals.cpp
@@ -46,10 +46,12 @@ 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))
+ 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(llvm::StringRef 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;
}
@@ -202,14 +204,15 @@ 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;
+ std::string_view dialectNamespace =
+ operationName.substr(0, operationName.find('.'));
(void)loadDialectModule(dialectNamespace);
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;
@@ -226,7 +229,8 @@ PyGlobals::lookupOpAdaptorClass(llvm::StringRef operationName) {
(void)loadDialectModule(dialectNamespace);
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;
@@ -280,7 +284,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(
@@ -294,13 +298,14 @@ bool PyGlobals::TracebackLoc::isUserTracebackFilename(
rebuildUserTracebackExcludeRegex = false;
isUserTracebackFilenameCache.clear();
}
- if (!isUserTracebackFilenameCache.contains(file)) {
- std::string fileStr = file.str();
+ 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
diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp
index 7f34343eba6c9..efe45d6488241 100644
--- a/mlir/lib/Bindings/Python/IRCore.cpp
+++ b/mlir/lib/Bindings/Python/IRCore.cpp
@@ -21,12 +21,12 @@
#include <functional>
#include <optional>
-#include <sstream>
#include <string>
namespace nb = nanobind;
using namespace nb::literals;
using namespace mlir;
+using nanobind::detail::join;
static const char kModuleParseDocstring[] =
R"(Parses a module's assembly format from a string.
@@ -49,14 +49,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) {
More information about the Mlir-commits
mailing list