[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] not optimal code generation (avr-gcc 3.4.3 -Os)
From: |
Andy Hutchinson |
Subject: |
Re: [avr-gcc-list] not optimal code generation (avr-gcc 3.4.3 -Os) |
Date: |
Wed, 23 Feb 2005 18:52:07 -0500 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax) |
I ran the code thru my personal version of 4.0 (with MODES_TIEABLE_P 1)
Since the change explictely help SUBREG stuff it is relevant.
My version also includes a patch to optimise the x=y<<8.
It also some other stuff that might help - but I cant be sure.
As you can see, things turn out quite nicely!
Be aware that declaring a variable as volatile severly restricts the
optimisation that can or will be done.
One trick with I/O (which is all volatile) is to copy the value to a
variable if it is used more than once and you dont expect (or want) the
value to change.
unsigned char x=SPCR;
if (x==1)
.....
else if (x==2)
......
else if (x==3)
will generaly give better much code than:
if (SPCR==1)
.....
else if (SPCR==2)
....
else if (SPCR==3)
address@hidden wrote:
Christof Krueger wrote:
Hello,
when compiling the following code I get not optimal code:
--------------------------------------
#include <avr/io.h>
int
main(void)
{
volatile uint8_t foo=3;
uint16_t bar;
bar = (uint8_t)(64+foo)<<8; // *
return bar;
}
--------------------------------------
As you can see, I want to set the upper byte of bar using foo which
can change before the line in question (marked with a *).
Compiling with
avr-gcc main.c -mmcu=atmega162 -Wa,-adhlns=main.lst -Os
yields following asm code:
20 0008 83E0 ldi r24,lo8(3)
21 000a 8983 std Y+1,r24
22 000c 8981 ldd r24,Y+1
23 000e 805C subi r24,lo8(-(64))
24 0010 9927 clr r25
25 0012 982F mov r25,r24
26 0014 8827 clr r24
Why is r25 cleared just before moving r24 to r25 and is there a way to
change my example code in a way that avr-gcc will not produce
redundant code?
Hmm. Good question....
I would suggest filling out a bug report on the GCC project on this. Be
sure to put "avr" in the "target" field of the bug report and mention
"missed optimization".
Another question:
When accessing (uint8_t)(variable>>8) avr-gcc produces
420 018e 8091 0000 lds r24,variable
421 0192 9091 0000 lds r25,(variable)+1
422 0196 892F mov r24,r25
423 0198 9927 clr r25
which could also be written as
lds r24,(variable)+1
clr r25
Is there a way to force this code without using inline asm?
You didn't say what type "variable" was before this operation.....
Eric
_______________________________________________
AVR-GCC-list mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
55 .LM0:
56 /* prologue: frame size=1 */
57 0000 C0E0 ldi r28,lo8(__stack - 1)
58 0002 D0E0 ldi r29,hi8(__stack - 1)
59 0004 DEBF out __SP_H__,r29
60 0006 CDBF out __SP_L__,r28
61 /* prologue end (size=4) */
232:looprv.c **** volatile uint8_t foo=3;
63 .LM1:
64 0008 83E0 ldi r24,lo8(3)
65 000a 8983 std Y+1,r24
233:looprv.c **** uint16_t bar;
234:looprv.c ****
235:looprv.c **** bar = (uint8_t)(64+foo)<<8; // *
67 .LM2:
68 000c 2981 ldd r18,Y+1
69 000e 205C subi r18,lo8(-(64))
236:looprv.c ****
237:looprv.c **** return bar;
238:looprv.c **** }
71 .LM3:
72 0010 922F mov r25,r18
73 0012 80E0 ldi r24,lo8(0)
74 /* epilogue: frame size=1 */
75 0014 0C94 0000 jmp exit
76 /* epilogue end (size=2) */
77 /* function main size 12 (6