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: Erik Christiansen
Subject: Re: [avr-gcc-list] RFC: Speeding up small ISRs: PR20296
Date: Sun, 18 Jun 2017 22:25:38 +1000
User-agent: Mutt/1.8.0 (2017-02-23)

TL;DR: The meat (one lower-effort solution) follows some resynchronisation
       of understanding of the problem, and what gcc can do.

On 17.06.17 15:41, Georg-Johann Lay wrote:
> Erik Christiansen schrieb:
> > Reply-To: address@hidden
> > > 1) Let GCC emit directives / pseudo-instructions in non-naked ISR 
> > > prologue /
> > > epilogue
> > 
> > If only existing directives and macro invocations are emitted, then the
> > need to modify gas code is obviated. I.e. if:
> > 
> >   .maybe_isr_prologue 123       ; were instead:
> >    maybe_isr_prologue 123
...
> > then a gas macro could generate the required code without unnecessary
> > complexity. If the desired code to be generated from the parameters
> 
> Can you make this explicit?  How can a macro know whether the following
> code, hundreds of insns, clobbers tmp_reg or SREG?

There's been some mutual misunderstanding: As mentioned above, a macro
can generate code, guided by parameters and information squirrelled into
the symbol table. I didn't find mention of gas look-ahead in the OP, and
so had only discussed forward information flow. That's fixed below.

> Macro expansion runs prior to instruction parse.

Yes, I have written a two-pass assembler, but the only look-ahead there
was for computing forward jump offsets. I've not delved into gas
internals (merely making heavy use of its capabilities, especially
macros), but adding clobber-list collation for multiple ISRs could
perhaps be a feasible addition to gas. (An easier, less intrusive method
also exists, however.)

...

> To be more precise, consider

> ;; Start of ISR1
> __vector_1:
>       .maybe_isr_prologue 123
>       ;; Rest of prologue
>       ; CodeA
>       ;; Rest of epilogue
>       .maybe_isr_epilogue 123
>       reti
>       ; CodeB
>       ;; Rest of epilogue
>       .maybe_isr_epilogue 123
>       reti
>       ; CodeC
> ;; End of ISR1
> 
> If CodeA+CodeB+CodeC clobber SREG, Rzero, Rtmp then .maybe_isr_prologue
> shall expand to
> 
>       push r1
>       push r0
>       in r0,__SREG__
>       push r0
>       clr __zero_reg__
...

Thank you for the expansion, though the variability of save requirements
is not lost on this coder who writes all his ISRs in assembler. ;-)
(What I had missed was that gcc has clobber lists, but not for this
use case - despite all its passes.)

Lets pause to consider another two-part approach; one which avoids gas
hacking, and avoids the need for look-ahead in either gas or gcc, but
achieves that in the toolchain as a whole:

1) Let GCC emit tagged macro invocations in non-naked ISR prologue /
                ------------------------
   epilogue. (I.e. Proposal basically unchanged so far, but no gas
   rewrite needed if it can still do the work.)

2) Let gcc also write ".set _save_r1_123 1" to a temporary header file
   if the ISR tagged 123 clobbers r1. Ditto for other registers.
   (Opening a second temporary file for write is no effort for gcc,
   which is already writing its output to a temporary .o file for gas to
   process.) Gcc also prefixes ".include temporary_header_file" to the
   .o file. (The .o files are also usually temporary, retained only with
   -save-temps or -S.)

3) Let the _maybe_isr_prologue macro be designed so that
   "maybe_isr_prologue 123" will generate a "push r1" if _save_r1_123 is
   set, and "maybe_isr_epilogue 123" will then in turn generate a "pop r1".
   Ditto for the other registers. (Very simple macros.)

   So long as there is a "maybe_isr_prologue 123" before each reti, then
   it does not matter how many of them there are. Alternatively, gcc
   could just emit "oe_reti 123" (i.e. optimised-epilogue reti) for less
   clutter in the gcc output. (A neater "look", but insufficiently
   explicit for a casual reader?)

   To see what gas is doing there, assembly with -alcmns will include
   macro expansions in the listing, cropping untrue conditionals. 

4) Let the two _maybe_isr_prologue/epilogue macro definitions be added
   to an always implicitly included header. (That's less work than
   having gcc copy the text to the extra temporary header.)

What we have thereby done is synthesise a code generation loop without
hacking gas at all, and without having to solve the look-ahead dilemma
within gcc, or do a great deal more work there than before. This "whole
toolchain" solution is minimally intrusive code-wise.

Including at the head of the standard gcc output file, information which
gcc only knows at the end of one of its passes, gives gas free look-ahead
without having to hack extra passes into its structure. I am uncertain
that that would be possible within the avr-gas modules, and shudder at
the prospect of suggesting a core redesign to binutils maintainers.

There may at some future date be advantages in retaining all clobber
detection wholly within gcc, rather than letting it fragment throughout
the toolchain. If any tweaking were ever necessary, then it could all be
done in one place - and keeping it coherent also remains simpler.

In any event, with look-ahead handled, the old ambiguity problem is
gone, AIUI.

Erik




reply via email to

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