Patchwork Fix PR rtl-optimization/54290

login
register
mail settings
Submitter Eric Botcazou
Date Sept. 18, 2012, 10:17 p.m.
Message ID <19544660.rkmkao6voe@polaris>
Download mbox | patch
Permalink /patch/184862/
State New
Headers show

Comments

Eric Botcazou - Sept. 18, 2012, 10:17 p.m.
> In any case, the change in the condition you noticed was introduced by a
> recent patch by Bernd:
> http://gcc.gnu.org/ml/gcc-patches/2012-08/msg00171.html
> 
> It seems that we ought to use a similar test to what Bernd introduced in
> gen_reload, that is, use the "replaced_subreg" routine on rld[r].in, check
> whether the result is a hard register and use its REGNO_REG_CLASS.

OK, thanks to both.  Revised version attached, OK for mainline after testing?


2012-09-18  Eric Botcazou  <ebotcazou@adacore.com>

	PR rtl-optimization/54290
	* reload1.c (choose_reload_regs): Also take into account secondary MEMs
	to remove address replacements for inherited reloads.
	(replaced_subreg): Move around.

Patch

Index: reload1.c
===================================================================
--- reload1.c	(revision 191365)
+++ reload1.c	(working copy)
@@ -6352,6 +6352,20 @@  choose_reload_regs_init (struct insn_cha
 			      rld[i].when_needed, rld[i].mode);
 }
 
+#ifdef SECONDARY_MEMORY_NEEDED
+/* If X is not a subreg, return it unmodified.  If it is a subreg,
+   look up whether we made a replacement for the SUBREG_REG.  Return
+   either the replacement or the SUBREG_REG.  */
+
+static rtx
+replaced_subreg (rtx x)
+{
+  if (GET_CODE (x) == SUBREG)
+    return find_replacement (&SUBREG_REG (x));
+  return x;
+}
+#endif
+
 /* Assign hard reg targets for the pseudo-registers we must reload
    into hard regs for this insn.
    Also output the instructions to copy them in and out of the hard regs.
@@ -6942,7 +6956,7 @@  choose_reload_regs (struct insn_chain *c
       for (j = 0; j < n_reloads; j++)
 	{
 	  int r = reload_order[j];
-	  rtx check_reg;
+	  rtx check_reg, tem;
 	  if (reload_inherited[r] && rld[r].reg_rtx)
 	    check_reg = rld[r].reg_rtx;
 	  else if (reload_override_in[r]
@@ -6974,10 +6988,26 @@  choose_reload_regs (struct insn_chain *c
 	     If we succeeded removing some reload and we are doing a preliminary
 	     pass just to remove such reloads, make another pass, since the
 	     removal of one reload might allow us to inherit another one.  */
-	  else if (rld[r].in
+	  else if (pass
+		   && rld[r].in
+		   && rld[r].out != rld[r].in
+		   && remove_address_replacements (rld[r].in))
+	    pass = 2;
+#ifdef SECONDARY_MEMORY_NEEDED
+	  /* If we needed a memory location for the reload, we also have to
+	     remove its related reloads.  */
+	  else if (pass
+	           && rld[r].in
 		   && rld[r].out != rld[r].in
-		   && remove_address_replacements (rld[r].in) && pass)
+		   && (tem = replaced_subreg (rld[r].in), REG_P (tem))		   
+		   && REGNO (tem) < FIRST_PSEUDO_REGISTER
+		   && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (tem)),
+					       rld[r].rclass, rld[r].inmode)
+		   && remove_address_replacements
+		      (get_secondary_mem (tem, rld[r].inmode, rld[r].opnum,
+					  rld[r].when_needed)))
 	    pass = 2;
+#endif
 	}
     }
 
@@ -8458,20 +8488,6 @@  emit_insn_if_valid_for_reload (rtx insn)
   return NULL;
 }
 
-#ifdef SECONDARY_MEMORY_NEEDED
-/* If X is not a subreg, return it unmodified.  If it is a subreg,
-   look up whether we made a replacement for the SUBREG_REG.  Return
-   either the replacement or the SUBREG_REG.  */
-
-static rtx
-replaced_subreg (rtx x)
-{
-  if (GET_CODE (x) == SUBREG)
-    return find_replacement (&SUBREG_REG (x));
-  return x;
-}
-#endif
-
 /* Emit code to perform a reload from IN (which may be a reload register) to
    OUT (which may also be a reload register).  IN or OUT is from operand
    OPNUM with reload type TYPE.