expmed.c (expand_shift): Consider expanding LSHIFT_EXPR by a constant as a sequence...
authorRoger Sayle <roger@eyesopen.com>
Thu, 1 Jul 2004 04:27:09 +0000 (04:27 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Thu, 1 Jul 2004 04:27:09 +0000 (04:27 +0000)
* expmed.c (expand_shift): Consider expanding LSHIFT_EXPR by a
constant as a sequence of additions depending upon the rtx_costs.
(synth_mult): Update the "observed" cost of a shift, based upon
the above optimization.

From-SVN: r83956

gcc/ChangeLog
gcc/expmed.c

index 46f33600eef12bdcbc14d78cda7fb45b8346ac50..92a4d69b804a50bc3b82e9ecf14b6fbb39961c3c 100644 (file)
@@ -1,3 +1,10 @@
+2004-06-30  Roger Sayle  <roger@eyesopen.com>
+
+       * expmed.c (expand_shift): Consider expanding LSHIFT_EXPR by a
+       constant as a sequence of additions depending upon the rtx_costs.
+       (synth_mult): Update the "observed" cost of a shift, based upon
+       the above optimization.
+
 2004-06-28  Geoffrey Keating  <geoffk@apple.com>
            Andreas Tobler  <a.tobler@schweiz.ch>
 
index a2278b9d8c17399e238f71f31fa2a2a6a324cde0..e95a62643fc3977fb2b091694d2b5f7c3ec3d824 100644 (file)
@@ -2017,6 +2017,24 @@ expand_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
   if (op1 == const0_rtx)
     return shifted;
 
+  /* Check whether its cheaper to implement a left shift by a constant
+     bit count by a sequence of additions.  */
+  if (code == LSHIFT_EXPR
+      && GET_CODE (op1) == CONST_INT
+      && INTVAL (op1) > 0
+      && INTVAL (op1) < GET_MODE_BITSIZE (mode)
+      && shift_cost[mode][INTVAL (op1)] > INTVAL (op1) * add_cost[mode])
+    {
+      int i;
+      for (i = 0; i < INTVAL (op1); i++)
+       {
+         temp = force_reg (mode, shifted);
+         shifted = expand_binop (mode, add_optab, temp, temp, NULL_RTX,
+                                 unsignedp, OPTAB_LIB_WIDEN);
+       }
+      return shifted;
+    }
+
   for (try = 0; temp == 0 && try < 3; try++)
     {
       enum optab_methods methods;
@@ -2242,7 +2260,12 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
       if (m < maxm)
        {
          q = t >> m;
-         cost = shift_cost[mode][m];
+         /* The function expand_shift will choose between a shift and
+            a sequence of additions, so the observed cost is given as
+            MIN (m * add_cost[mode], shift_cost[mode][m]).  */
+         cost = m * add_cost[mode];
+         if (shift_cost[mode][m] < cost)
+           cost = shift_cost[mode][m];
          synth_mult (alg_in, q, cost_limit - cost, mode);
 
          cost += alg_in->cost;