[Mlir-commits] [mlir] [MLIR][Python] Impl XOpInterface(s) from Python, with X=Transform and X=MemoryEffects (PR #176920)

Rolf Morel llvmlistbot at llvm.org
Mon Feb 2 08:30:50 PST 2026


================
@@ -0,0 +1,156 @@
+//===- IRInterfaces.h - IR Interfaces for Python Bindings -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_BINDINGS_PYTHON_IRINTERFACES_H
+#define MLIR_BINDINGS_PYTHON_IRINTERFACES_H
+
+#include "mlir-c/IR.h"
+#include "mlir-c/Interfaces.h"
+#include "mlir-c/Support.h"
+#include "mlir/Bindings/Python/IRCore.h"
+
+namespace nb = nanobind;
+
+namespace mlir {
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
+
+constexpr static const char *constructorDoc =
+    R"(Creates an interface from a given operation/opview object or from a
+subclass of OpView. Raises ValueError if the operation does not implement the
+interface.)";
+
+constexpr static const char *operationDoc =
+    R"(Returns an Operation for which the interface was constructed.)";
+
+constexpr static const char *opviewDoc =
+    R"(Returns an OpView subclass _instance_ for which the interface was
+constructed)";
+
+/// CRTP base class for Python classes representing MLIR Op interfaces.
+/// Interface hierarchies are flat so no base class is expected here. The
+/// derived class is expected to define the following static fields:
+///  - `const char *pyClassName` - the name of the Python class to create;
+///  - `GetTypeIDFunctionTy getInterfaceID` - the function producing the TypeID
+///    of the interface.
+/// Derived classes may redefine the `bindDerived(ClassTy &)` method to bind
+/// interface-specific methods.
+///
+/// An interface class may be constructed from either an Operation/OpView object
+/// or from a subclass of OpView. In the latter case, only the static interface
+/// methods are available, similarly to calling ConcereteOp::staticMethod on the
+/// C++ side. Implementations of concrete interfaces can use the `isStatic`
+/// method to check whether the interface object was constructed from a class or
+/// an operation/opview instance. The `getOpName` always succeeds and returns a
+/// canonical name of the operation suitable for lookups.
+template <typename ConcreteIface>
+class PyConcreteOpInterface {
+protected:
+  using ClassTy = nb::class_<ConcreteIface>;
+  using GetTypeIDFunctionTy = MlirTypeID (*)();
+
+public:
+  /// Constructs an interface instance from an object that is either an
+  /// operation or a subclass of OpView. In the latter case, only the static
+  /// methods of the interface are accessible to the caller.
+  PyConcreteOpInterface(nb::object object, DefaultingPyMlirContext context)
+      : obj(std::move(object)) {
+    try {
+      operation = &nb::cast<PyOperation &>(obj);
+    } catch (nb::cast_error &) {
+      // Do nothing.
+    }
+
+    try {
+      operation = &nb::cast<PyOpView &>(obj).getOperation();
+    } catch (nb::cast_error &) {
+      // Do nothing.
+    }
----------------
rolfmorel wrote:

I can clean try to clean it up, if you'd like.

https://github.com/llvm/llvm-project/pull/176920


More information about the Mlir-commits mailing list