[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
Wed May 15 04:10:57 PDT 2024
Abhishek-Varma wrote:
>> 4. Now, the old candidate slice should be replaced by the cloned loop's candidate slice - this again requires you to traverse through the loop structure to find out exactly which insert slice op is going to be the new "old" candidate slice op
> Could you detail this with an example if possible?
Hi @Yun-Fly , sure.
What I meant above was that the API is based on `candidateSliceOp` : `fuseConsumerOfSlice(candidateSliceOp)`.
Now, assume this input IR (for sake of discussion let's just take single output def-chain) :-
```
%a = scf.for
{
%b = scf.for
{
. . .
%c = scf.for {
%candidateSlice = <CANDIDATE SLICE OF INTEREST>
scf.yield %candidateSlice
}
scf.yield %c
}
scf.yield %b
}
%op1 = tensor.empty
%op2 = ..
...
%user = <USER OF %a -> which is essentially the actual "consumer" of %candidateSlice> this also uses other operand like %op1, %op2,... etc.
```
Now, since the API is invoked with `%candidateSlice` - after the point 3 I enlisted in the [above comment thread's pointers](https://github.com/llvm/llvm-project/pull/88712#issuecomment-2104441680) the state of the IR will become :-
```
%a = scf.for
{
%b = scf.for
{
. . .
%c = scf.for {
%candidateSlice = <CANDIDATE SLICE OF INTEREST>
scf.yield %candidateSlice
}
scf.yield %c
}
scf.yield %b
}
%op1 = tensor.empty
%op2 = ..
...
%new_a = scf.for
{
%new_b = scf.for
{
. . .
%new_c = scf.for {
%new_candidateSlice = <CANDIDATE SLICE OF INTEREST>
scf.yield %new_candidateSlice
}
scf.yield %new_c
}
scf.yield %new_b
}
%user = <USER OF %a -> which is essentially the actual "consumer" of %candidateSlice> this also uses other operand like %op1, %op2,... etc.
```
This was done to ensure that when we fuse the consumer the other operands should DOMINATE their use. Handling this THIS way for now seemed like a clean solution, else this in itself is another can of worms.
Now, the original invocation was `fuseConsumerOfSlice(%candidateSlice)`, which should now revolve around `%new_candidateSlice`.
After merging such big def-chains we need to know WHICH new candidate slice is 1:1 of the previous one. Involve multiple yielding `scf.for` and this already becomes too complex to handle at the moment.
Also, when I tried implementing the "fetch actual consumer" logic - I maintained the `OpResult`'s resultNumber as I went through the use-def-chains.
Let me know your thoughts. It's anyway better to deal with this in future if such use case arises. :)
https://github.com/llvm/llvm-project/pull/88712
More information about the Mlir-commits
mailing list