This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PowerPC] Fix pr25212
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 2 Dec 2005 23:01:30 +1030
- Subject: [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