]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR rtl-optimization/53176 (gcc.dg/lower-subreg-1.c FAILs)
authorHans-Peter Nilsson <hp@axis.com>
Thu, 12 Jul 2012 21:14:14 +0000 (21:14 +0000)
committerHans-Peter Nilsson <hp@gcc.gnu.org>
Thu, 12 Jul 2012 21:14:14 +0000 (21:14 +0000)
PR rtl-optimization/53176
* rtlanal.c (rtx_cost): Adjust default cost for X with a
UNITS_PER_WORD factor for all X according to the size of
its mode, not just for SUBREGs with untieable modes.
Handle SET.  Use factor * factor for MULT, DIV, UDIV,
MOD, UMOD.

From-SVN: r189441

gcc/ChangeLog
gcc/rtlanal.c

index 2eb783b44f88eaebea4ab48df027f07d9eda0bda..e5637bfb274809d7052ad53521fe8da22ca278e9 100644 (file)
@@ -1,3 +1,12 @@
+2012-07-12  Hans-Peter Nilsson  <hp@axis.com>
+
+       PR rtl-optimization/53176
+       * rtlanal.c (rtx_cost): Adjust default cost for X with a
+       UNITS_PER_WORD factor for all X according to the size of
+       its mode, not just for SUBREGs with untieable modes.
+       Handle SET.  Use factor * factor for MULT, DIV, UDIV,
+       MOD, UMOD.
+
 2012-07-12  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.md (QImode and HImode cmove splitters): Merge
index f3527b4f1a6bb5bf8d4bffc20db70a78c455df66..8f52e4f9db4b04d27253bbe6e2d64d9c3b61d577 100644 (file)
@@ -3755,10 +3755,17 @@ rtx_cost (rtx x, enum rtx_code outer_code, int opno, bool speed)
   enum rtx_code code;
   const char *fmt;
   int total;
+  int factor;
 
   if (x == 0)
     return 0;
 
+  /* A size N times larger than UNITS_PER_WORD likely needs N times as
+     many insns, taking N times as long.  */
+  factor = GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD;
+  if (factor == 0)
+    factor = 1;
+
   /* Compute the default costs of certain things.
      Note that targetm.rtx_costs can override the defaults.  */
 
@@ -3766,20 +3773,31 @@ rtx_cost (rtx x, enum rtx_code outer_code, int opno, bool speed)
   switch (code)
     {
     case MULT:
-      total = COSTS_N_INSNS (5);
+      /* Multiplication has time-complexity O(N*N), where N is the
+        number of units (translated from digits) when using
+        schoolbook long multiplication.  */
+      total = factor * factor * COSTS_N_INSNS (5);
       break;
     case DIV:
     case UDIV:
     case MOD:
     case UMOD:
-      total = COSTS_N_INSNS (7);
+      /* Similarly, complexity for schoolbook long division.  */
+      total = factor * factor * COSTS_N_INSNS (7);
       break;
     case USE:
       /* Used in combine.c as a marker.  */
       total = 0;
       break;
+    case SET:
+      /* A SET doesn't have a mode, so let's look at the SET_DEST to get
+        the mode for the factor.  */
+      factor = GET_MODE_SIZE (GET_MODE (SET_DEST (x))) / UNITS_PER_WORD;
+      if (factor == 0)
+       factor = 1;
+      /* Pass through.  */
     default:
-      total = COSTS_N_INSNS (1);
+      total = factor * COSTS_N_INSNS (1);
     }
 
   switch (code)
@@ -3792,8 +3810,7 @@ rtx_cost (rtx x, enum rtx_code outer_code, int opno, bool speed)
       /* If we can't tie these modes, make this expensive.  The larger
         the mode, the more expensive it is.  */
       if (! MODES_TIEABLE_P (GET_MODE (x), GET_MODE (SUBREG_REG (x))))
-       return COSTS_N_INSNS (2
-                             + GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD);
+       return COSTS_N_INSNS (2 + factor);
       break;
 
     default: