avr-libc-dev
[Top][All Lists]
Advanced

[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





reply via email to

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