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

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

Re: [avr-gcc-list] GCC-AVR Register optimisations


From: Wouter van Gulik
Subject: Re: [avr-gcc-list] GCC-AVR Register optimisations
Date: Thu, 10 Jan 2008 09:47:13 +0100
User-agent: Thunderbird 2.0.0.9 (Windows/20071031)

Registers 17 downwards are  call saved and push/popped in prescribed
order by prolog/epilog functions. Also R28,29 is potential frame pointer
and so that is best left alone. So the key registers are: R18-R27  & R30,31


Note that in some cases it could be very interesting to use r27, or Y, register.

Consider this example:

char *x;
volatile int y;

void foo(char *p)
{
    y += *p;
}

void main(void)
{
        char *p1 = x;
        foo(p1++);
        foo(p1++);
        foo(p1++);
        foo(p1++);
        foo(p1++);
        foo(p1++);
        foo(p1++);
        foo(p1++);
        foo(p1++);
        foo(p1++);
}


This will generate very bad code.
/* prologue: frame size=0 */
        push r14
        push r15
        push r16
        push r17
/* prologue end (size=4) */
        lds r24,x
        lds r25,(x)+1
        movw r16,r24
        subi r16,lo8(-(1))
        sbci r17,hi8(-(1))
        call foo
        movw r14,r16
        sec
        adc r14,__zero_reg__
        adc r15,__zero_reg__
        movw r24,r16
        call foo
        movw r16,r14
        subi r16,lo8(-(1))
        sbci r17,hi8(-(1))
        movw r24,r14
        call foo
        movw r14,r16
        sec
        adc r14,__zero_reg__
        adc r15,__zero_reg__
        movw r24,r16
        call foo
        movw r16,r14
        subi r16,lo8(-(1))
        sbci r17,hi8(-(1))
        movw r24,r14
        call foo
etc..

A more optimal scheme would be
        call foo
        movw r24, r16
        adiw r24, 1
        movw r16, r24
        call foo
etc..
Using the r24 capability to do a 16 bit increment

But in this "special" case there is no frame pointer. So we could use R28 to store instead of R16. Then we can add on r28 and do something like this:
        
     call foo
     adiw r28, 1
     movw r24, r28
     call foo

So yes using R28 as last resort looks like a sane thing.
Unless there is no frame pointer at all, and there is a need for 16 (or 32 bit) arithmetic on saved registers. This is probably incredibly difficult. But I thought to mention it anyway

HTH,

Wouter

ps.

Writing it like "foo(p); p++;" Will produce better code?!? I will fill a bug report for this.

With the order, there are several problems:

1) Initial register  allocation fragments the register set. For example,
allocating r25 will prevent R24-25 being used for 16bit register  and
prevent R22-25 and R24-27 being used as 32 bit registers. gcc register
allocator does not seem to overcome this fragmentation.

2) The situation is made worse by the order of  16bit+ register used for
call and return values - which are "allocated" in reverse order. eg
R24-R25, R22-24, R18-24.  This means that the function parameters or
return values are rarely  in the right place - except for 16bit values.

3) Allocating a byte to odd number register precluded it being extended
to 16bit value without a move.

So, I tried creating an order which would preserve the contiguous
register space and avoid the above issues as much as possible.
This is what I ended up with:

R18,26,22,30,20,24,19,21,23,25,27,31,28,29, \
   17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,\


The result is a 1.25% saving in code size for a simple mixed
application. Pretty good for such a simple change!

For more floating point, the saving might well be higher as it demands
more contiguous 32 bit registers.

On the same basis, the current order of called saved registers R2-R17
dictated by  (mcall) prolog limit further improvement is clearly
imperfect.  These are used less frequently, though their cost is much
higher. So its difficult to gauge impact. I might take a look at some
intense floating point functions to see if this if it is worth pursuing
reordering these too.


Andy









_______________________________________________
AVR-GCC-list mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list





reply via email to

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