Re: How avoid bad optimization in gcc >= 4.3?

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

 



Andrew Haley schrieb:
Georg-Johann Lay wrote:


is there a way to prevent gcc 4.3.x from doing bad optimizations?


We don't have a -fno-bad-optimizations flag; patches welcome!

I could patch it in the avr backend, but IMHO it is not good to
clutter up backend code because the middle end is on a trip ;-)

I attached an example that shows the performance degradation for
a source compiled with -Os (-O2 is similar) for target avr.

The code from the new compiler increased by at about 30%
with respect to good old 3.4.6 and needs more as double
of stack slots (13 instead of 6).

  text    data     bss     dec     hex filename
   156       0       0     156      9c foo-3.4.6.o
   206       0       0     206      ce foo-4.3.2.o

Moreover, it expands a rather trivial address computation into a
multiplication on a target without hardware multiplier, so
there is additional, unacceptable time and code penalty
caused by a call to __mulhi3 from libgcc2.

The multiplication is by -2, i.e. trivial


This is strange.  Can you provide an example of that address
computation as a test case?

Make it just a few lines long, please.


I compiled with
avr-gcc -mmcu=attiny85 -S foo2.c -dp -save-temps -fverbose-asm -Os -fno-keep-inline-functions -fno-common -fno-inline-small-functions -fno-tree-scev-cprop -fno-split-wide-types

Georg-Johann

typedef unsigned int uint8_t __attribute__((__mode__(__QI__)));
typedef unsigned int uint16_t __attribute__ ((__mode__ (__HI__)));

typedef struct
{
    uint8_t timer_val;
    uint16_t puls[10];
    uint8_t codes[];
} powercode_t;

#define pgm_read_word(addr) \
(__extension__({                            \
    uint16_t __addr16 = (uint16_t)(addr);   \
    uint16_t __result;                      \
    __asm__  ("lpm %A0,%a1+\n\tlpm %B0,%a1" : "=r" (__result), "=z" (__addr16) : "1" (__addr16));                                      \
    __result;                               \
}))

void foo2 (uint8_t on_off, powercode_t * code)
{
    uint16_t offtime;

    do
    {
        offtime = pgm_read_word(& code->puls[on_off-1]);
    } while (offtime != 0);
}

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux