http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50448

             Bug #: 50448
           Summary: [avr] Missed optimization accessing struct component
                    with known, absolute address.
    Classification: Unclassified
           Product: gcc
           Version: 4.6.1
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: g...@gcc.gnu.org
                CC: eric.wedding...@atmel.com
            Target: avr


typedef struct
{
    unsigned char a,b,c,d;
} SPI_t;

#define SPIE (*(SPI_t volatile*) 0x0AC0)

void foo (void)
{
    SPIE.d = 0xAA;
    while (!(SPIE.c & 0x80));

    SPIE.d = 0xBB;
    while (!(SPIE.c & 0x80));
}

avr-gcc-4.6.1 -Os -S -fdump-tree-optimized -fdump-rtl-expand 
compiles that code to

foo:
    ldi r24,lo8(-86)
    ldi r30,lo8(2752)
    ldi r31,hi8(2752)
    std Z+3,r24
.L2:
    lds r24,2754
    sbrs r24,7
    rjmp .L2
    ldi r24,lo8(-69)
    ldi r30,lo8(2752)
    ldi r31,hi8(2752)
    std Z+3,r24
.L3:
    lds r24,2754
    sbrs r24,7
    rjmp .L3
    ret

Instead of loading the address 2752 two times, it's sufficient to load it once
or to do a direct access to 2755 and avoid loading the constant altogether.

The load appeard first in .expand; .optimized looks fine:

foo ()
{
  signed char D.1932;
  volatile unsigned char D.1931;
  signed char D.1930;
  volatile unsigned char D.1929;

<bb 2>:
  MEM[(volatile struct SPI_t *)2752B].d ={v} 170;

<bb 3>:
  D.1929_3 ={v} MEM[(volatile struct SPI_t *)2752B].c;
  D.1930_4 = (signed char) D.1929_3;
  if (D.1930_4 >= 0)
    goto <bb 3>;
  else
    goto <bb 4>;

<bb 4>:
  MEM[(volatile struct SPI_t *)2752B].d ={v} 187;

<bb 5>:
  D.1931_7 ={v} MEM[(volatile struct SPI_t *)2752B].c;
  D.1932_8 = (signed char) D.1931_7;
  if (D.1932_8 >= 0)
    goto <bb 5>;
  else
    goto <bb 6>;

<bb 6>:
  return;
}

Reply via email to