This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[commit] spu: Fix inefficient address generation
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: trevor_smigiel at playstation dot sony dot com
- Date: Thu, 15 Nov 2007 15:33:26 +0100 (CET)
- Subject: [commit] spu: Fix inefficient address generation
Hello,
the following patch fixes an inefficiency in address generation
on SPU: there is no reason why SYMBOL_REF + CONST_INT should not
be allowed as address in load/store instructions, no matter how
large the CONST_INT is.
Tested on spu-elf without regressions.
Approved off-list by Trevor Smigiel; committed to mainline.
Bye,
Ulrich
ChangeLog:
* config/spu/spu-protos.h (legitimate_const): Remove prototype.
* config/spu/spu.c (legitimate_const): Remove.
(classify_immediate): Inline call to legitimate_const.
(spu_legitimate_address): Likewise. Allow SMBOL_REF + CONST_INT
for any constant, not just -512 .. 511.
Index: gcc/config/spu/spu-protos.h
===================================================================
--- gcc/config/spu/spu-protos.h (revision 129930)
+++ gcc/config/spu/spu-protos.h (working copy)
@@ -52,7 +52,6 @@
extern int iohl_immediate_p (rtx op, enum machine_mode mode);
extern int arith_immediate_p (rtx op, enum machine_mode mode,
HOST_WIDE_INT low, HOST_WIDE_INT high);
-extern int legitimate_const (rtx x, int aligned);
extern int spu_constant_address_p (rtx x);
extern int spu_legitimate_constant_p (rtx x);
extern int spu_legitimate_address (enum machine_mode mode, rtx x,
Index: gcc/config/spu/spu.c
===================================================================
--- gcc/config/spu/spu.c (revision 129930)
+++ gcc/config/spu/spu.c (working copy)
@@ -2489,30 +2489,7 @@
return CONST_DOUBLE_FROM_REAL_VALUE (value, mode);
}
-/* Given a (CONST (PLUS (SYMBOL_REF) (CONST_INT))) return TRUE when the
- CONST_INT fits constraint 'K', i.e., is small. */
int
-legitimate_const (rtx x, int aligned)
-{
- /* We can never know if the resulting address fits in 18 bits and can be
- loaded with ila. Instead we should use the HI and LO relocations to
- load a 32-bit address. */
- rtx sym, cst;
-
- gcc_assert (GET_CODE (x) == CONST);
-
- if (GET_CODE (XEXP (x, 0)) != PLUS)
- return 0;
- sym = XEXP (XEXP (x, 0), 0);
- cst = XEXP (XEXP (x, 0), 1);
- if (GET_CODE (sym) != SYMBOL_REF || GET_CODE (cst) != CONST_INT)
- return 0;
- if (aligned && ((INTVAL (cst) & 15) != 0 || !ALIGNED_SYMBOL_REF_P (sym)))
- return 0;
- return satisfies_constraint_K (cst);
-}
-
-int
spu_constant_address_p (rtx x)
{
return (GET_CODE (x) == LABEL_REF || GET_CODE (x) == SYMBOL_REF
@@ -2632,9 +2609,21 @@
return TARGET_LARGE_MEM ? IC_IL2s : IC_IL1s;
case CONST:
- return TARGET_LARGE_MEM
- || !legitimate_const (op, 0) ? IC_IL2s : IC_IL1s;
+ /* We can never know if the resulting address fits in 18 bits and can be
+ loaded with ila. For now, assume the address will not overflow if
+ the displacement is "small" (fits 'K' constraint). */
+ if (!TARGET_LARGE_MEM && GET_CODE (XEXP (op, 0)) == PLUS)
+ {
+ rtx sym = XEXP (XEXP (op, 0), 0);
+ rtx cst = XEXP (XEXP (op, 0), 1);
+ if (GET_CODE (sym) == SYMBOL_REF
+ && GET_CODE (cst) == CONST_INT
+ && satisfies_constraint_K (cst))
+ return IC_IL1s;
+ }
+ return IC_IL2s;
+
case HIGH:
return IC_IL1s;
@@ -2884,8 +2873,18 @@
return !TARGET_LARGE_MEM;
case CONST:
- return !TARGET_LARGE_MEM && legitimate_const (x, 0);
+ if (!TARGET_LARGE_MEM && GET_CODE (XEXP (x, 0)) == PLUS)
+ {
+ rtx sym = XEXP (XEXP (x, 0), 0);
+ rtx cst = XEXP (XEXP (x, 0), 1);
+ /* Accept any symbol_ref + constant, assuming it does not
+ wrap around the local store addressability limit. */
+ if (GET_CODE (sym) == SYMBOL_REF && GET_CODE (cst) == CONST_INT)
+ return 1;
+ }
+ return 0;
+
case CONST_INT:
return INTVAL (x) >= 0 && INTVAL (x) <= 0x3ffff;
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com