[Mlir-commits] [mlir] 9c16eef - [mlir][IR] Add ReverseDominanceIterator for IR walkers
Matthias Springer
llvmlistbot at llvm.org
Wed Mar 22 01:02:12 PDT 2023
Author: Matthias Springer
Date: 2023-03-22T09:01:58+01:00
New Revision: 9c16eef1ec46e10185713043663511d49ffff6b1
URL: https://github.com/llvm/llvm-project/commit/9c16eef1ec46e10185713043663511d49ffff6b1
DIFF: https://github.com/llvm/llvm-project/commit/9c16eef1ec46e10185713043663511d49ffff6b1.diff
LOG: [mlir][IR] Add ReverseDominanceIterator for IR walkers
Blocks are enumerated depth-first, but post-order. I.e., a block is enumerated when its successors have been enumerated. This iteration style is suitable when deleting blocks in a regions: in the absence of cycles, uses are deleted before their definitions.
Differential Revision: https://reviews.llvm.org/D146125
Added:
Modified:
mlir/include/mlir/IR/Iterators.h
mlir/test/IR/visitors.mlir
mlir/test/lib/IR/TestVisitors.cpp
Removed:
################################################################################
diff --git a/mlir/include/mlir/IR/Iterators.h b/mlir/include/mlir/IR/Iterators.h
index c16f7117f3dc..2c6137c72cf5 100644
--- a/mlir/include/mlir/IR/Iterators.h
+++ b/mlir/include/mlir/IR/Iterators.h
@@ -21,6 +21,7 @@
#include "mlir/Support/LLVM.h"
#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/PostOrderIterator.h"
namespace mlir {
/// This iterator enumerates elements in "reverse" order. It is a wrapper around
@@ -37,7 +38,7 @@ struct ReverseIterator {
/// This iterator enumerates elements according to their dominance relationship.
/// Operations and regions are enumerated in "forward" order. Blocks are
/// enumerated according to their successor relationship. Unreachable blocks are
-/// not enumerated.
+/// not enumerated. Blocks may not be erased during the traversal.
///
/// Note: If `NoGraphRegions` is set to "true", this iterator asserts that each
/// visited region has SSA dominance. In either case, the ops in such regions
@@ -70,6 +71,44 @@ struct ForwardDominanceIterator {
return ForwardIterator::makeIterable(range);
}
};
+
+/// This iterator enumerates elements according to their reverse dominance
+/// relationship. Operations and regions are enumerated in "reverse" order.
+/// Blocks are enumerated according to their successor relationship, but
+/// post-order. I.e., a block is visited after its successors have been visited.
+/// Cycles in the block graph are broken in an unspecified way. Unreachable
+/// blocks are not enumerated. Blocks may not be erased during the traversal.
+///
+/// Note: If `NoGraphRegions` is set to "true", this iterator asserts that each
+/// visited region has SSA dominance.
+template <bool NoGraphRegions = false>
+struct ReverseDominanceIterator {
+ // llvm::reverse uses RangeT::rbegin and RangeT::rend.
+ static constexpr auto makeIterable(Block &range) {
+ return llvm::reverse(ForwardIterator::makeIterable(range));
+ }
+
+ static constexpr auto makeIterable(Operation &range) {
+ return llvm::reverse(ForwardIterator::makeIterable(range));
+ }
+
+ static auto makeIterable(Region ®ion) {
+ if (NoGraphRegions) {
+ // Only regions with SSA dominance are allowed.
+ assert(mayHaveSSADominance(region) && "graph regions are not allowed");
+ }
+
+ // Create post-order iterator. Blocks are enumerated according to their
+ // successor relationship.
+ Block *null = nullptr;
+ auto it = region.empty()
+ ? llvm::make_range(llvm::po_end(null), llvm::po_end(null))
+ : llvm::post_order(®ion.front());
+
+ // Walk API expects Block references instead of pointers.
+ return llvm::make_pointee_range(it);
+ }
+};
} // namespace mlir
#endif // MLIR_IR_ITERATORS_H
diff --git a/mlir/test/IR/visitors.mlir b/mlir/test/IR/visitors.mlir
index ddbc334fa4ee..2d83d6922e0c 100644
--- a/mlir/test/IR/visitors.mlir
+++ b/mlir/test/IR/visitors.mlir
@@ -323,6 +323,36 @@ func.func @unordered_cfg_with_loop() {
// CHECK: Visiting region 0 from operation 'regionOp0'
// CHECK: Visiting region 0 from operation 'func.func'
+// CHECK-LABEL: Op reverse dominance post-order visits
+// CHECK: Visiting op 'func.return'
+// CHECK-NOT: Visiting op 'op6'
+// CHECK: Visiting op 'op7'
+// CHECK: Visiting op 'cf.br'
+// CHECK: Visiting op 'op5'
+// CHECK: Visiting op 'cf.br'
+// CHECK: Visiting op 'op1'
+// CHECK: Visiting op 'cf.br'
+// CHECK: Visiting op 'op2'
+// CHECK: Visiting op 'cf.br'
+// CHECK: Visiting op 'op3'
+// CHECK: Visiting op 'cf.cond_br'
+// CHECK: Visiting op 'op0'
+// CHECK: Visiting op 'regionOp0'
+// CHECK: Visiting op 'func.func'
+
+// CHECK-LABEL: Block reverse dominance post-order visits
+// CHECK: Visiting block ^bb7 from region 0 from operation 'regionOp0'
+// CHECK: Visiting block ^bb5 from region 0 from operation 'regionOp0'
+// CHECK: Visiting block ^bb1 from region 0 from operation 'regionOp0'
+// CHECK: Visiting block ^bb2 from region 0 from operation 'regionOp0'
+// CHECK: Visiting block ^bb3 from region 0 from operation 'regionOp0'
+// CHECK: Visiting block ^bb0 from region 0 from operation 'regionOp0'
+// CHECK: Visiting block ^bb0 from region 0 from operation 'func.func'
+
+// CHECK-LABEL: Region reverse dominance post-order visits
+// CHECK: Visiting region 0 from operation 'regionOp0'
+// CHECK: Visiting region 0 from operation 'func.func'
+
// CHECK-LABEL: Block pre-order erasures (skip)
// CHECK: Erasing block ^bb0 from region 0 from operation 'regionOp0'
// CHECK: Cannot erase block ^bb0 from region 0 from operation 'regionOp0', still has uses
diff --git a/mlir/test/lib/IR/TestVisitors.cpp b/mlir/test/lib/IR/TestVisitors.cpp
index 6ed4abc71b7d..a14347ed2ec3 100644
--- a/mlir/test/lib/IR/TestVisitors.cpp
+++ b/mlir/test/lib/IR/TestVisitors.cpp
@@ -92,6 +92,19 @@ static void testPureCallbacks(Operation *op) {
<< "\n";
funcOp->walk<WalkOrder::PostOrder,
ForwardDominanceIterator</*NoGraphRegions=*/true>>(regionPure);
+
+ llvm::outs() << "Op reverse dominance post-order visits"
+ << "\n";
+ funcOp->walk<WalkOrder::PostOrder,
+ ReverseDominanceIterator</*NoGraphRegions=*/true>>(opPure);
+ llvm::outs() << "Block reverse dominance post-order visits"
+ << "\n";
+ funcOp->walk<WalkOrder::PostOrder,
+ ReverseDominanceIterator</*NoGraphRegions=*/true>>(blockPure);
+ llvm::outs() << "Region reverse dominance post-order visits"
+ << "\n";
+ funcOp->walk<WalkOrder::PostOrder,
+ ReverseDominanceIterator</*NoGraphRegions=*/true>>(regionPure);
});
}
More information about the Mlir-commits
mailing list