Commit d8305a03 by Alexander Monakov

rtlanal: optimize costly division in rtx_cost

There's a costly signed 64-bit division in rtx_cost on x86 as well as
any other target where UNITS_PER_WORD expands to TARGET_64BIT ?  8 : 4.
It's also evident that rtx_cost does redundant work for a SET.

Obviously the variable named 'factor' rarely exceeds 1, so in the
majority of cases it can be computed with a well-predictable branch
rather than a division.

This patch makes rtx_cost do the division only in case mode is wider
than UNITS_PER_WORD, and also moves a test for a SET up front to avoid
redundancy.
No functional change.

	* rtlanal.c (rtx_cost): Handle a SET up front. Avoid division if
	the mode is not wider than UNITS_PER_WORD.
parent 519a33f9
2020-02-14 Alexander Monakov <amonakov@ispras.ru>
* rtlanal.c (rtx_cost): Handle a SET up front. Avoid division if
the mode is not wider than UNITS_PER_WORD.
2020-02-14 Martin Jambor <mjambor@suse.cz> 2020-02-14 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/93516 PR tree-optimization/93516
......
...@@ -4207,18 +4207,23 @@ rtx_cost (rtx x, machine_mode mode, enum rtx_code outer_code, ...@@ -4207,18 +4207,23 @@ rtx_cost (rtx x, machine_mode mode, enum rtx_code outer_code,
const char *fmt; const char *fmt;
int total; int total;
int factor; int factor;
unsigned mode_size;
if (x == 0) if (x == 0)
return 0; return 0;
if (GET_MODE (x) != VOIDmode) if (GET_CODE (x) == SET)
/* A SET doesn't have a mode, so let's look at the SET_DEST to get
the mode for the factor. */
mode = GET_MODE (SET_DEST (x));
else if (GET_MODE (x) != VOIDmode)
mode = GET_MODE (x); mode = GET_MODE (x);
mode_size = estimated_poly_value (GET_MODE_SIZE (mode));
/* A size N times larger than UNITS_PER_WORD likely needs N times as /* A size N times larger than UNITS_PER_WORD likely needs N times as
many insns, taking N times as long. */ many insns, taking N times as long. */
factor = estimated_poly_value (GET_MODE_SIZE (mode)) / UNITS_PER_WORD; factor = mode_size > UNITS_PER_WORD ? mode_size / UNITS_PER_WORD : 1;
if (factor == 0)
factor = 1;
/* Compute the default costs of certain things. /* Compute the default costs of certain things.
Note that targetm.rtx_costs can override the defaults. */ Note that targetm.rtx_costs can override the defaults. */
...@@ -4243,14 +4248,6 @@ rtx_cost (rtx x, machine_mode mode, enum rtx_code outer_code, ...@@ -4243,14 +4248,6 @@ rtx_cost (rtx x, machine_mode mode, enum rtx_code outer_code,
/* Used in combine.c as a marker. */ /* Used in combine.c as a marker. */
total = 0; total = 0;
break; 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. */
mode = GET_MODE (SET_DEST (x));
factor = estimated_poly_value (GET_MODE_SIZE (mode)) / UNITS_PER_WORD;
if (factor == 0)
factor = 1;
/* FALLTHRU */
default: default:
total = factor * COSTS_N_INSNS (1); total = factor * COSTS_N_INSNS (1);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment