Re: RFC: Speeding up small ISRs: PR20296
Georg-Johann Lay <[email protected]> Fri, 14 Jul 2017 19:18:52 +0200
| Newsgroups | gmane.comp.hardware.avr.gcc |
|---|---|
| Message-ID | <[email protected]> |
Georg-Johann Lay schrieb:
> On 15.06.2017 14:43, Georg-Johann Lay wrote:
>> https://gcc.gnu.org/PR20296
>>
>> is about speeding up "small" ISRs, and is open for 12 years now...
>>
>> Anyone familiar with avr-gcc knows that a fix would be high effort and
>> risk, and that's the major reason for why PR20296 is still open (and
>> even classified "suspended").
>>
>> In some forum discussion (again!) on that issue, there was the
>> following proposal to approach that PR:
>>
>> 1) Let GCC emit directives / pseudo-instructions in non-naked ISR
>> prologue / epilogue
>>
>> 2) Let GAS scan the code and replace the directives with code as needed.
>>
>> Currently,
>>
>> #include <avr/io.h>
>> #include <avr/interrupt.h>
>>
>> ISR (INT0_vect)
>> {
>> __asm ("; Code");
>> }
>>
>> emit something like:
>>
>>
>> __vector_1:
>> push r1
>> push r0
>> in r0,__SREG__
>> push r0
>> clr __zero_reg__
>> .L__stack_usage = 3
>>
>> ; Code
>>
>> pop r0
>> out __SREG__,r0
>> pop r0
>> pop r1
>> reti
>>
>>
>> which would change to:
>>
>>
>> __vector_1:
>> .maybe_isr_prologue 123
>> ;; Rest of prologue
>>
>> ; Code
>>
>> ;; Rest of epilogue
>> .maybe_isr_epilogue 123
>> reti
>>
>> GAS would then scan the code associated to the function and replace
>> the .maybe by appropriate sequence to safe / init / restore tmp-reg,
>> zero-reg and SREG. Other registers like R24 are handled by GCC as
>> usual. For example, if the scan reveals that tmp-reg is not needed
>> but zero-reg is (which will imply SREG due to the CLR) the replacement
>> code would be:
>>
>>
>> __vector_1:
>> push r1
>> in r1,__SREG__
>> push r1
>> clr __zero_reg__
>>
>> ; Code
>>
>> pop r1
>> out __SREG__,r1
>> pop r1
>> reti
>>
>>
>> Maybe someone is interested in implementing the GAS part, and if that
>> is the case and the proposal is feasible, I would take care of the GCC
>> part.
>>
>> Caveats:
>>
>> a) .L__stack_usage can no more be computed by GCC
>>
>> b) It's hard to find the end of the relevant code. We might have
>> interleaved sections (like with dispatch tables), there might be code
>> that is emit after the epilogue, there might be more than 1 epilogue,
>> dunno if GAS can infer whether JMP is local or non-local.
>>
>> We could add a new GCC pass that filters out situations that are
>> pointless to scan like code with dispatch tables or function calls,
>> and fall back to classical prologue / epilogue in such cases.
>>
>> The .maybe gets function-unique identifiers (123 in the example) so
>> that GAS knows which epilogue belongs to which .prologue provided
>> that's helpful.
>>
>> I am not familiar with Binutils / GAS though and don't know if it's
>> easy to add the 2 new passes: One to scan and one to replace the
>> .maybe with appropriate code. IIUC GAS only works on sections, and
>> the scan would be on BFD internal representation (like relaxing) after
>> the parser read in the asm sources?
>
> FYI, I just went ahead any typed down these lines for GAS.
>
>
> If someone wants to give it a try, it's here:
>
> https://sourceware.org/bugzilla/show_bug.cgi?id=21683#c2
>
>> The GCC change would add a new option, configure test whether GAS
>> supports this, let ISR prologue and epilogue emit new unspec_volatile
>> pseudo insns and add a scan pass to detect situations that are
>> pointless should fall back to old code, like when dispatch tables,
>> calls or non-local goto is seen.
The according avr-gcc feature is also upstream now. It adds a new
option -m[no-]gas-isr-prologues and a new function attribute to disable
__gcc_isr generation for individual ISRs:
http://gcc.gnu.org/onlinedocs/gcc/AVR-Function-Attributes.html
If you want to play around with it, you need Binutils that implement
PR20296 (e.g. Binutils GIT master or upcoming 2.29) and avr-gcc that
implements PR81268 (GCC SVN trunk r250093 or newer).
The feature is enabled per default for all optimization levels except
for -O0 and -Og.
Johann