[Mlir-commits] [mlir] [MLIR][SCF] Add an API to fuse consumer to a producer within scf loop (PR #88712)

Abhishek Varma llvmlistbot at llvm.org
Thu May 16 04:22:09 PDT 2024


Abhishek-Varma wrote:

> If we want to extend such consumer fusion to scf loop with multiple results or uses cases in the future. It is also necessary to ensure no other op(s) between %a and %user is dominated by %a. In another word, we should select the FIRST user in use-chain of scf loop to invoke fuseConsumerOfSlice. Otherwise, the DOMINATION will be violated.

Hi @Yun-Fly - this is a very good point! Thanks for this. Keeping this pointer in mind I've added an assumption validator which will perform the following two checks :-
1. The loop has exactly one result.
OR
2. The consumer op is the first user of the loop AND rest of the users are in the same containing block of the consumer op.

I believe the above two checks fairly guards us now.

> Based on your latest implementation, I understand each loop of nested structure need cloned to add new inits from consumer to be fused and that is what you do now. However, I didn't see any explicit slice clone operation during fuseConsumerOfSlice. Or did you mean mergeBlock when create new scf loop [here](https://github.com/llvm/llvm-project/blob/fc7b121375231b008f90441e2b53699ea50bed66/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp#L1353)? If so, It looks like not a clone, but just a movement? As for offset replacement related to block argument, it is a in-place modification anyway. No new slice seems created and you keep using the same candidateSliceOp object. If not, please correct me:)

So, `Operation.h` has [clone(...) API](https://github.com/llvm/llvm-project/blob/ba2e4fe4e7f79e49fcac54ea20f5b899dc687cfc/mlir/include/mlir/IR/Operation.h#L198) - and this API's usage will lead to the mapping scenario I was mentioning earlier.
Correct me if I'm wrong but the `mergeBlock` API is used for merging from a given `source` to `destination` block. And for this I then need to create the OUTERMOST `sc.for`. To avoid doing that I'm using `clone`.
I've used `mergeBlocks` to do that after creating a new loop into which the tiled consumer will be fused - this reminds me we not only need to clone the entire hierarchy of loops but also traverse back to the point which leads us to the target inner loop and then re-create it (and then use `mergeBlock`) in a similar fashion.


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


More information about the Mlir-commits mailing list