With the following, small C test program typedef struct { unsigned char a, b, c, d; } s_t; unsigned char func1 (s_t *x, s_t *y, s_t *z) { unsigned char s = 0; s += x->a; s += y->a; s += z->a; s += x->b; s += y->b; s += z->b; s += x->c; s += y->c; s += z->c; return s; } there is a frame pointer set up for no apparent reason. The machine for which this code is compiled for (AVR) has just few pointer registers and taking away one of them to use it as frame pointer leads to severe performance degradation in many real-world programs: moving from/to memory is more expensive than movon around registers, setting up a frame is expensive and taking away 1 of 2 address registers is expensive. What I tried and what did not fix it: - increase targetm.memory_move_cost (up to unsane value) - play around with targetm.class_likely_spilled_p The program is compiled with $ avr-gcc in.c -S -Os -fdump-rtl-ira-details -fdump-rtl-postreload-details -mmcu=avr4 -mstrict-X with avr-gcc from current trunk SVN r180399. The issue is that AVR has only 3 pointer registers X, Y, and Z with the following addressing capabilities: *X, *X++, *--X (R27:R26, call-clobbered) *Y, *Y++, *--Y, *(Y+const) (R28:R29, call-saved, frame pointer) *Z, *Z++, *--Z, *(Z+const) (R30:R31, call-clobbered) Older version of the compiler prior to 4.7 trunk r179993 allowed a fake addressing mode *(X+const) and emulated it by emitting appropriate instructions sequence like X = X + const r = *X X = X - const which was only a rare corner case in the old register allocator, but in the new allocator this sequence is seen very often leading to code bloat of +50% for some real-world functions. This is the reason why the command line option -mstrict-X has been added to the AVR backend, see PR46278. This option denies fake *(X+const) addressing but leads to the mentioned spills from register allocator and to code even worse as compared to without setting -mstrict-X, i.e. register allocator sabotages a smart usage of the address registers. All I see is that reload1.c:alter_reg() generates the spill because ira_conflicts_p is true. With the option -morder1 turn on (affects ADJUST_REG_ALLOC_ORDER) there is still a frame set up even though never accessed. Can anyone give me some advice how to proceed with this issue? Can be said if this is a target issue or IRA/reload flaw? FYI, you find attached the IRA dump as generated with the above command line Thanks for any hints! Johann GCC configured with: --target=avr --disable-nls --disable-shared --enable-languages=c,c++ --with-dwarf2 --disable-lto --enable-checking=yes,rtl --enable-doc