This is a mini-patch to fix rtx_costs for SYMBOL_REF.

The cost of a SYMBOL_REF is the same as a CONST_INT because it can be
used the same way.  I observed small performance regression in my code
and found that the reason is too high cost for SYMBOL_REF.

char x[10];

char getx2 (unsigned char i, unsigned char j)
{
    return x[i] + x[j];
}

char getx1 (unsigned char i)
{
    return x[i];
}


Without the patch, in getx2 symbol x in loaded in insn 8 and
then used in insn 9 and insn 12:

getx2:
        ldi r18,lo8(x)   ;  8   *movhi/4        [length = 2]
        ldi r19,hi8(x)
        movw r30,r18     ;  27  *movhi/1        [length = 1]
        add r30,r22      ;  9   *addhi3_zero_extend     [length = 2]
        adc r31,__zero_reg__
        movw r26,r18     ;  28  *movhi/1        [length = 1]
        add r26,r24      ;  12  *addhi3_zero_extend     [length = 2]
        adc r27,__zero_reg__
        ld r25,Z         ;  13  *movqi/4        [length = 1]
        ld r24,X         ;  14  *movqi/4        [length = 1]
        add r24,r25      ;  20  addqi3/1        [length = 1]
        ret      ;  31  return  [length = 1]

getx1:
        ldi r30,lo8(x)   ;  7   *movhi/4        [length = 2]
        ldi r31,hi8(x)
        add r30,r24      ;  8   *addhi3_zero_extend     [length = 2]
        adc r31,__zero_reg__
        ld r24,Z         ;  14  *movqi/4        [length = 1]
        ret      ;  23  return  [length = 1]


With the patch, the symbol is added directly resulting in smaller
and faster code for getx2.  Moreover, register pressure is smaller.
getx1 performs the same as before.

getx2:
        mov r30,r22      ;  27  *movqi/1        [length = 1]
        ldi r31,lo8(0)   ;  28  *movqi/1        [length = 1]
        subi r30,lo8(-(x))       ;  9   *addhi3/4       [length = 2]
        sbci r31,hi8(-(x))
        mov r26,r24      ;  29  *movqi/1        [length = 1]
        ldi r27,lo8(0)   ;  30  *movqi/1        [length = 1]
        subi r26,lo8(-(x))       ;  12  *addhi3/4       [length = 2]
        sbci r27,hi8(-(x))
        ld r25,Z         ;  13  *movqi/4        [length = 1]
        ld r24,X         ;  14  *movqi/4        [length = 1]
        add r24,r25      ;  20  addqi3/1        [length = 1]
        ret      ;  33  return  [length = 1]

getx1:
        mov r30,r24      ;  21  *movqi/1        [length = 1]
        ldi r31,lo8(0)   ;  22  *movqi/1        [length = 1]
        subi r30,lo8(-(x))       ;  8   *addhi3/4       [length = 2]
        sbci r31,hi8(-(x))
        ld r24,Z         ;  14  *movqi/4        [length = 1]
        ret      ;  25  return  [length = 1]


OK to commit?

Johann

        * config/avr/avr.c (avr_rtx_costs): Set cost of SYMBOL_REF to 0.

Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c    (revision 176276)
+++ config/avr/avr.c    (working copy)
@@ -5341,6 +5341,7 @@ avr_rtx_costs (rtx x, int codearg, int o
     {
     case CONST_INT:
     case CONST_DOUBLE:
+    case SYMBOL_REF:
       /* Immediate constants are as cheap as registers.  */
       *total = 0;
       return true;
@@ -5348,7 +5349,6 @@ avr_rtx_costs (rtx x, int codearg, int o
     case MEM:
     case CONST:
     case LABEL_REF:
-    case SYMBOL_REF:
       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
       return true;

Reply via email to