[PATCH] D146198: [RISCV] Make ResourceCycles relevant to LMUL

Wang Pengcheng via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 20 20:34:45 PDT 2023


pcwang-thead added a comment.

In D146198#4206929 <https://reviews.llvm.org/D146198#4206929>, @michaelmaitland wrote:

> In D146198#4205441 <https://reviews.llvm.org/D146198#4205441>, @pcwang-thead wrote:
>
>> In D146198#4202168 <https://reviews.llvm.org/D146198#4202168>, @michaelmaitland wrote:
>>
>>>> If there are some microarchitectures that can't be modeled, just add a new subroutine to upstream if approved.
>>>
>>> Does this mean that subtarget routines must be added to the RISCVScheduleV file since the following function needs to know about the custom subroutine to do its isa checks:
>>>
>>>   // Helper class for generating a list of resource cycles of different LMULs.
>>>   class ResourceCycles<list<ResourceCycle> resourceCycles, string mx> {
>>>
>>> I am concerned that the `RISCVScheduleV` file will take on bloat due to holding subtarget related routines if this is the case.
>>
>> Yes. So I posted this patch here just to discuss how we should handle this.
>> For example, solutions may be:
>>
>> 1. Add routines to `RISCVScheduleV.td` just as what I have done.
>> 2. Extend `TableGen` to support pass functions:
>>
>>   // Supposes that we have a Function class to present a function object that its parameters are function parameters.
>>   class TargetSubroutine<int base, string mx> : Function;
>>   
>>   // Then. Supposes that we have a new bang operator to apply this function to input parameters and the result is `ret`.
>>   class ResourceCycles<list<TargetSubroutine> subroutines, int base, string mx> {
>>     list<int> value = !foreach(subroutine, subroutines,
>>                                !apply(subroutine, base, mx)
>>                               );
>>   }
>>   
>>   // In SchedXXX.td, we can define our own routines.
>>   class Multiplier<int base, string mx>:TargetSubroutine {
>>    // We return an int value calculated from mx.
>>    int ret = !mul(base, multiplier<mx>.value);
>>   }
>>
>> 3. Some templates are flexible to specify cycles according to LMULs (I haven't figured out one...).
>
> What stops us from doing something like this:
> https://github.com/llvm/llvm-project/blob/0c0468e6df2bcabd207858891c2387357857b0bc/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td#L95https://github.com/llvm/llvm-project/blob/0c0468e6df2bcabd207858891c2387357857b0bc/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td#L95
> or
> https://github.com/llvm/llvm-project/blob/0c0468e6df2bcabd207858891c2387357857b0bc/llvm/lib/Target/AMDGPU/SISchedule.td#L160
> ?
>
> `Num` or `2` could be replaced with something like `MyTargetGetCycles<mx>.c` without needing to extend the tablegen language. For example in the SchedXXX.td file:
>
>   class MyTargetGetCycles<string mx> {
>     int c = !cond(
>       !eq(mx, "M1") : 1,
>       !eq(mx, "M2") : 1,
>       !eq(mx, "M4") : 1,
>       !eq(mx, "M8") : 1,
>       !eq(mx, "MF2") : 1,
>       !eq(mx, "MF4") : 1,
>       !eq(mx, "MF8") : 1,
>       !eq(mx, "UpperBound") : 1
>     );
>   }
>   
>   foreach mx = SchedMxList in {
>     defvar Cycles = MyTargetGetCycles<mx>.c;
>     let Latency = Cycles, ResourceCycles = [Cycles] in {
>       defm "" : LMULWriteResMX<"WriteVLDE",   [MyTargetSomeResource], mx>;
>       defm "" : LMULWriteResMX<"WriteVSTE",   [MyTargetSomeResource], mx>;
>     }
>   }

That's because `LMULWriteRes` is already LMUL-relevant and we have looped `SchedMxList` in `LMULWriteResImpl`. If we loop it again, the result would be weird.
Another approach is to define something like  `LMULWriteResImpl` in `SchedXXX.td` and override `Latency` and `ResourceCycles` according to LMUL. But if so, why bother to define some boilerplates like `LMULWriteRes` in `RISCVScheduleV.td`?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D146198/new/

https://reviews.llvm.org/D146198



More information about the llvm-commits mailing list