aboutsummaryrefslogtreecommitdiff
path: root/gcc/rtlanal.c
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@axis.com>2012-07-12 21:14:14 +0000
committerHans-Peter Nilsson <hp@gcc.gnu.org>2012-07-12 21:14:14 +0000
commite098c1696289d3d935d13ebed803c5b32045ba6d (patch)
treedc588155e6de500b6c1e343812291707762bbd90 /gcc/rtlanal.c
parent8c15b4b04f81d00c916aeb7a5ba186722d4a4b2d (diff)
downloadgcc-e098c1696289d3d935d13ebed803c5b32045ba6d.zip
gcc-e098c1696289d3d935d13ebed803c5b32045ba6d.tar.gz
gcc-e098c1696289d3d935d13ebed803c5b32045ba6d.tar.bz2
re PR rtl-optimization/53176 (gcc.dg/lower-subreg-1.c FAILs)
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
Diffstat (limited to 'gcc/rtlanal.c')
-rw-r--r--gcc/rtlanal.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index f3527b4..8f52e4f 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -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: