[Mlir-commits] [mlir] [mlir][scf] Extend consumer fusion to multiple tilable users (PR #111955)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Oct 28 20:43:17 PDT 2024
================
@@ -1699,28 +1702,131 @@ getUntiledConsumerFromSlice(tensor::ParallelInsertSliceOp candidateSliceOp) {
return getConsumerFromUses(resultingValue, containingOp->getBlock());
}
-/// This utility currently checks whether the loop either :-
-/// 1. Yields exactly one result.
-/// 2. Has consumer op as its first user and other users to be in the same
-/// containing block as that of consumer op's. Currently we clone the loop op
-/// right before the consumer op in order to maintain a valid def-use chain.
-/// This utility thus helps ensuring that no invalid IR is formed due to the
-/// same.
-static LogicalResult checkAssumptionForLoop(Operation *loopOp,
- Operation *consumerOp) {
- // Check if the loop op yields one result.
- if (loopOp->getNumResults() == 1)
- return success();
- // Check if the consumerOp is the first user of the loopOp and if other users
- // are in the same containing block as that of consumer op's.
+/// This utility currently checks whether the first userOp of loop is NOT before
+/// the last defineOp of consumer. Currently we need to move the loop op right
+/// before a certain op in order to maintain a valid use-def chain. This utility
+/// thus helps ensuring that no invalid IR is formed. E.g.
+///
+/// ```
+/// %0 = scf.for() {
+/// ...
+/// }
+/// ...
+/// %1 = firstUserOfLoop(%0)
+/// ...
+/// %2 = lastDefOfConsumer
+/// ...
+/// %3 = consumerOp(%2)
+/// ```
+///
+/// If the `firstUserOfLoop`is before `lastDefOfConsumer`, then it would be
+/// invalid to move the loop op right before the `firstUserOfLoop`, a.k.a.
+/// use-def chain violation:
+///
+/// ```
+/// %0:2 = scf.for() {
+/// // use before define error
+/// %3 = tiledConsumerOp(%2)
+/// }
+/// %1 = firstUserOfLoop(%0)
+/// ...
+/// %2 = lastDefOfConsumer
+/// ```
+///
+/// To address this issue, this utility would try to move `lastDefOfConsumer`
----------------
Yun-Fly wrote:
Hey, I have split the move and check logic into two different methods as you suggested. In general:
1. In `getConsumerFromUses`, we will check the assumption for loop with `reorderOperations` flag **_enabled_**. That means we can move computed slice before `firstUserOfLoop` at this moment unless `checkAssumptionForLoop` return failure. Anyway, `getConsumerFromUses` will return the first valid consumer, otherwise bail out.
2. In the second time of calling `checkAssumptionForLoop` with `reorderOperations` flag **_disabled_**, it highly expects the right form, or else bail out.
https://github.com/llvm/llvm-project/pull/111955
More information about the Mlir-commits
mailing list