[llvm] [VPlan] Generalize `VPAllSuccessorsIterator` to support predecessors (PR #178724)

Andrei Elovikov via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 3 07:14:04 PST 2026


================
@@ -25,90 +25,136 @@ namespace llvm {
 // GraphTraits specializations for VPlan Hierarchical Control-Flow Graphs     //
 //===----------------------------------------------------------------------===//
 
-/// Iterator to traverse all successors of a VPBlockBase node. This includes the
-/// entry node of VPRegionBlocks. Exit blocks of a region implicitly have their
-/// parent region's successors. This ensures all blocks in a region are visited
-/// before any blocks in a successor region when doing a reverse post-order
-// traversal of the graph. Region blocks themselves traverse only their entries
-// directly and not their successors. Those will be traversed when a region's
-// exiting block is traversed
-template <typename BlockPtrTy>
-class VPAllSuccessorsIterator
-    : public iterator_facade_base<VPAllSuccessorsIterator<BlockPtrTy>,
-                                  std::bidirectional_iterator_tag,
-                                  VPBlockBase> {
+/// Iterator to traverse all successors/predecessors of a VPBlockBase node,
+/// including its hierarchical successors/predecessors:
+///
+///     A
+///     |
+///  +-----+ <- Region R
+///  |  b  |
+///  |     |
+///  | ... |
+///  |     |
+///  |  e  |
+///  +-----+
+///     |
+///     B
+///
+///  Forward == true:
+///    Region blocks themselves traverse only their entries directly.
+///    Region's successor is implictly traversed when processing its exiting
+///    block.
+///    children(A) == {R}
+///    children(R) == {b}
+///    children(e) == {B}
+///
+///  Forward == false:
+///    Region blocks themselves traverse only their exiting blocks directly.
+///    Region's predecessor is implicitly traversed when processing its entry
+///    block.
+///    children(B) == {R}
+///    children(R) == {e}
+///    children(b) == {A}
+///
+/// The scheme described above ensures that all blocks of the region are visited
+/// before continuing traversal outside the region when doing a reverse
+/// post-order traversal of the VPlan.
+template <typename BlockPtrTy, bool Forward = true>
+class VPHierarchicalChildrenIterator
+    : public iterator_facade_base<
+          VPHierarchicalChildrenIterator<BlockPtrTy, Forward>,
+          std::bidirectional_iterator_tag, VPBlockBase> {
   BlockPtrTy Block;
-  /// Index of the current successor. For VPBasicBlock nodes, this simply is the
-  /// index for the successor array. For VPRegionBlock, SuccessorIdx == 0 is
-  /// used for the region's entry block, and SuccessorIdx - 1 are the indices
-  /// for the successor array.
-  size_t SuccessorIdx;
-
-  static BlockPtrTy getBlockWithSuccs(BlockPtrTy Current) {
-    while (Current && Current->getNumSuccessors() == 0)
+  /// Index of the current successor/predecessor. For VPBasicBlock nodes, this
+  /// simply is the index for the successors/predecessors array. For
+  /// VPRegionBlock, EdgeIdx == 0 is used for the region's entry/exiting block,
+  /// and EdgeIdx - 1 are the indices for the successors/predecessors array.
+  size_t EdgeIdx;
+
+  static size_t getNumOutgoingEdges(BlockPtrTy Current) {
+    if constexpr (Forward)
+      return Current->getNumSuccessors();
+    else
+      return Current->getNumPredecessors();
+  }
+
+  static ArrayRef<BlockPtrTy> getOutgoingEdges(BlockPtrTy Current) {
+    if constexpr (Forward)
+      return Current->getSuccessors();
+    else
+      return Current->getPredecessors();
+  }
+
+  static BlockPtrTy getBlockWithOutgoingEdges(BlockPtrTy Current) {
+    while (Current && getNumOutgoingEdges(Current) == 0)
       Current = Current->getParent();
     return Current;
   }
 
   /// Templated helper to dereference successor \p SuccIdx of \p Block. Used by
   /// both the const and non-const operator* implementations.
----------------
eas wrote:

Thanks, fixed.

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


More information about the llvm-commits mailing list