[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