This is the mail archive of the gcc-patches@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]

[PowerPC] Fix pr25212


This patch provides a function that returns the reg class of an input
reload for a given piece of rtl, allowing address and memory predicates
to see what is happening in reload.  I use this in
legitimate_indexed_address_p to match addresses that have already had
some reloads, catching more cases than my fix for PR24997.

While fiddling with this patch, I noticed that INT_REG_OK_FOR_BASE_P can
return true for a pseudo reg that has reg_renumber[REGNO] == 0, so I
fixed this problem too.  Bootstrap and regression tests on powerpc-linux
and powerpc64-linux in progress.  OK for mainline and 4.1 assuming no
regressions?  (If input_reload_for doesn't seem generally useful, I can
move it to rs6000.c.)

:ADD_PATCH target, middle-end:

	PR target/25212
	* reload.c (input_reload_for): New function.
	* reload.h (input_reload_for): Prototype.
	* config/rs6000/rs6000.c (is_base_index): New function.
	(legitimate_indexed_address_p): Use is_base_index.
	* config/rs6000/rs6000.h (INT_REG_OK_FOR_INDEX_P): Simplify.
	(INT_REG_OK_FOR_BASE_P): Correct.

Index: gcc/reload.c
===================================================================
--- gcc/reload.c	(revision 107839)
+++ gcc/reload.c	(working copy)
@@ -1576,6 +1576,18 @@ dup_replacements (rtx *dup_loc, rtx *ori
 	push_replacement (dup_loc, r->what, r->mode);
     }
 }
+
+/* Return the reg_class for an input reload stored by push_reload.  */
+
+enum reg_class
+input_reload_for (rtx x)
+{
+  int i;
+  for (i = 0; i < n_reloads; i++)
+    if (rld[i].in == x)
+      return rld[i].class;
+  return NO_REGS;
+}
 
 /* Transfer all replacements that used to be in reload FROM to be in
    reload TO.  */
Index: gcc/reload.h
===================================================================
--- gcc/reload.h	(revision 107839)
+++ gcc/reload.h	(working copy)
@@ -322,6 +322,9 @@ extern int push_reload (rtx, rtx, rtx *,
 			enum machine_mode, enum machine_mode,
 			int, int, int, enum reload_type);
 
+/* Return the reg_class for an input reload stored by push_reload.  */
+extern enum reg_class input_reload_for (rtx) ATTRIBUTE_PURE;
+
 /* Functions in postreload.c:  */
 extern void reload_cse_regs (rtx);
 
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 107839)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -2717,6 +2712,20 @@ rs6000_legitimate_offset_address_p (enum
 
   offset += 0x8000;
   return (offset < 0x10000) && (offset + extra < 0x10000);
+}
+
+static bool
+is_base_index (rtx rb, rtx ri, int strict)
+{
+  enum reg_class rld;
+
+  return (((REG_P (rb) && INT_REG_OK_FOR_BASE_P (rb, strict))
+	   || (reload_in_progress
+	       && input_reload_for (rb) == BASE_REG_CLASS))
+	  && ((REG_P (ri) && INT_REG_OK_FOR_INDEX_P (ri, strict))
+	      || (reload_in_progress
+		  && ((rld = input_reload_for (ri)) == INDEX_REG_CLASS
+		      || rld == BASE_REG_CLASS))));
 }
 
 static bool
@@ -2730,23 +2740,7 @@ legitimate_indexed_address_p (rtx x, int
   op0 = XEXP (x, 0);
   op1 = XEXP (x, 1);
 
-  if (REG_P (op0) && REG_P (op1))
-    return ((INT_REG_OK_FOR_BASE_P (op0, strict)
-	     && INT_REG_OK_FOR_INDEX_P (op1, strict))
-	    || (INT_REG_OK_FOR_BASE_P (op1, strict)
-		&& INT_REG_OK_FOR_INDEX_P (op0, strict)));
-
-  /* Recognize the rtl generated by reload which we know will later be
-     replaced by a base reg.  We rely on nothing but reload generating
-     this particular pattern, a reasonable assumption because it is not
-     canonical.  */
-  else if (reload_in_progress
-	   && GET_CODE (op0) == PLUS
-	   && REG_P (XEXP (op0, 0))
-	   && GET_CODE (XEXP (op0, 1)) == CONST_INT
-	   && REG_P (op1))
-    return INT_REG_OK_FOR_INDEX_P (op1, strict);
-  return false;
+  return is_base_index (op0, op1, strict) || is_base_index (op1, op0, strict);
 }
 
 inline bool
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 107839)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -1723,17 +1751,14 @@ typedef struct rs6000_args
 /* Nonzero if X is a hard reg that can be used as an index
    or if it is a pseudo reg in the non-strict case.  */
 #define INT_REG_OK_FOR_INDEX_P(X, STRICT)			\
-  ((! (STRICT)							\
-    && (REGNO (X) <= 31						\
-	|| REGNO (X) == ARG_POINTER_REGNUM			\
-	|| REGNO (X) == FRAME_POINTER_REGNUM			\
-	|| REGNO (X) >= FIRST_PSEUDO_REGISTER))			\
-   || ((STRICT) && REGNO_OK_FOR_INDEX_P (REGNO (X))))
+  ((!(STRICT) && REGNO (X) >= FIRST_PSEUDO_REGISTER)		\
+   || REGNO_OK_FOR_INDEX_P (REGNO (X)))
 
 /* Nonzero if X is a hard reg that can be used as a base reg
    or if it is a pseudo reg in the non-strict case.  */
 #define INT_REG_OK_FOR_BASE_P(X, STRICT)			\
-  (REGNO (X) > 0 && INT_REG_OK_FOR_INDEX_P (X, (STRICT)))
+  ((!(STRICT) && REGNO (X) >= FIRST_PSEUDO_REGISTER)		\
+   || REGNO_OK_FOR_BASE_P (REGNO (X)))
 
 #define REG_OK_FOR_INDEX_P(X) INT_REG_OK_FOR_INDEX_P (X, REG_OK_STRICT_FLAG)
 #define REG_OK_FOR_BASE_P(X)  INT_REG_OK_FOR_BASE_P (X, REG_OK_STRICT_FLAG)

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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