Skip to content
This repository was archived by the owner on Oct 11, 2025. It is now read-only.

Commit 759f2c1

Browse files
authored
[mlir][python] bind block predecessors and successors (#145116)
bind `block.getSuccessor` and `block.getPredecessors`.
1 parent fe99b39 commit 759f2c1

File tree

1 file changed

+97
-1
lines changed

1 file changed

+97
-1
lines changed

IRCore.cpp

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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.
26312713
class 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

Comments
 (0)