[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-libc-dev] Missed optimizations
From: |
Georg-Johann Lay |
Subject: |
Re: [avr-libc-dev] Missed optimizations |
Date: |
Tue, 18 Apr 2017 10:38:15 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.7.1 |
On 16.04.2017 19:30, Raul Sanchez wrote:
Your email is badly broken, something it terribly wrong with your line
breaks.
Just wanted to report the following observations in generated code.
Target: __AVR_ATtiny85__
Version: AVR gcc 4.6.4
Quite old a version, dates 6 years back which is 6 major GCC versions.
Optimization level: -Os
-------- C source ----------
uint16_t sum_adc;
uint16_t analog;
uint16_t adc_buffer[64];
uint8_t adc_index;
...
This is not valid C. "..." may only occur as varargs function parameter
sum_adc += ADC;
This is not valid C: Assignments may only occur inside functions.
sum_adc -= adc_buffer[adc_index];
analog = (uint16_t) (sum_adc >> 3);
...
------- end C source ------------
------- assembly code (with corresponding C statements) --------
// sum_adc += ADC;
lds r18,sum_adc
lds r19,sum_adc+1
in r24,36-0x20
in r25,36+1-0x20
add r24,r18
adc r25,r19
sts sum_adc+1,r25
sts sum_adc,r24
// sum_adc -= adc_buffer[adc_index];
lds r18,sum_adc ; why not "mov r18,r24" "mov r19,r25" ?
Presumably, because you are using an outdated version of avr-gcc. The
oldest version I have handy is avr-gcc 4.7, and with that, the generated
code is different. But very likely, your "missed optimization" roots
somewhere in the extra obfuscation "...".
lds r19,sum_adc+1
lds r30,adc_index
ldi r31,lo8(0) ;why not "clr r31"?
Because LDI *,0 performs as well as CLR * but with the advantage that
the former does not clobber SREG.
ldi r24,lo8(adc_buffer)
ldi r25,hi8(adc_buffer)
lsl r30
rol r31
add r30,r24
adc r31,r25
ld r20,Z
ldd r21,Z+1
sub r18,r20
sbc r19,r21
sts sum_adc+1,r19
sts sum_adc,r18
// analog = (uint16_t) (sum_adc >> 3);
lds r18,sum_adc ; loading into r18, r19 the same values
they alredy hold!
lds r19,sum_adc+1
lsr r19
ror r18
lsr r19
ror r18
lsr r19
ror r18
This shift appears to be invoked by -O2 or -O3, not by -Os as stated above.
sts analog+1,r19
sts analog,r18
Just for the recored, I compiled the following C code
#include <avr/io.h>
uint16_t sum_adc;
uint16_t analog;
uint16_t adc_buffer[64];
uint8_t adc_index;
void func (void)
{
sum_adc += ADC;
sum_adc -= adc_buffer[adc_index];
analog = (uint16_t) (sum_adc >> 3);
}
with
$ avr-gcc-4.7 code.c -mmcu=attiny85 -S -O2
and the resulting code.s reads:
func:
in r24,0x4
in r25,0x4+1
lds r18,sum_adc
lds r19,sum_adc+1
add r24,r18
adc r25,r19
lds r30,adc_index
ldi r31,0
lsl r30
rol r31
subi r30,lo8(-(adc_buffer))
sbci r31,hi8(-(adc_buffer))
ld r18,Z
ldd r19,Z+1
sub r24,r18
sbc r25,r19
sts sum_adc+1,r25
sts sum_adc,r24
lsr r25
ror r24
lsr r25
ror r24
lsr r25
ror r24
sts analog+1,r25
sts analog,r24
ret
Johann