[RS6000] Don't restore fixed regs

Message ID 20170811025815.GM16312@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra Aug. 11, 2017, 2:58 a.m.
As noted in fixed_reg_p comment

/* Return whether REG is a global user reg or has been specifed by
   -ffixed-REG.  We should not restore these, and so cannot use
   lmw or out-of-line restore functions if there are any.  We also
   can't save them (well, emit frame notes for them), because frame
   unwinding during exception handling will restore saved registers.  */

	* config/rs6000/rs6000.c (rs6000_savres_strategy): Don't restore
	fixed regs.

Bootstrapped and regression tested powerpc64-linux (-m32 too) and
powerpc64le-linux.  OK?

Comments

Segher Boessenkool Aug. 15, 2017, 2:45 a.m. | #1
Hi!

Sorry the review took a while.

On Fri, Aug 11, 2017 at 12:28:16PM +0930, Alan Modra wrote:
> 	* config/rs6000/rs6000.c (rs6000_savres_strategy): Don't restore
> 	fixed regs.

> diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
> index 74158cd..b628808 100644
> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -24309,6 +24309,7 @@ rs6000_savres_strategy (rs6000_stack_t *info,
>  			bool using_static_chain_p)
>  {
>    int strategy = 0;
> +  int i;

Let's not move declarations to three screens before the first use.  You
can conveniently declare the loop counters straight in the "for" itself,
like  for (int i = 0; i < n; i++)  .

Okay for trunk, with that improvement please.


Segher

Patch

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 74158cd..b628808 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -24309,6 +24309,7 @@  rs6000_savres_strategy (rs6000_stack_t *info,
 			bool using_static_chain_p)
 {
   int strategy = 0;
+  int i;
 
   /* Select between in-line and out-of-line save and restore of regs.
      First, all the obvious cases where we don't use out-of-line.  */
@@ -24383,6 +24384,17 @@  rs6000_savres_strategy (rs6000_stack_t *info,
 		 | SAVE_INLINE_GPRS
 		 | SAVE_INLINE_VRS);
 
+  /* Don't ever restore fixed regs.  That means we can't use the
+     out-of-line register restore functions if a fixed reg is in the
+     range of regs restored.   */
+  if (!(strategy & REST_INLINE_FPRS))
+    for (i = info->first_fp_reg_save; i < 64; i++)
+      if (fixed_regs[i])
+	{
+	  strategy |= REST_INLINE_FPRS;
+	  break;
+	}
+
   /* We can only use the out-of-line routines to restore fprs if we've
      saved all the registers from first_fp_reg_save in the prologue.
      Otherwise, we risk loading garbage.  Of course, if we have saved
@@ -24390,10 +24402,8 @@  rs6000_savres_strategy (rs6000_stack_t *info,
   if ((strategy & SAVE_INLINE_FPRS)
       && !(strategy & REST_INLINE_FPRS))
     {
-      int i;
-
       for (i = info->first_fp_reg_save; i < 64; i++)
-	if (fixed_regs[i] || !save_reg_p (i))
+	if (!save_reg_p (i))
 	  {
 	    strategy |= REST_INLINE_FPRS;
 	    break;
@@ -24401,13 +24411,19 @@  rs6000_savres_strategy (rs6000_stack_t *info,
     }
 
   /* Similarly, for altivec regs.  */
+  if (!(strategy & REST_INLINE_VRS))
+    for (i = info->first_altivec_reg_save; i < LAST_ALTIVEC_REGNO + 1; i++)
+      if (fixed_regs[i])
+	{
+	  strategy |= REST_INLINE_VRS;
+	  break;
+	}
+
   if ((strategy & SAVE_INLINE_VRS)
       && !(strategy & REST_INLINE_VRS))
     {
-      int i;
-
       for (i = info->first_altivec_reg_save; i < LAST_ALTIVEC_REGNO + 1; i++)
-	if (fixed_regs[i] || !save_reg_p (i))
+	if (!save_reg_p (i))
 	  {
 	    strategy |= REST_INLINE_VRS;
 	    break;
@@ -24467,6 +24483,16 @@  rs6000_savres_strategy (rs6000_stack_t *info,
 	  }
     }
 
+  /* Don't ever restore fixed regs.  */
+  if ((strategy & (REST_INLINE_GPRS | REST_MULTIPLE)) != REST_INLINE_GPRS)
+    for (i = info->first_gp_reg_save; i < 32; i++)
+      if (fixed_reg_p (i))
+	{
+	  strategy |= REST_INLINE_GPRS;
+	  strategy &= ~REST_MULTIPLE;
+	  break;
+	}
+
   /* We can only use load multiple or the out-of-line routines to
      restore gprs if we've saved all the registers from
      first_gp_reg_save.  Otherwise, we risk loading garbage.
@@ -24475,10 +24501,8 @@  rs6000_savres_strategy (rs6000_stack_t *info,
   if ((strategy & (SAVE_INLINE_GPRS | SAVE_MULTIPLE)) == SAVE_INLINE_GPRS
       && (strategy & (REST_INLINE_GPRS | REST_MULTIPLE)) != REST_INLINE_GPRS)
     {
-      int i;
-
       for (i = info->first_gp_reg_save; i < 32; i++)
-	if (fixed_reg_p (i) || !save_reg_p (i))
+	if (!save_reg_p (i))
 	  {
 	    strategy |= REST_INLINE_GPRS;
 	    strategy &= ~REST_MULTIPLE;