]> gcc.gnu.org Git - gcc.git/commitdiff
[PATCH 4/4] Add CCMP selection based on rtx costs
authorWilco Dijkstra <wdijkstr@arm.com>
Tue, 19 Jan 2016 14:14:56 +0000 (14:14 +0000)
committerJiong Wang <jiwang@gcc.gnu.org>
Tue, 19 Jan 2016 14:14:56 +0000 (14:14 +0000)
    2015-01-19  Wilco Dijkstra  <wdijkstr@arm.com>
Jiong Wang  <jiong.wang@arm.com>

    gcc/
* ccmp.c (expand_ccmp_expr_1): Cost the instruction sequences
generated from different expand order.

    gcc/testsuite/
        * gcc.target/aarch64/ccmp_1.c: Add new tests.

Co-Authored-By: Jiong Wang <jiong.wang@arm.com>
From-SVN: r232565

gcc/ChangeLog
gcc/ccmp.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/ccmp_1.c

index a9cc4e462e520b8300cca2939c07a63151422f49..de730d43807deed675a581c71996b51e261fbe4f 100644 (file)
@@ -1,4 +1,10 @@
-2016-01-19  Wilco Dijkstra  <wdijkstr@arm.com>
+2015-01-19  Wilco Dijkstra  <wdijkstr@arm.com>
+           Jiong Wang  <jiong.wang@arm.com>
+
+       * ccmp.c (expand_ccmp_expr_1): Cost the instruction sequences
+       generated from different expand order.
+
+2015-01-19  Wilco Dijkstra  <wdijkstr@arm.com>
 
        * /config/aarch64/aarch64.c (aarch64_if_then_else_costs):
        Add support for CCMP costing.
index a393d3546f3b453408ccbb3cfd6907f647a3ed86..9e49d1e4e4a4c46ebb802596c83e2c5c37a7d499 100644 (file)
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-outof-ssa.h"
 #include "cfgexpand.h"
 #include "ccmp.h"
+#include "predict.h"
 
 /* The following functions expand conditional compare (CCMP) instructions.
    Here is a short description about the over all algorithm:
@@ -72,7 +73,7 @@ ccmp_candidate_p (gimple *g)
   tree rhs = gimple_assign_rhs_to_tree (g);
   tree lhs, op0, op1;
   gimple *gs0, *gs1;
-  enum tree_code tcode, tcode0, tcode1;
+  tree_code tcode, tcode0, tcode1;
   tcode = TREE_CODE (rhs);
 
   if (tcode != BIT_AND_EXPR && tcode != BIT_IOR_EXPR)
@@ -119,10 +120,10 @@ ccmp_candidate_p (gimple *g)
    PREP_SEQ returns all insns to prepare opearands for compare.
    GEN_SEQ returns all compare insns.  */
 static rtx
-expand_ccmp_next (gimple *g, enum tree_code code, rtx prev,
+expand_ccmp_next (gimple *g, tree_code code, rtx prev,
                  rtx *prep_seq, rtx *gen_seq)
 {
-  enum rtx_code rcode;
+  rtx_code rcode;
   int unsignedp = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (g)));
 
   gcc_assert (code == BIT_AND_EXPR || code == BIT_IOR_EXPR);
@@ -149,13 +150,15 @@ expand_ccmp_next (gimple *g, enum tree_code code, rtx prev,
 static rtx
 expand_ccmp_expr_1 (gimple *g, rtx *prep_seq, rtx *gen_seq)
 {
+  rtx prep_seq_1, gen_seq_1;
+  rtx prep_seq_2, gen_seq_2;
   tree exp = gimple_assign_rhs_to_tree (g);
-  enum tree_code code = TREE_CODE (exp);
+  tree_code code = TREE_CODE (exp);
   gimple *gs0 = get_gimple_for_ssa_name (TREE_OPERAND (exp, 0));
   gimple *gs1 = get_gimple_for_ssa_name (TREE_OPERAND (exp, 1));
   rtx tmp;
-  enum tree_code code0 = gimple_assign_rhs_code (gs0);
-  enum tree_code code1 = gimple_assign_rhs_code (gs1);
+  tree_code code0 = gimple_assign_rhs_code (gs0);
+  tree_code code1 = gimple_assign_rhs_code (gs1);
 
   gcc_assert (code == BIT_AND_EXPR || code == BIT_IOR_EXPR);
   gcc_assert (gs0 && gs1 && is_gimple_assign (gs0) && is_gimple_assign (gs1));
@@ -164,19 +167,53 @@ expand_ccmp_expr_1 (gimple *g, rtx *prep_seq, rtx *gen_seq)
     {
       if (TREE_CODE_CLASS (code1) == tcc_comparison)
        {
-         int unsignedp0;
-         enum rtx_code rcode0;
+         int unsignedp0, unsignedp1;
+         rtx_code rcode0, rcode1;
+         int speed_p = optimize_insn_for_speed_p ();
+         rtx tmp2, ret, ret2;
+         unsigned cost1 = MAX_COST;
+         unsigned cost2 = MAX_COST;
 
          unsignedp0 = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (gs0)));
+         unsignedp1 = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (gs1)));
          rcode0 = get_rtx_code (code0, unsignedp0);
+         rcode1 = get_rtx_code (code1, unsignedp1);
 
-         tmp = targetm.gen_ccmp_first (prep_seq, gen_seq, rcode0,
+         tmp = targetm.gen_ccmp_first (&prep_seq_1, &gen_seq_1, rcode0,
                                        gimple_assign_rhs1 (gs0),
                                        gimple_assign_rhs2 (gs0));
-         if (!tmp)
+
+         tmp2 = targetm.gen_ccmp_first (&prep_seq_2, &gen_seq_2, rcode1,
+                                        gimple_assign_rhs1 (gs1),
+                                        gimple_assign_rhs2 (gs1));
+
+         if (!tmp && !tmp2)
            return NULL_RTX;
 
-         return expand_ccmp_next (gs1, code, tmp, prep_seq, gen_seq);
+         if (tmp != NULL)
+           {
+             ret = expand_ccmp_next (gs1, code, tmp, &prep_seq_1, &gen_seq_1);
+             cost1 = seq_cost (safe_as_a <rtx_insn *> (prep_seq_1), speed_p);
+             cost1 += seq_cost (safe_as_a <rtx_insn *> (gen_seq_1), speed_p);
+           }
+         if (tmp2 != NULL)
+           {
+             ret2 = expand_ccmp_next (gs0, code, tmp2, &prep_seq_2,
+                                      &gen_seq_2);
+             cost2 = seq_cost (safe_as_a <rtx_insn *> (prep_seq_2), speed_p);
+             cost2 += seq_cost (safe_as_a <rtx_insn *> (gen_seq_2), speed_p);
+           }
+
+         if (cost2 < cost1)
+           {
+             *prep_seq = prep_seq_2;
+             *gen_seq = gen_seq_2;
+             return ret2;
+           }
+
+         *prep_seq = prep_seq_1;
+         *gen_seq = gen_seq_1;
+         return ret;
        }
       else
        {
@@ -230,8 +267,8 @@ expand_ccmp_expr (gimple *g)
 
   if (tmp)
     {
-      enum insn_code icode;
-      enum machine_mode cc_mode = CCmode;
+      insn_code icode;
+      machine_mode cc_mode = CCmode;
       tree lhs = gimple_assign_lhs (g);
       rtx_code cmp_code = GET_CODE (tmp);
 
@@ -241,7 +278,7 @@ expand_ccmp_expr (gimple *g)
       icode = optab_handler (cstore_optab, cc_mode);
       if (icode != CODE_FOR_nothing)
        {
-         enum machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
+         machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
          rtx target = gen_reg_rtx (mode);
 
          emit_insn (prep_seq);
index cd38389af8e0bae62ead3108cd63a03dc1d32070..057dc1e9e88b741257b4646bc76e14611fc2ec5d 100644 (file)
@@ -1,3 +1,7 @@
+2015-01-19  Wilco Dijkstra  <wdijkstr@arm.com>
+
+       * gcc.target/aarch64/ccmp_1.c: Add new tests.
+
 2015-01-19  Wilco Dijkstra  <wdijkstr@arm.com>
 
        * gcc.target/aarch64/ccmp_1.c: New testcase.
index ef077e0f711b0412193d6521b81b89f84a127ee6..7c39b61a585a1d4d662b0736e1c80e06bdc6b4ce 100644 (file)
@@ -80,5 +80,16 @@ f13 (int a, int b)
   return a == 3 || a == 0;
 }
 
-/* { dg-final { scan-assembler "fccmp\t" } } */
-/* { dg-final { scan-assembler "fccmpe\t" } } */
+/* { dg-final { scan-assembler "cmp\t(.)+32" } } */
+/* { dg-final { scan-assembler "cmp\t(.)+33" } } */
+/* { dg-final { scan-assembler "cmp\t(.)+34" } } */
+/* { dg-final { scan-assembler "cmp\t(.)+35" } } */
+
+/* { dg-final { scan-assembler-times "\tcmp\tw\[0-9\]+, 0" 4 } } */
+/* { dg-final { scan-assembler-times "fcmpe\t(.)+0\\.0" 2 } } */
+/* { dg-final { scan-assembler-times "fcmp\t(.)+0\\.0" 2 } } */
+
+/* { dg-final { scan-assembler "adds\t" } } */
+/* { dg-final { scan-assembler-times "\tccmp\t" 11 } } */
+/* { dg-final { scan-assembler-times "fccmp\t.*0\\.0" 1 } } */
+/* { dg-final { scan-assembler-times "fccmpe\t.*0\\.0" 1 } } */
This page took 0.069162 seconds and 5 git commands to generate.