rs6000: Some rs6000_emit_epilogue improvements
authorSegher Boessenkool <segher@kernel.crashing.org>
Fri, 17 May 2019 22:10:29 +0000 (00:10 +0200)
committerSegher Boessenkool <segher@gcc.gnu.org>
Fri, 17 May 2019 22:10:29 +0000 (00:10 +0200)
This uses epilogue_type directly.  It also changes some ints to bools,
declares variables later, and simplifies some code.

There is one actual change:

   else if (info->push_p
           && DEFAULT_ABI != ABI_V4
-          && !crtl->calls_eh_return)
+          && epilogue_type != EPILOGUE_TYPE_EH_RETURN)
     {
       /* Prevent reordering memory accesses against stack pointer restore.  */

(different because calls_eh_return can be true for sibcalls).  This is
a bugfix.  The code was never exercised.

One place in the epilogue still uses crtl->calls_eh_return.  If that
is changed the prologue has to have a corresponding change, and the
emit_prologue function does not have an epilogue_type parameter, so
bail on changing this for now.  We might want to do this (saving the
CR fields to separate stack slots) always, not just for functions
calling eh_return, but that will require more investigation.

* config/rs6000/rs6000.c (restore_saved_cr): Change a boolean
argument to be type bool (was int before).
(rs6000_emit_epilogue): Simplify some code.  Declare some variables
at first use.  Use type bool for some variables.  Fix a theoretical
eh_return bug for svr4.

From-SVN: r271361

gcc/ChangeLog
gcc/config/rs6000/rs6000.c

index 988a86040a2171c011eebdff0ab46420ace59c22..0d27fffccd9532d3237eb47822095fb1333b7f5d 100644 (file)
@@ -1,3 +1,11 @@
+2019-05-17  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       * config/rs6000/rs6000.c (restore_saved_cr): Change a boolean
+       argument to be type bool (was int before).
+       (rs6000_emit_epilogue): Simplify some code.  Declare some variables
+       at first use.  Use type bool for some variables.  Fix a theoretical
+       eh_return bug for svr4.
+
 2019-05-17  Segher Boessenkool  <segher@kernel.crashing.org>
 
        * config/rs6000/rs6000.md (isa): New attribute.
index 7f7b1674c1a832931778d87c6c5953f7fb49a244..6cbff91260669e94d3c8d4c9a487169ff1be5334 100644 (file)
@@ -27712,7 +27712,7 @@ load_cr_save (int regno, rtx frame_reg_rtx, int offset, bool exit_func)
 /* Reload CR from REG.  */
 
 static void
-restore_saved_cr (rtx reg, int using_mfcr_multiple, bool exit_func)
+restore_saved_cr (rtx reg, bool using_mfcr_multiple, bool exit_func)
 {
   int count = 0;
   int i;
@@ -27876,15 +27876,6 @@ emit_cfa_restores (rtx cfa_restores)
 void
 rs6000_emit_epilogue (enum epilogue_type epilogue_type)
 {
-  int sibcall = (epilogue_type == EPILOGUE_TYPE_SIBCALL);
-  rs6000_stack_t *info;
-  int restoring_GPRs_inline;
-  int restoring_FPRs_inline;
-  int using_load_multiple;
-  int using_mtcr_multiple;
-  int use_backchain_to_restore_sp;
-  int restore_lr;
-  int strategy;
   HOST_WIDE_INT frame_off = 0;
   rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
   rtx frame_reg_rtx = sp_reg_rtx;
@@ -27896,30 +27887,38 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
   machine_mode fp_reg_mode = TARGET_HARD_FLOAT ? DFmode : SFmode;
   int fp_reg_size = 8;
   int i;
-  bool exit_func;
   unsigned ptr_regno;
 
-  info = rs6000_stack_info ();
+  rs6000_stack_t *info = rs6000_stack_info ();
+
+  if (epilogue_type == EPILOGUE_TYPE_NORMAL && crtl->calls_eh_return)
+    epilogue_type = EPILOGUE_TYPE_EH_RETURN;
+
+  int strategy = info->savres_strategy;
+  bool using_load_multiple = !!(strategy & REST_MULTIPLE);
+  bool restoring_GPRs_inline = !!(strategy & REST_INLINE_GPRS);
+  bool restoring_FPRs_inline = !!(strategy & REST_INLINE_FPRS);
+  if (epilogue_type == EPILOGUE_TYPE_SIBCALL)
+    {
+      restoring_GPRs_inline = true;
+      restoring_FPRs_inline = true;
+    }
+
+  bool using_mtcr_multiple = (rs6000_tune == PROCESSOR_PPC601
+                             || rs6000_tune == PROCESSOR_PPC603
+                             || rs6000_tune == PROCESSOR_PPC750
+                             || optimize_size);
 
-  strategy = info->savres_strategy;
-  using_load_multiple = strategy & REST_MULTIPLE;
-  restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
-  restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
-  using_mtcr_multiple = (rs6000_tune == PROCESSOR_PPC601
-                        || rs6000_tune == PROCESSOR_PPC603
-                        || rs6000_tune == PROCESSOR_PPC750
-                        || optimize_size);
   /* Restore via the backchain when we have a large frame, since this
      is more efficient than an addis, addi pair.  The second condition
      here will not trigger at the moment;  We don't actually need a
      frame pointer for alloca, but the generic parts of the compiler
      give us one anyway.  */
-  use_backchain_to_restore_sp = (info->total_size + (info->lr_save_p
-                                                    ? info->lr_save_offset
-                                                    : 0) > 32767
-                                || (cfun->calls_alloca
-                                    && !frame_pointer_needed));
-  restore_lr = (info->lr_save_p
+  bool use_backchain_to_restore_sp
+    = (info->total_size + (info->lr_save_p ? info->lr_save_offset : 0) > 32767
+       || (cfun->calls_alloca && !frame_pointer_needed));
+
+  bool restore_lr = (info->lr_save_p
                && (restoring_FPRs_inline
                    || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
                && (restoring_GPRs_inline
@@ -27929,10 +27928,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
 
   if (WORLD_SAVE_P (info))
     {
-      int i, j;
-      char rname[30];
-      const char *alloc_rname;
-      rtvec p;
+      gcc_assert (epilogue_type != EPILOGUE_TYPE_SIBCALL);
 
       /* eh_rest_world_r10 will return to the location saved in the LR
         stack slot (which is not likely to be our caller.)
@@ -27941,19 +27937,31 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
         The exception-handling stuff that was here in 2.95 is no
         longer necessary.  */
 
+      rtvec p;
       p = rtvec_alloc (9
                       + 32 - info->first_gp_reg_save
                       + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
                       + 63 + 1 - info->first_fp_reg_save);
 
-      strcpy (rname, ((crtl->calls_eh_return) ?
-                     "*eh_rest_world_r10" : "*rest_world"));
-      alloc_rname = ggc_strdup (rname);
+      const char *rname;
+      switch (epilogue_type)
+       {
+       case EPILOGUE_TYPE_NORMAL:
+         rname = ggc_strdup ("*rest_world");
+         break;
 
-      j = 0;
+       case EPILOGUE_TYPE_EH_RETURN:
+         rname = ggc_strdup ("*eh_rest_world_r10");
+         break;
+
+       default:
+         gcc_unreachable ();
+       }
+
+      int j = 0;
       RTVEC_ELT (p, j++) = ret_rtx;
       RTVEC_ELT (p, j++)
-       = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
+       = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, rname));
       /* The instruction pattern requires a clobber here;
         it is shared with the restVEC helper. */
       RTVEC_ELT (p, j++) = gen_hard_reg_clobber (Pmode, 11);
@@ -27972,6 +27980,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
          }
       }
 
+      int i;
       for (i = 0; i < 32 - info->first_gp_reg_save; i++)
        {
          rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
@@ -28196,7 +28205,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
     }
   else if (info->push_p
           && DEFAULT_ABI != ABI_V4
-          && !crtl->calls_eh_return)
+          && epilogue_type != EPILOGUE_TYPE_EH_RETURN)
     {
       /* Prevent reordering memory accesses against stack pointer restore.  */
       if (cfun->calls_alloca
@@ -28356,9 +28365,9 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
      function will deallocate the stack, so we don't need to worry
      about the unwinder restoring cr from an invalid stack frame
      location.  */
-  exit_func = (!restoring_FPRs_inline
-              || (!restoring_GPRs_inline
-                  && info->first_fp_reg_save == 64));
+  bool exit_func = (!restoring_FPRs_inline
+                   || (!restoring_GPRs_inline
+                       && info->first_fp_reg_save == 64));
 
   /* In the ELFv2 ABI we need to restore all call-saved CR fields from
      *separate* slots if the routine calls __builtin_eh_return, so
@@ -28424,7 +28433,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
     restore_saved_lr (0, exit_func);
 
   /* Load exception handler data registers, if needed.  */
-  if (!sibcall && crtl->calls_eh_return)
+  if (epilogue_type == EPILOGUE_TYPE_EH_RETURN)
     {
       unsigned int i, regno;
 
@@ -28615,13 +28624,13 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
       RTX_FRAME_RELATED_P (insn) = 1;
     }
 
-  if (!sibcall && crtl->calls_eh_return)
+  if (epilogue_type == EPILOGUE_TYPE_EH_RETURN)
     {
       rtx sa = EH_RETURN_STACKADJ_RTX;
       emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
     }
 
-  if (!sibcall && restoring_FPRs_inline)
+  if (epilogue_type != EPILOGUE_TYPE_SIBCALL && restoring_FPRs_inline)
     {
       if (cfa_restores)
        {
@@ -28646,7 +28655,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
       emit_jump_insn (targetm.gen_simple_return ());
     }
 
-  if (!sibcall && !restoring_FPRs_inline)
+  if (epilogue_type != EPILOGUE_TYPE_SIBCALL && !restoring_FPRs_inline)
     {
       bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
       rtvec p = rtvec_alloc (3 + !!lr + 64 - info->first_fp_reg_save);
@@ -28685,7 +28694,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
 
   if (cfa_restores)
     {
-      if (sibcall)
+      if (epilogue_type == EPILOGUE_TYPE_SIBCALL)
        /* Ensure the cfa_restores are hung off an insn that won't
           be reordered above other restores.  */
        emit_insn (gen_blockage ());