[Mlir-commits] [mlir] [mlir][scf] Extend consumer fuse to single nested `scf.for` (PR #94190)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Sep 10 05:44:30 PDT 2024
================
@@ -1478,7 +1504,54 @@ static FailureOr<OpOperand *> getConsumerFromUses(Value val,
return failure();
if (containingOpBlock != consumerOp->getBlock())
return failure();
- return &operand;
+ return operand;
+}
+
+/// Recursively find the outer nest loops of given loop(included) while the
+/// predict function succeed, sorted from outer to inner.
+///
+/// @param loop: target loop, note that this loop will be also included. I.e.
+/// if no other nest loops were found, just return itself.
+/// @param pred: predict function, the termination condition of recursive
+/// process.
+/// @return Outer Nest Loops: nest loops outside given target loop(included).
+///
+/// E.g.
+///
+/// ```
+/// %0 = scf.for()
+/// %1 = scf.for()
+/// %2 = scf.for()
+/// ```
+///
+/// If `%2 = scf.for` is given without specific prediction function, this
+/// function will return three nest loops: %0 + %1 + %2.
+static SmallVector<LoopLikeOpInterface> getOuterNestLoopsWhile(
+ LoopLikeOpInterface loop,
+ const std::function<LogicalResult(LoopLikeOpInterface)> &pred) {
+ SmallVector<LoopLikeOpInterface> nestLoops = {loop};
+ auto outerLoop = dyn_cast<LoopLikeOpInterface>(loop->getParentOp());
+ while (outerLoop && succeeded(pred(outerLoop))) {
+ nestLoops.push_back(outerLoop);
+ outerLoop = dyn_cast<LoopLikeOpInterface>(outerLoop->getParentOp());
+ }
+ // sorted from outer to inner
+ return {nestLoops.rbegin(), nestLoops.rend()};
+}
+
+/// Check if it is the ForOp that yield the result of inner loop
+static LogicalResult isForOpYieldResultOfInnerLoop(LoopLikeOpInterface loop) {
+ if (auto forOp = dyn_cast<scf::ForOp>(loop.getOperation())) {
+ Block::OpListType &opsInLoopBody = forOp.getBody()->getOperations();
+ for (auto &&[index, op] : llvm::enumerate(opsInLoopBody)) {
+ // If the orderIndex of inner loop is the last second one before the
+ // yieldOp of ForOp, the given loop must yield the result of inner loop.
+ if (isa<LoopLikeOpInterface>(op)) {
----------------
Yun-Fly wrote:
Actually my previous code allow more than two op contained by outer loop. I guess your assumption is more similar to [getPerfectlyNestedLoops](https://github.com/llvm/llvm-project/blob/main/mlir/lib/Dialect/SCF/Utils/Utils.cpp#L1139)? Anyway, I think it is enough as a startup. Let's firstly rename it to `getPerfectlyOuterNestedLoops`.
https://github.com/llvm/llvm-project/pull/94190
More information about the Mlir-commits
mailing list