[llvm-dev] Specify special cases of delay slots in the back end
Alex Susu via llvm-dev
llvm-dev at lists.llvm.org
Sat Feb 11 04:39:29 PST 2017
Hello.
Hal, the problem I have is that it doesn't advance at the next available instruction
- it always gets the same store. This might be because I did not specify in a file like
[Target]Schedule.td the functional units, processor and instruction itineraries.
Regarding the Stalls argument to my method
[Target]DispatchGroupSBHazardRecognizer::getHazardType() I always get the argument Stalls
= 0. This is no surprise since in PostRASchedulerList.cpp we have only one call to it, in
method SchedulePostRATDList::ListScheduleTopDown():
ScheduleHazardRecognizer::HazardType HT =
HazardRec->getHazardType(CurSUnit, 0/*no stalls*/);
Let me state what I have added to my back end to enable scheduling with hazards:
- inspiring from lib/Target/PowerPC/PPCHazardRecognizers.h, I have created a class
[Target]DispatchGroupSBHazardRecognizer : public ScoreboardHazardRecognizer (I use
ScoreboardHazardRecognizer because I hope in the near future to make my class employ in
"out-of-order" execution USEFUL program instructions instead of NOP to handle my data
hazards), implementing for it only a method:
HazardType getHazardType(SUnit *SU, int Stalls);
In this method I check if the current SU is a vector store and the previous
instruction updates the register used by the store, which in my processor is a data
hazard, in which case I give:
return NoopHazard;
and otherwise, I give:
return ScoreboardHazardRecognizer::getHazardType(SU, Stalls);
- I implemented in [Target]InstrInfo.cpp 2 more methods:
- CreateTargetPostRAHazardRecognizer() to register the
[Target]DispatchGroupSBHazardRecognizer()
- insertNoop() which returns the target's NOP
- note that my vector (and scalar) instructions are inspired from the Mips back
end, which has MSAInst (and MipsInst) with NoItinerary InstrItinClass. Currently I am not
using a [Target]Schedule.td specifying functional units, processor and instruction
itineraries. This might be a problem - I guess ScoreboardHazardRecognizer relies on this
information.
In principle, should I maybe use the post-RA MI-scheduler instead of the standard
post-RA scheduler (maybe also
http://llvm.org/docs/doxygen/html/classllvm_1_1MachineSchedStrategy.html ) to deal with my
hazards ?
Following http://llvm.org/devmtg/2014-10/Slides/Estes-MISchedulerTutorial.pdf, the
MI-scheduler also handles hazards, but I guess it's less documented, although the AArch64
is using it.
Thank you,
Alex
On 2/10/2017 11:33 PM, Hal Finkel wrote:
> Hi Alex,
>
> All of this makes sense, but are you correctly handling the Stalls argument to
> getHazardType? What are you doing with it?
>
> -Hal
>
>
> On 02/10/2017 02:42 PM, Alex Susu via llvm-dev wrote:
>> Hello.
>> I am progressing a bit with difficulty with the post RA scheduler
>> (PostRASchedulerList.cpp with ScoreboardHazardRecognizer) - the problem I have is that
>> it doesn't advance at the next available instruction when the overridden
>> ScoreboardHazardRecognizer::getHazardType() method returns NoopHazard and it gets stuck
>> at the same instruction (store in my runs).
>>
>> Just to make sure: I am trying to use the post-RA (Register Allocation) scheduler to
>> avoid data hazards by inserting, if possible, other USEFUL instructions from the program
>> instead of (just) NOPs. Is this out-of-order scheduling (e.g., using the
>> ScoreboardHazardRecognizer) that employs useful program instructions instead of NOPs
>> working well with the post-RA scheduler?
>> Otherwise, if the post RA scheduler only inserts NOPs, since I have issues using it,
>> I could as well insert NOPs in the [Target]AsmPrinter.cpp module .
>>
>> Thank you,
>> Alex
>>
>> On 2/10/2017 1:42 AM, Hal Finkel wrote:
>>>
>>> On 02/09/2017 04:46 PM, Alex Susu via llvm-dev wrote:
>>>> Hello.
>>>> Hal, thank you for the information.
>>>> I managed to get inspired from PPCHazardRecognizers.cpp. So I created my very simple
>>>> [Target]HazardRecognizers.cpp pass that is also derived from ScoreboardHazardRecognizer.
>>>> My class only implements the method getHazardType(), which checks if, as stated in my
>>>> first email, for example, I have a store instruction that is storing the value updated
>>>> by the instruction immediately above, which is NOT ok, since for my processor this is a
>>>> data hazard and in this case I have to insert a NOP in between by making getHazardType()
>>>> to:
>>>> return NoopHazard; // this basically emits noop
>>>>
>>>> However, to my surprise, my very simple post-RA scheduler (using my class derived
>>>> from ScoreboardHazardRecognizer) is cycling FOREVER after this return NoopHazard, by
>>>> calling getHazardType() again and again for this SAME store instruction I found in the
>>>> first place with the data hazard problem. So, llc is no longer finishing - I have to
>>>> stop the process because of this strange behavior.
>>>> I was expecting after the first call to getHazardType() with the respective store
>>>> instruction (and return NoopHazard) that the scheduler would move forward to the other
>>>> instructions in the DAG/basic-block.
>>>
>>> It should emit a nop if all available instructions return NoopHazard.
>>>
>>>>
>>>> Do you have an idea what can I do to fix this problem?
>>>
>>> I'm not sure. I recall running into a situation like this years ago, but I don't recall
>>> now how I resolved it. Are you correctly handling the Stalls argument to getHazardType?
>>>
>>> -Hal
>>>
>>>>
>>>> Thank you very much,
>>>> Alex
>>>>
>>>> On 2/3/2017 10:25 PM, Hal Finkel wrote:
>>>>> Hi Alex,
>>>>>
>>>>> You can program a post-RA scheduler which will return NoopHazard in the appropriate
>>>>> circumstances. You can look at the PowerPC target (e.g.
>>>>> lib/Target/PowerPC/PPCHazardRecognizers.cpp) as an example.
>>>>>
>>>>> -Hal
>>>>>
>>>>>
>>>>> On 02/02/2017 05:03 PM, Alex Susu via llvm-dev wrote:
>>>>>> Hello.
>>>>>> I see there is little information on specifying instructions with delay slots.
>>>>>> So could you please tell me how can I insert NOPs (BEFORE or after an instruction)
>>>>>> or how to make an aware instruction scheduler in order to avoid miscalculations due to
>>>>>> the delay slot effect?
>>>>>>
>>>>>> More exactly, I have the following constraints on my (SIMD) processor:
>>>>>> - certain stores or loads, must be executed 1 cycle after the instruction
>>>>>> generating their input operands ends. For example, if I have:
>>>>>> R1 = R2 + R3
>>>>>> LS[R10] = R1 // this will not produce the correct result because it does not
>>>>>> see the updated value of R1 from the previous instruction
>>>>>> To make this code execute correctly we need to insert a NOP:
>>>>>> R1 = R2 + R3
>>>>>> NOP // or other instruction to fill the delay slot
>>>>>> LS[R10] = R1
>>>>>>
>>>>>> - a compare instruction requires to add a NOP after it, before the predicated
>>>>>> block (something like a conditional JMP instruction) starts.
>>>>>>
>>>>>>
>>>>>> Thank you,
>>>>>> Alex
>>>>>> _______________________________________________
>>>>>> LLVM Developers mailing list
>>>>>> llvm-dev at lists.llvm.org
>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>>>
>>>> _______________________________________________
>>>> LLVM Developers mailing list
>>>> llvm-dev at lists.llvm.org
>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
More information about the llvm-dev
mailing list