This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/34789] New: Missed optimisation on avr - sometimes the compiler keeps addresses in registers unnecessarily


On RISC cpus with many registers, it is often helpful to keep constants (such
as addresses) in registers for later use, since loading a register with a
constant takes longer than moving data between registers, and since
register-constant operations are seldom available.  On the AVR, however,
register-constant operations are just as small and fast as register-register
operations (excluding the movw operation), so it is often better to use the
constants directly - it saves a few instructions (time and code space), and
avoids tying up a register pair unnecessarily.

Example:

extern uint16_t data[64];
extern uint16_t foo(uint16_t x);
extern uint16_t a;

uint16_t bar(void) {
        uint16_t x;
        x = foo(data[a]);
        return foo(data[x]);
}

In this case, the compiler caches the address of "data" in r16:r17 :

  59                    bar:
  60                    /* prologue: frame size=0 */
  61 001a 0F93                  push r16
  62 001c 1F93                  push r17
  63                    /* prologue end (size=2) */
  64 001e E091 0000             lds r30,a        ;  a, a
  65 0022 F091 0000             lds r31,(a)+1    ;  a, a
  66 0026 00E0                  ldi r16,lo8(data)        ;  tmp45,
  67 0028 10E0                  ldi r17,hi8(data)        ;  tmp45,
  68 002a EE0F                  lsl r30  ;  a
  69 002c FF1F                  rol r31  ;  a
  70 002e E00F                  add r30,r16      ;  a, tmp45
  71 0030 F11F                  adc r31,r17      ;  a, tmp45
  72 0032 8081                  ld r24,Z         ; , data
  73 0034 9181                  ldd r25,Z+1      ; , data
  74 0036 0E94 0000             call foo         ; 
  75 003a 880F                  lsl r24  ;  tmp50
  76 003c 991F                  rol r25  ;  tmp50
  77 003e 080F                  add r16,r24      ;  tmp45, tmp50
  78 0040 191F                  adc r17,r25      ;  tmp45, tmp50
  79 0042 F801                  movw r30,r16     ; , tmp45
  80 0044 8081                  ld r24,Z         ; , data
  81 0046 9181                  ldd r25,Z+1      ; , data
  82 0048 0E94 0000             call foo         ; 
  83                    /* epilogue: frame size=0 */
  84 004c 1F91                  pop r17
  85 004e 0F91                  pop r16
  86 0050 0895                  ret

Better code could be generated by using "data" directly:

                        ; Prologue avoided - saved 2 words code
                                lds r30, a
                                lds r31, (a) + 1
                        ; Load of r16:r17 avoided - saved 2 words code
                                lsl r30 ; a
                                rol r31 ; a
                                subi r30, lo8(-(data))
                                sbci r31, hi8(-(data))
                                ld r24, z
                                ldd r25, Z+1
                                call foo
                                lsl r24 ; x
                                rol r25 ; x
                        ; Using constant for data is just as small as register
                                subi r24, lo8(-(data))
                                sbci r25, hi8(-(data))
                                movw r30, r16
                                ld r24, z
                                ldd r25, Z+1
                                call foo
                        ; Epilogue avoided - saved 2 words code
                                ret

This saves 6 code words, and corresponding time.


-- 
           Summary: Missed optimisation on avr - sometimes the compiler
                    keeps addresses in registers unnecessarily
           Product: gcc
           Version: 4.2.2
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: david at westcontrol dot com
GCC target triplet: avrgcc


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]