[Mlir-commits] [mlir] [mlir][python] bind block predecessors and successors (PR #145116)

Maksim Levental llvmlistbot at llvm.org
Sat Jun 21 06:18:29 PDT 2025


================
@@ -1059,6 +1059,26 @@ void mlirBlockPrint(MlirBlock block, MlirStringCallback callback,
   unwrap(block)->print(stream);
 }
 
+intptr_t mlirBlockGetNumSuccessors(MlirBlock block) {
+  return static_cast<intptr_t>(unwrap(block)->getNumSuccessors());
+}
+
+MlirBlock mlirBlockGetSuccessor(MlirBlock block, intptr_t pos) {
+  return wrap(unwrap(block)->getSuccessor(static_cast<unsigned>(pos)));
+}
+
+intptr_t mlirBlockGetNumPredecessors(MlirBlock block) {
+  Block *b = unwrap(block);
+  return static_cast<intptr_t>(std::distance(b->pred_begin(), b->pred_end()));
+}
+
+MlirBlock mlirBlockGetPredecessor(MlirBlock block, intptr_t pos) {
+  Block *b = unwrap(block);
+  Block::pred_iterator it = b->pred_begin();
+  std::advance(it, pos);
+  return wrap(*it);
----------------
makslevental wrote:

Sorry just to add a litlle more "context"; if you look at `getSuccessors` and `getSuccessor(unsigned)` they work differently but still in a way that doesn't seem possible for `getPredecessors`:

```c++
SuccessorRange getSuccessors() { return SuccessorRange(this); }

...

SuccessorRange::SuccessorRange(Block *block) : SuccessorRange() {
  if (block->empty() || llvm::hasSingleElement(*block->getParent()))
    return;
  Operation *term = &block->back();
  if ((count = term->getNumSuccessors()))
    base = term->getBlockOperands().data();
}
```
and
```c++
Block *Block::getSuccessor(unsigned i) {
  assert(i < getNumSuccessors());
  return getTerminator()->getSuccessor(i);
}

...

class Operation {
  ...
  Block *getSuccessor(unsigned index) {
    assert(index < getNumSuccessors());
    return getBlockOperands()[index].get();
  }
  ...
}
```

compared with

```c++
using pred_iterator = PredecessorIterator;
pred_iterator pred_begin() {
  return pred_iterator((BlockOperand *)getFirstUse());
}
pred_iterator pred_end() { return pred_iterator(nullptr); }
iterator_range<pred_iterator> getPredecessors() {
  return {pred_begin(), pred_end()};
}
```

so while I agree that iterating the chain isn't great I don't see what else can be done (other than caching those predecessors, which I'm sure we don't want to do either).

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


More information about the Mlir-commits mailing list