aboutsummaryrefslogtreecommitdiff
path: root/gcc/rtlanal.c
diff options
context:
space:
mode:
authorAlexander Monakov <amonakov@ispras.ru>2020-02-14 20:14:36 +0300
committerAlexander Monakov <amonakov@ispras.ru>2020-02-14 20:22:36 +0300
commitd8305a03b4f0bb081dd9c88917cc8c48def22a80 (patch)
treecb1eb11e78e31963e2d7e79195a9170a281aa2aa /gcc/rtlanal.c
parent519a33f954fd71cb8b74053e168e23a1cb00d30b (diff)
downloadgcc-d8305a03b4f0bb081dd9c88917cc8c48def22a80.zip
gcc-d8305a03b4f0bb081dd9c88917cc8c48def22a80.tar.gz
gcc-d8305a03b4f0bb081dd9c88917cc8c48def22a80.tar.bz2
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.
Diffstat (limited to 'gcc/rtlanal.c')
-rw-r--r--gcc/rtlanal.c21
1 files changed, 9 insertions, 12 deletions
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 9a7afcc..c7ab86e 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -4207,18 +4207,23 @@ rtx_cost (rtx x, machine_mode mode, enum rtx_code outer_code,
const char *fmt;
int total;
int factor;
+ unsigned mode_size;
if (x == 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_size = estimated_poly_value (GET_MODE_SIZE (mode));
+
/* A size N times larger than UNITS_PER_WORD likely needs N times as
many insns, taking N times as long. */
- factor = estimated_poly_value (GET_MODE_SIZE (mode)) / UNITS_PER_WORD;
- if (factor == 0)
- factor = 1;
+ factor = mode_size > UNITS_PER_WORD ? mode_size / UNITS_PER_WORD : 1;
/* Compute the default costs of certain things.
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,
/* 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. */
- mode = GET_MODE (SET_DEST (x));
- factor = estimated_poly_value (GET_MODE_SIZE (mode)) / UNITS_PER_WORD;
- if (factor == 0)
- factor = 1;
- /* FALLTHRU */
default:
total = factor * COSTS_N_INSNS (1);
}