This reverts commit bbc2976868.
This change seems to be at odds with the non-owning part semantics of
MlirOperation in C API. Since downstream clients can only take and
return MlirOperation, it does not sound correct to force all returns of
MlirOperation transfer ownership. Specifically, this makes it impossible
for downstreams to implement IR-traversing functions that, e.g., look at
neighbors of an operation.
The following patch triggers the exception, and there does not seem to
be an alternative way for a downstream binding writer to express this:
```
diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp
index 39757dfad5be..2ce640674245 100644
--- a/mlir/lib/Bindings/Python/IRCore.cpp
+++ b/mlir/lib/Bindings/Python/IRCore.cpp
@@ -3071,6 +3071,11 @@ void mlir::python::populateIRCore(py::module &m) {
py::arg("successors") = py::none(), py::arg("regions") = 0,
py::arg("loc") = py::none(), py::arg("ip") = py::none(),
py::arg("infer_type") = false, kOperationCreateDocstring)
+ .def("_get_first_in_block", [](PyOperation &self) -> MlirOperation {
+ MlirBlock block = mlirOperationGetBlock(self.get());
+ MlirOperation first = mlirBlockGetFirstOperation(block);
+ return first;
+ })
.def_static(
"parse",
[](const std::string &sourceStr, const std::string &sourceName,
diff --git a/mlir/test/python/ir/operation.py b/mlir/test/python/ir/operation.py
index f59b1a26ba48..6b12b8da5c24 100644
--- a/mlir/test/python/ir/operation.py
+++ b/mlir/test/python/ir/operation.py
@@ -24,6 +24,25 @@ def expect_index_error(callback):
except IndexError:
pass
+@run
+def testCustomBind():
+ ctx = Context()
+ ctx.allow_unregistered_dialects = True
+ module = Module.parse(
+ r"""
+ func.func @f1(%arg0: i32) -> i32 {
+ %1 = "custom.addi"(%arg0, %arg0) : (i32, i32) -> i32
+ return %1 : i32
+ }
+ """,
+ ctx,
+ )
+ add = module.body.operations[0].regions[0].blocks[0].operations[0]
+ op = add.operation
+ # This will get a reference to itself.
+ f1 = op._get_first_in_block()
+
+
# Verify iterator based traversal of the op/region/block hierarchy.
# CHECK-LABEL: TEST: testTraverseOpRegionBlockIterators
```
50 lines
1.1 KiB
Python
50 lines
1.1 KiB
Python
# RUN: %PYTHON %s
|
|
# Standalone sanity check of context life-cycle.
|
|
import gc
|
|
import mlir.ir
|
|
|
|
assert mlir.ir.Context._get_live_count() == 0
|
|
|
|
# Create first context.
|
|
print("CREATE C1")
|
|
c1 = mlir.ir.Context()
|
|
assert mlir.ir.Context._get_live_count() == 1
|
|
c1_repr = repr(c1)
|
|
print("C1 = ", c1_repr)
|
|
|
|
print("GETTING AGAIN...")
|
|
c2 = c1._get_context_again()
|
|
c2_repr = repr(c2)
|
|
assert mlir.ir.Context._get_live_count() == 1
|
|
assert c1_repr == c2_repr
|
|
|
|
print("C2 =", c2)
|
|
|
|
# Make sure new contexts on constructor.
|
|
print("CREATE C3")
|
|
c3 = mlir.ir.Context()
|
|
assert mlir.ir.Context._get_live_count() == 2
|
|
c3_repr = repr(c3)
|
|
print("C3 =", c3)
|
|
assert c3_repr != c1_repr
|
|
print("FREE C3")
|
|
c3 = None
|
|
gc.collect()
|
|
assert mlir.ir.Context._get_live_count() == 1
|
|
|
|
print("Free C1")
|
|
c1 = None
|
|
gc.collect()
|
|
assert mlir.ir.Context._get_live_count() == 1
|
|
print("Free C2")
|
|
c2 = None
|
|
gc.collect()
|
|
assert mlir.ir.Context._get_live_count() == 0
|
|
|
|
# Create a context, get its capsule and create from capsule.
|
|
c4 = mlir.ir.Context()
|
|
c4_capsule = c4._CAPIPtr
|
|
assert '"mlir.ir.Context._CAPIPtr"' in repr(c4_capsule)
|
|
c5 = mlir.ir.Context._CAPICreate(c4_capsule)
|
|
assert c4 is c5
|