Problem with -fcaller-saves is that there are situations where it triggers an expensive frame just to store a variable around a function call even though there are plenty of call-saved registers.

Example:

typedef __UINT8_TYPE__ uint8_t;

extern uint8_t uart0_getc (void);

void foo (uint8_t *buffer, uint8_t cnt)
{
  while (--cnt)
    {
      *buffer++ = uart0_getc();
    }
}

$ avr-gcc -Os -S -dp -mmcu=atmega8 loop-buf.c

$ avr-gcc gcc -B$TV -Os -c -save-temps -dp -mmcu=atmega8 loop-buf.c && avr-size loop-buf.o
   text    data     bss     dec     hex filename
     50       0       0      50      32 loop-buf.o

$ avr-gcc -Os -c -save-temps -dp -mmcu=atmega8 loop-buf.c -fno-caller-saves && avr-size loop-buf.o
   text    data     bss     dec     hex filename
     32       0       0      32      20 loop-buf.o

I actually came never across a situation where -fcaller-saves improved the code performance, hence this patch proposes to switch off -fcaller-saved per default.

I can test the patch without regressions, but what bothers me is the following lines in ira-color.c:allocno_reload_assign()

      if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0
          && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a),
                                              call_used_reg_set))
        {
          ira_assert (flag_caller_saves);
          caller_save_needed = 1;
        }

What's not clear is whether this assertion is about the inner working of IRA as alloc depends on caller-saves in other places of IRA, or if caller-saves is needed because otherwise IRA cannot resolve complicated reload situations and hence the proposed change might trigger ICEs for complex programs.

Therefore CCed Vladimir who added the assertion to IRA.

Ok to apply if IRA can do without caller-saves?


Johann


        PR 70677
        * common/config/avr/avr-common.c (avr_option_optimization_table)
        [OPT_LEVELS_ALL]: Turn off -fcaller-saves.


Index: common/config/avr/avr-common.c
===================================================================
--- common/config/avr/avr-common.c	(revision 238849)
+++ common/config/avr/avr-common.c	(working copy)
@@ -28,6 +28,9 @@
 static const struct default_options avr_option_optimization_table[] =
   {
     { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    // The only effect of -fcaller-saves might be that it triggers
+    // a frame without need when it tries to be smart around calls.
+    { OPT_LEVELS_ALL, OPT_fcaller_saves, NULL, 0 },
     { OPT_LEVELS_NONE, 0, NULL, 0 }
   };
 

Reply via email to