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