Re: RFC: Speeding up small ISRs: PR20296

Georg-Johann Lay <[email protected]> Fri, 30 Jun 2017 18:19:35 +0200
Newsgroups gmane.comp.hardware.avr.gcc
Message-ID <[email protected]>
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

Binutils manual didn't catch up with master yet.  If so, you should
see a new "AVR Pseudo Instructions" entry in

https://sourceware.org/binutils/docs/as/AVR_002dDependent.html

that adds some documentation / specification.

Johann


> 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.
> 
> Johann