@@ -2626,6 +2626,88 @@ class PyOpSuccessors : public Sliceable<PyOpSuccessors, PyBlock> {
26262626 PyOperationRef operation;
26272627};
26282628
2629+ // / A list of block successors. Internally, these are stored as consecutive
2630+ // / elements, random access is cheap. The (returned) successor list is
2631+ // / associated with the operation and block whose successors these are, and thus
2632+ // / extends the lifetime of this operation and block.
2633+ class PyBlockSuccessors : public Sliceable <PyBlockSuccessors, PyBlock> {
2634+ public:
2635+ static constexpr const char *pyClassName = " BlockSuccessors" ;
2636+
2637+ PyBlockSuccessors (PyBlock block, PyOperationRef operation,
2638+ intptr_t startIndex = 0 , intptr_t length = -1 ,
2639+ intptr_t step = 1 )
2640+ : Sliceable(startIndex,
2641+ length == -1 ? mlirBlockGetNumSuccessors(block.get())
2642+ : length,
2643+ step),
2644+ operation (operation), block(block) {}
2645+
2646+ private:
2647+ // / Give the parent CRTP class access to hook implementations below.
2648+ friend class Sliceable <PyBlockSuccessors, PyBlock>;
2649+
2650+ intptr_t getRawNumElements () {
2651+ block.checkValid ();
2652+ return mlirBlockGetNumSuccessors (block.get ());
2653+ }
2654+
2655+ PyBlock getRawElement (intptr_t pos) {
2656+ MlirBlock block = mlirBlockGetSuccessor (this ->block .get (), pos);
2657+ return PyBlock (operation, block);
2658+ }
2659+
2660+ PyBlockSuccessors slice (intptr_t startIndex, intptr_t length, intptr_t step) {
2661+ return PyBlockSuccessors (block, operation, startIndex, length, step);
2662+ }
2663+
2664+ PyOperationRef operation;
2665+ PyBlock block;
2666+ };
2667+
2668+ // / A list of block predecessors. The (returned) predecessor list is
2669+ // / associated with the operation and block whose predecessors these are, and
2670+ // / thus extends the lifetime of this operation and block.
2671+ // /
2672+ // / WARNING: This Sliceable is more expensive than the others here because
2673+ // / mlirBlockGetPredecessor actually iterates the use-def chain (of block
2674+ // / operands) anew for each indexed access.
2675+ class PyBlockPredecessors : public Sliceable <PyBlockPredecessors, PyBlock> {
2676+ public:
2677+ static constexpr const char *pyClassName = " BlockPredecessors" ;
2678+
2679+ PyBlockPredecessors (PyBlock block, PyOperationRef operation,
2680+ intptr_t startIndex = 0 , intptr_t length = -1 ,
2681+ intptr_t step = 1 )
2682+ : Sliceable(startIndex,
2683+ length == -1 ? mlirBlockGetNumPredecessors(block.get())
2684+ : length,
2685+ step),
2686+ operation (operation), block(block) {}
2687+
2688+ private:
2689+ // / Give the parent CRTP class access to hook implementations below.
2690+ friend class Sliceable <PyBlockPredecessors, PyBlock>;
2691+
2692+ intptr_t getRawNumElements () {
2693+ block.checkValid ();
2694+ return mlirBlockGetNumPredecessors (block.get ());
2695+ }
2696+
2697+ PyBlock getRawElement (intptr_t pos) {
2698+ MlirBlock block = mlirBlockGetPredecessor (this ->block .get (), pos);
2699+ return PyBlock (operation, block);
2700+ }
2701+
2702+ PyBlockPredecessors slice (intptr_t startIndex, intptr_t length,
2703+ intptr_t step) {
2704+ return PyBlockPredecessors (block, operation, startIndex, length, step);
2705+ }
2706+
2707+ PyOperationRef operation;
2708+ PyBlock block;
2709+ };
2710+
26292711// / A list of operation attributes. Can be indexed by name, producing
26302712// / attributes, or by index, producing named attributes.
26312713class PyOpAttributeMap {
@@ -3655,7 +3737,19 @@ void mlir::python::populateIRCore(nb::module_ &m) {
36553737 },
36563738 nb::arg (" operation" ),
36573739 " Appends an operation to this block. If the operation is currently "
3658- " in another block, it will be moved." );
3740+ " in another block, it will be moved." )
3741+ .def_prop_ro (
3742+ " successors" ,
3743+ [](PyBlock &self) {
3744+ return PyBlockSuccessors (self, self.getParentOperation ());
3745+ },
3746+ " Returns the list of Block successors." )
3747+ .def_prop_ro (
3748+ " predecessors" ,
3749+ [](PyBlock &self) {
3750+ return PyBlockPredecessors (self, self.getParentOperation ());
3751+ },
3752+ " Returns the list of Block predecessors." );
36593753
36603754 // ----------------------------------------------------------------------------
36613755 // Mapping of PyInsertionPoint.
@@ -4099,6 +4193,8 @@ void mlir::python::populateIRCore(nb::module_ &m) {
40994193 PyBlockArgumentList::bind (m);
41004194 PyBlockIterator::bind (m);
41014195 PyBlockList::bind (m);
4196+ PyBlockSuccessors::bind (m);
4197+ PyBlockPredecessors::bind (m);
41024198 PyOperationIterator::bind (m);
41034199 PyOperationList::bind (m);
41044200 PyOpAttributeMap::bind (m);
0 commit comments