rtlanal: optimize costly division in rtx_cost
authorAlexander Monakov <amonakov@ispras.ru>
Fri, 14 Feb 2020 17:14:36 +0000 (20:14 +0300)
committerAlexander Monakov <amonakov@ispras.ru>
Fri, 14 Feb 2020 17:22:36 +0000 (20:22 +0300)
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
gcc/rtlanal.c

index 1cdec0b4071ed6c3690a94c3478db7130b050b43..2080b738fb653923756209dd5236c9e89c1f69dd 100644 (file)
@@ -1,3 +1,8 @@
+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>
 
        PR tree-optimization/93516
index 9a7afccefb838fd440ed37b1a3bf8c89a31afd52..c7ab86e228b1fe4c3645d7746b5c1ae046b0f821 100644 (file)
@@ -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);
     }