@@ -2207,9 +2207,9 @@ class PyBlockArgumentList
2207
2207
};
2208
2208
2209
2209
// / A list of operation operands. Internally, these are stored as consecutive
2210
- // / elements, random access is cheap. The result list is associated with the
2211
- // / operation whose results these are, and extends the lifetime of this
2212
- // / operation.
2210
+ // / elements, random access is cheap. The (returned) operand list is associated
2211
+ // / with the operation whose operands these are, and thus extends the lifetime
2212
+ // / of this operation.
2213
2213
class PyOpOperandList : public Sliceable <PyOpOperandList, PyValue> {
2214
2214
public:
2215
2215
static constexpr const char *pyClassName = " OpOperandList" ;
@@ -2262,9 +2262,9 @@ class PyOpOperandList : public Sliceable<PyOpOperandList, PyValue> {
2262
2262
};
2263
2263
2264
2264
// / A list of operation results. Internally, these are stored as consecutive
2265
- // / elements, random access is cheap. The result list is associated with the
2266
- // / operation whose results these are, and extends the lifetime of this
2267
- // / operation.
2265
+ // / elements, random access is cheap. The (returned) result list is associated
2266
+ // / with the operation whose results these are, and thus extends the lifetime of
2267
+ // / this operation.
2268
2268
class PyOpResultList : public Sliceable <PyOpResultList, PyOpResult> {
2269
2269
public:
2270
2270
static constexpr const char *pyClassName = " OpResultList" ;
@@ -2307,6 +2307,52 @@ class PyOpResultList : public Sliceable<PyOpResultList, PyOpResult> {
2307
2307
PyOperationRef operation;
2308
2308
};
2309
2309
2310
+ // / A list of operation successors. Internally, these are stored as consecutive
2311
+ // / elements, random access is cheap. The (returned) successor list is
2312
+ // / associated with the operation whose successors these are, and thus extends
2313
+ // / the lifetime of this operation.
2314
+ class PyOpSuccessors : public Sliceable <PyOpSuccessors, PyBlock> {
2315
+ public:
2316
+ static constexpr const char *pyClassName = " OpSuccessors" ;
2317
+
2318
+ PyOpSuccessors (PyOperationRef operation, intptr_t startIndex = 0 ,
2319
+ intptr_t length = -1 , intptr_t step = 1 )
2320
+ : Sliceable(startIndex,
2321
+ length == -1 ? mlirOperationGetNumSuccessors(operation->get ())
2322
+ : length,
2323
+ step),
2324
+ operation(operation) {}
2325
+
2326
+ void dunderSetItem (intptr_t index, PyBlock block) {
2327
+ index = wrapIndex (index);
2328
+ mlirOperationSetSuccessor (operation->get (), index, block.get ());
2329
+ }
2330
+
2331
+ static void bindDerived (ClassTy &c) {
2332
+ c.def (" __setitem__" , &PyOpSuccessors::dunderSetItem);
2333
+ }
2334
+
2335
+ private:
2336
+ // / Give the parent CRTP class access to hook implementations below.
2337
+ friend class Sliceable <PyOpSuccessors, PyBlock>;
2338
+
2339
+ intptr_t getRawNumElements () {
2340
+ operation->checkValid ();
2341
+ return mlirOperationGetNumSuccessors (operation->get ());
2342
+ }
2343
+
2344
+ PyBlock getRawElement (intptr_t pos) {
2345
+ MlirBlock block = mlirOperationGetSuccessor (operation->get (), pos);
2346
+ return PyBlock (operation, block);
2347
+ }
2348
+
2349
+ PyOpSuccessors slice (intptr_t startIndex, intptr_t length, intptr_t step) {
2350
+ return PyOpSuccessors (operation, startIndex, length, step);
2351
+ }
2352
+
2353
+ PyOperationRef operation;
2354
+ };
2355
+
2310
2356
// / A list of operation attributes. Can be indexed by name, producing
2311
2357
// / attributes, or by index, producing named attributes.
2312
2358
class PyOpAttributeMap {
@@ -2924,16 +2970,28 @@ void mlir::python::populateIRCore(py::module &m) {
2924
2970
&PyOperation::getCapsule)
2925
2971
.def (MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyOperation::createFromCapsule)
2926
2972
.def_property_readonly (" operation" , [](py::object self) { return self; })
2927
- .def_property_readonly (" opview" , &PyOperation::createOpView);
2973
+ .def_property_readonly (" opview" , &PyOperation::createOpView)
2974
+ .def_property_readonly (
2975
+ " successors" ,
2976
+ [](PyOperationBase &self) {
2977
+ return PyOpSuccessors (self.getOperation ().getRef ());
2978
+ },
2979
+ " Returns the list of Operation successors." );
2928
2980
2929
2981
auto opViewClass =
2930
2982
py::class_<PyOpView, PyOperationBase>(m, " OpView" , py::module_local ())
2931
2983
.def (py::init<py::object>(), py::arg (" operation" ))
2932
2984
.def_property_readonly (" operation" , &PyOpView::getOperationObject)
2933
2985
.def_property_readonly (" opview" , [](py::object self) { return self; })
2934
- .def (" __str__" , [](PyOpView &self) {
2935
- return py::str (self.getOperationObject ());
2936
- });
2986
+ .def (
2987
+ " __str__" ,
2988
+ [](PyOpView &self) { return py::str (self.getOperationObject ()); })
2989
+ .def_property_readonly (
2990
+ " successors" ,
2991
+ [](PyOperationBase &self) {
2992
+ return PyOpSuccessors (self.getOperation ().getRef ());
2993
+ },
2994
+ " Returns the list of Operation successors." );
2937
2995
opViewClass.attr (" _ODS_REGIONS" ) = py::make_tuple (0 , true );
2938
2996
opViewClass.attr (" _ODS_OPERAND_SEGMENTS" ) = py::none ();
2939
2997
opViewClass.attr (" _ODS_RESULT_SEGMENTS" ) = py::none ();
@@ -3448,7 +3506,8 @@ void mlir::python::populateIRCore(py::module &m) {
3448
3506
mlirOpPrintingFlagsUseLocalScope (flags);
3449
3507
valueState = mlirAsmStateCreateForValue (self.get (), flags);
3450
3508
}
3451
- mlirValuePrintAsOperand (self.get (), valueState, printAccum.getCallback (),
3509
+ mlirValuePrintAsOperand (self.get (), valueState,
3510
+ printAccum.getCallback (),
3452
3511
printAccum.getUserData ());
3453
3512
// Release state if allocated locally.
3454
3513
if (!state) {
@@ -3523,6 +3582,7 @@ void mlir::python::populateIRCore(py::module &m) {
3523
3582
PyOpOperandIterator::bind (m);
3524
3583
PyOpOperandList::bind (m);
3525
3584
PyOpResultList::bind (m);
3585
+ PyOpSuccessors::bind (m);
3526
3586
PyRegionIterator::bind (m);
3527
3587
PyRegionList::bind (m);
3528
3588
0 commit comments