From d8305a03b4f0bb081dd9c88917cc8c48def22a80 Mon Sep 17 00:00:00 2001 From: Alexander Monakov Date: Fri, 14 Feb 2020 20:14:36 +0300 Subject: [PATCH] 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. --- gcc/ChangeLog | 5 +++++ gcc/rtlanal.c | 21 +++++++++------------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1cdec0b4071..2080b738fb6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2020-02-14 Alexander Monakov + + * 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 PR tree-optimization/93516 diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 9a7afccefb8..c7ab86e228b 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); } -- 2.30.2