On 09/28/2011 02:14 PM, Georg-Johann Lay wrote:
This leads to unpleasant code. The machine can access all RAM locations by
direct addressing. However, the resulting code is:

foo:
        ldi r24,lo8(-86)         ;  6   *movqi/2        [length = 1]
        ldi r30,lo8(-64)         ;  34  *movhi/5        [length = 2]
        ldi r31,lo8(10)
        std Z+3,r24      ;  7   *movqi/3        [length = 1]
.L2:
        lds r24,2754     ;  10  *movqi/4        [length = 2]
        sbrs r24,7       ;  43  *sbrx_branchhi  [length = 2]
        rjmp .L2
        ldi r24,lo8(-69)         ;  16  *movqi/2        [length = 1]
        ldi r30,lo8(-64)         ;  33  *movhi/5        [length = 2]
        ldi r31,lo8(10)
        std Z+3,r24      ;  17  *movqi/3        [length = 1]
.L3:
        lds r24,2754     ;  20  *movqi/4        [length = 2]
        sbrs r24,7       ;  42  *sbrx_branchhi  [length = 2]
        rjmp .L3
        ret      ;  39  return  [length = 1]

Insn 34 loads 2752 (0xAC0) to r30/r31 (Z) and does an indirect access (*(Z+3),
i.e. *2755) in insn 7.  The same happens in insn 33 (load 2752) and access
(insn 17).

Is there a way to avoid this? I tried -f[no-]rerun-cse-after-loop but without
effect, same for -Os/-O2 and trying to patch rtx_costs. cse_not_expected is
overridden in some places in the middle-end.

fwprop should take care of propagating the address. Have you tried patching address_costs? Might be as simple as this (untested):

Index: avr.c
===================================================================
--- avr.c       (revision 177688)
+++ avr.c       (working copy)
@@ -5986,8 +5986,8 @@ avr_address_cost (rtx x, bool speed ATTR
     return 18;
   if (CONSTANT_ADDRESS_P (x))
     {
-      if (optimize > 0 && io_address_operand (x, QImode))
-       return 2;
+      if (optimize > 0)
+       return io_address_operand (x, QImode) ? 2 : 3;
       return 4;
     }
   return 4;

Paolo

Reply via email to