[Mlir-commits] [mlir] [MLIR][SCF] Fix LoopPeelOp documentation (NFC) (PR #113179)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Oct 22 07:41:58 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-scf
Author: Hugo Trachino (nujaa)
<details>
<summary>Changes</summary>
There is a mistake in the SCF documentation explaining the order of results of PeelOp in the case where `peel_front` is true.
As an example, I added annotations to the peel_front unit test.
```
func.func @<!-- -->loop_peel_first_iter_op() {
// CHECK: %[[C0:.+]] = arith.constant 0
// CHECK: %[[C41:.+]] = arith.constant 41
// CHECK: %[[C5:.+]] = arith.constant 5
// CHECK: %[[C5_0:.+]] = arith.constant 5
// CHECK: scf.for %{{.+}} = %[[C0]] to %[[C5_0]] step %[[C5]]
// CHECK: arith.addi
// CHECK: scf.for %{{.+}} = %[[C5_0]] to %[[C41]] step %[[C5]]
// CHECK: arith.addi
%0 = arith.constant 0 : index
%1 = arith.constant 41 : index
%2 = arith.constant 5 : index
scf.for %i = %0 to %1 step %2 {
arith.addi %i, %i : index
}
return
}
module attributes {transform.with_named_sequence} {
transform.named_sequence @<!-- -->__transform_main(%arg1: !transform.any_op {transform.readonly}) {
%0 = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op
%1 = transform.get_parent_op %0 {op_name = "scf.for"} : (!transform.any_op) -> !transform.op<"scf.for">
%main_loop, %remainder = transform.loop.peel %1 {peel_front = true} : (!transform.op<"scf.for">) -> (!transform.op<"scf.for">, !transform.op<"scf.for">)
transform.annotate %main_loop "main_loop" : !transform.op<"scf.for">
transform.annotate %remainder "remainder" : !transform.op<"scf.for">
transform.yield
}
}
```
Gives :
```
func.func @<!-- -->loop_peel_first_iter_op() {
%c0 = arith.constant 0 : index
%c41 = arith.constant 41 : index
%c5 = arith.constant 5 : index
%c5_0 = arith.constant 5 : index
scf.for %arg0 = %c0 to %c5_0 step %c5 {
%0 = arith.addi %arg0, %arg0 : index
} {remainder} // The first iteration loop (second result) has been annotated remainder
scf.for %arg0 = %c5_0 to %c41 step %c5 {
%0 = arith.addi %arg0, %arg0 : index
} {main_loop} // The main loop (first result) has been annotated main_loop
return
}
```
---
Full diff: https://github.com/llvm/llvm-project/pull/113179.diff
2 Files Affected:
- (modified) mlir/include/mlir/Dialect/SCF/TransformOps/SCFTransformOps.td (+6-6)
- (modified) mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp (+5-6)
``````````diff
diff --git a/mlir/include/mlir/Dialect/SCF/TransformOps/SCFTransformOps.td b/mlir/include/mlir/Dialect/SCF/TransformOps/SCFTransformOps.td
index 20880d94a83cac..d13c1ba9a8ed1e 100644
--- a/mlir/include/mlir/Dialect/SCF/TransformOps/SCFTransformOps.td
+++ b/mlir/include/mlir/Dialect/SCF/TransformOps/SCFTransformOps.td
@@ -146,7 +146,7 @@ def LoopPeelOp : Op<Transform_Dialect, "loop.peel",
let summary = "Peels the first or last iteration of the loop";
let description = [{
Rewrite the given loop with a main loop and a partial (first or last) loop.
- When the `peelFront` option is set as true, the first iteration is peeled off.
+ When the `peelFront` option is set to true, the first iteration is peeled off.
Otherwise, updates the given loop so that its step evenly divides its range and puts
the remaining iteration into a separate loop or a conditional.
@@ -158,12 +158,12 @@ def LoopPeelOp : Op<Transform_Dialect, "loop.peel",
This operation ignores non-scf::ForOp ops and drops them in the return.
When `peelFront` is true, this operation returns two scf::ForOp Ops, the
- first scf::ForOp corresponds to the first iteration of the loop which can
- be canonicalized away in the following optimization. The second loop Op
- contains the remaining iteration, and the new lower bound is the original
- lower bound plus the number of steps.
+ first scf::ForOp corresponds to the target loop, whose lower bound has
+ been updated to the original lower bound plus the step. The second result
+ is the first iteration of the loop which can be canonicalized away in the
+ following optimization.
- When `peelFront` is not true, this operation returns two scf::ForOp Ops, with the first
+ When `peelFront` is false, this operation returns two scf::ForOp Ops, with the first
scf::ForOp satisfying: "the loop trip count is divisible by the step".
The second loop Op contains the remaining iteration. Note that even though the
Payload IR modification may be performed in-place, this operation consumes
diff --git a/mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp b/mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp
index a30e349d49136c..c06a448c3108c3 100644
--- a/mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp
+++ b/mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp
@@ -206,12 +206,11 @@ LogicalResult mlir::scf::peelForLoopAndSimplifyBounds(RewriterBase &rewriter,
return success();
}
-/// When the `peelFront` option is set as true, the first iteration of the loop
-/// is peeled off. This function rewrites the original scf::ForOp as two
-/// scf::ForOp Ops, the first scf::ForOp corresponds to the first iteration of
-/// the loop which can be canonicalized away in the following optimization. The
-/// second loop Op contains the remaining iteration, and the new lower bound is
-/// the original lower bound plus the number of steps.
+/// Rewrites the original scf::ForOp as two scf::ForOp Ops, the first scf::ForOp
+/// corresponds to the first iteration of the loop which can be canonicalized
+/// away in the following optimization. The second loop Op contains the
+/// remaining iteration, and the new lower bound is the original lower bound
+/// plus the number of steps.
LogicalResult mlir::scf::peelForLoopFirstIteration(RewriterBase &b, ForOp forOp,
ForOp &firstIteration) {
RewriterBase::InsertionGuard guard(b);
``````````
</details>
https://github.com/llvm/llvm-project/pull/113179
More information about the Mlir-commits
mailing list