avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] RFC: Speeding up small ISRs: PR20296


From: Georg-Johann Lay
Subject: Re: [avr-gcc-list] RFC: Speeding up small ISRs: PR20296
Date: Fri, 14 Jul 2017 19:18:52 +0200
User-agent: Thunderbird 2.0.0.24 (Windows/20100228)

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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]