Hi,

The attached patch is to avoid PR target/48596 which is a 4.7
regression on SH.  It seems that now IRA aggressively tried to
use fp regs as the holder for memory addresses on this port.
SH requires a special fpul register to move from the fp regs to
the general regs which are legitimate for pointers and, in
the problematic situation, fpul is already reserved for reload
and the spill failure resulted for the reg equiv processing in RA.
I guess that no other targets have such restrictions.  Perhaps
if there eas a direct way to notify IRA that some register classes
will be too costly for the addresses, SH port will utilize it,
though it looks to be invasive.

The patch tries to work around the problem with increasing the move
cost between fp and general registers for SImode.  The usual tests
are done successfully on sh4-unknown-linux-gnu with no new failures.
A bit surprisingly, there are no size/performance regressions and
a few code size improvements with CSiBE tests I've done.
I'd like to hear the suggestions from the experts before applying
this work around.

Regards,
        kaz
--
        PR target/48596
        * config/sh/sh.c (sh_register_move_cost): Increase cost between
        GENERAL_REGS and FP_REGS for SImode.

--- ORIG/trunk/gcc/config/sh/sh.c       2012-02-23 21:24:18.000000000 +0900
+++ trunk/gcc/config/sh/sh.c    2012-03-01 09:41:00.000000000 +0900
@@ -11497,8 +11498,15 @@ sh_register_move_cost (enum machine_mode
        && REGCLASS_HAS_GENERAL_REG (srcclass))
       || (REGCLASS_HAS_GENERAL_REG (dstclass)
          && REGCLASS_HAS_FP_REG (srcclass)))
-    return (((TARGET_SHMEDIA ? 4 : TARGET_FMOVD ? 8 : 12) + 64)
-           * ((GET_MODE_SIZE (mode) + 7) / 8U));
+    {
+      /* Discourage trying to use fp regs for a pointer.  This also
+        discourages fp regs with SImode because Pmode is an alias
+        of SImode on this target.  See PR target/48596.  */
+      int addend = (mode == Pmode) ? 40 : 0;
+
+      return (((TARGET_SHMEDIA ? 4 : TARGET_FMOVD ? 8 : 12) + addend)
+             * ((GET_MODE_SIZE (mode) + 7) / 8U));
+    }
 
   if ((dstclass == FPUL_REGS
        && REGCLASS_HAS_GENERAL_REG (srcclass))

Reply via email to