[Patch/expand] Cost instruction sequences when doing left wide shift
authorJiong Wang <jiong.wang@arm.com>
Thu, 10 Sep 2015 10:37:17 +0000 (10:37 +0000)
committerJiong Wang <jiwang@gcc.gnu.org>
Thu, 10 Sep 2015 10:37:17 +0000 (10:37 +0000)
Patch background details:

    https://gcc.gnu.org/ml/gcc-patches/2015-08/msg01147.html

gcc/
  PR rtl-optimization/67421
  * expr.c (expand_expr_real_2): Cost instrcution sequences when doing left wide
  shift tranformation.

From-SVN: r227629

gcc/ChangeLog
gcc/expr.c

index 92665934d8188e1f0a743fede3ddcaeb74d830d1..d5254fa95ea4d8053c4a0c5bd653a16112f14048 100644 (file)
@@ -1,3 +1,9 @@
+2015-09-10  Jiong Wang  <jiong.wang@arm.com>
+
+       PR rtl-optimization/67421
+       * expr.c (expand_expr_real_2): Cost instrcution sequences when doing
+       left wide shift tranformation.
+
 2015-09-10  Claudiu Zissulescu  <claziss@synopsys.com>
 
        * common/config/arc/arc-common.c: Remove references to A5.
index ee0c1f932493b0fde22798d8be59842d11c440a7..cf28f4493096515b8a78d27e35cb4012a91a7b65 100644 (file)
@@ -8892,7 +8892,6 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
            && ! unsignedp
            && mode == GET_MODE_WIDER_MODE (word_mode)
            && GET_MODE_SIZE (mode) == 2 * GET_MODE_SIZE (word_mode)
-           && ! have_insn_for (ASHIFT, mode)
            && TREE_CONSTANT (treeop1)
            && TREE_CODE (treeop0) == SSA_NAME)
          {
@@ -8908,6 +8907,7 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
                    && ((TREE_INT_CST_LOW (treeop1) + GET_MODE_BITSIZE (rmode))
                        >= GET_MODE_BITSIZE (word_mode)))
                  {
+                   rtx_insn *seq, *seq_old;
                    unsigned int high_off = subreg_highpart_offset (word_mode,
                                                                    mode);
                    rtx low = lowpart_subreg (word_mode, op0, mode);
@@ -8918,6 +8918,7 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
                                             - TREE_INT_CST_LOW (treeop1));
                    tree rshift = build_int_cst (TREE_TYPE (treeop1), ramount);
 
+                   start_sequence ();
                    /* dest_high = src_low >> (word_size - C).  */
                    temp = expand_variable_shift (RSHIFT_EXPR, word_mode, low,
                                                  rshift, dest_high, unsignedp);
@@ -8930,7 +8931,28 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
                    if (temp != dest_low)
                      emit_move_insn (dest_low, temp);
 
+                   seq = get_insns ();
+                   end_sequence ();
                    temp = target ;
+
+                   if (have_insn_for (ASHIFT, mode))
+                     {
+                       bool speed_p = optimize_insn_for_speed_p ();
+                       start_sequence ();
+                       rtx ret_old = expand_variable_shift (code, mode, op0,
+                                                            treeop1, target,
+                                                            unsignedp);
+
+                       seq_old = get_insns ();
+                       end_sequence ();
+                       if (seq_cost (seq, speed_p)
+                           >= seq_cost (seq_old, speed_p))
+                         {
+                           seq = seq_old;
+                           temp = ret_old;
+                         }
+                     }
+                     emit_insn (seq);
                  }
              }
          }