diff mbox

[RFA] Minor improvement to canonicalization of COND_EXPR for gimple

Message ID 51600373.7050706@redhat.com
State New
Headers show

Commit Message

Jeff Law April 6, 2013, 11:13 a.m. UTC
The tree combiner/forward propagator is missing opportunities to 
collapse sequences like this:

   _15 = _12 ^ _14;
   if (_15 != 0)


Into:

     if (_12 != _14)

The tree combiner/forward propagator builds this tree:

x ^ y

Then passes it to canonicalize_cond_expr_cond  That is not suitable for 
the condition in a gimple COND_EXPR.  So canonicalize_cond_expr_cond 
returns NULL.  Thus combine_cond_expr_cond decides the tree it created 
isn't useful and throws it away.

This patch changes canonicalize_cond_expr to rewrite x ^ y into x != y. 
  The net result being the tree combiner/forward propagator is able to 
perform the desired simplification, eliminating the BIT_XOR_EXPR.

Bootstrapped and regression tested on x86_64-unknown-linux-gnu.  As you 
can see from the testcase, these kinds of sequences show up when 
compiling gcc itself.

OK for the trunk?
commit 809408a4bde6dfbaf62c5bda9ab7ae6c4447d984
Author: Jeff Law <law@redhat.com>
Date:   Sat Apr 6 05:11:17 2013 -0600

            * gimple.c (canonicalize_cond_expr_cond): Rewrite x ^ y into
            x != y.
    
            * gcc.dg/tree-ssa/forwprop-25.c: New test

Comments

Richard Biener April 8, 2013, 9:12 a.m. UTC | #1
On Sat, Apr 6, 2013 at 1:13 PM, Jeff Law <law@redhat.com> wrote:
>
>
> The tree combiner/forward propagator is missing opportunities to collapse
> sequences like this:
>
>   _15 = _12 ^ _14;
>   if (_15 != 0)
>
>
> Into:
>
>     if (_12 != _14)
>
> The tree combiner/forward propagator builds this tree:
>
> x ^ y
>
> Then passes it to canonicalize_cond_expr_cond  That is not suitable for the
> condition in a gimple COND_EXPR.  So canonicalize_cond_expr_cond returns
> NULL.  Thus combine_cond_expr_cond decides the tree it created isn't useful
> and throws it away.
>
> This patch changes canonicalize_cond_expr to rewrite x ^ y into x != y.  The
> net result being the tree combiner/forward propagator is able to perform the
> desired simplification, eliminating the BIT_XOR_EXPR.
>
> Bootstrapped and regression tested on x86_64-unknown-linux-gnu.  As you can
> see from the testcase, these kinds of sequences show up when compiling gcc
> itself.
>
> OK for the trunk?

Nice. Ok.

Thanks,
Richard.

> commit 809408a4bde6dfbaf62c5bda9ab7ae6c4447d984
> Author: Jeff Law <law@redhat.com>
> Date:   Sat Apr 6 05:11:17 2013 -0600
>
>             * gimple.c (canonicalize_cond_expr_cond): Rewrite x ^ y into
>             x != y.
>
>             * gcc.dg/tree-ssa/forwprop-25.c: New test
>
> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
> index b8a6900..44797cc 100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,3 +1,8 @@
> +2013-04-06  Jeff Law  <law@redhat.com>
> +
> +       * gimple.c (canonicalize_cond_expr_cond): Rewrite x ^ y into
> +       x != y.
> +
>  2013-04-03  Jeff Law  <law@redhat.com>
>
>         * Makefile.in (lra-constraints.o): Depend on $(OPTABS_H).
> diff --git a/gcc/gimple.c b/gcc/gimple.c
> index 785c2f0..cdb6f24 100644
> --- a/gcc/gimple.c
> +++ b/gcc/gimple.c
> @@ -2958,7 +2958,11 @@ canonicalize_cond_expr_cond (tree t)
>        t = build2 (TREE_CODE (top0), TREE_TYPE (t),
>                   TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1));
>      }
> -
> +  /* For x ^ y use x != y.  */
> +  else if (TREE_CODE (t) == BIT_XOR_EXPR)
> +    t = build2 (NE_EXPR, TREE_TYPE (t),
> +               TREE_OPERAND (t, 0), TREE_OPERAND (t, 1));
> +
>    if (is_gimple_condexpr (t))
>      return t;
>
> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
> index dc0b745..601ca66 100644
> --- a/gcc/testsuite/ChangeLog
> +++ b/gcc/testsuite/ChangeLog
> @@ -1,3 +1,7 @@
> +2013-04-06  Jeff Law  <law@redhat.com>
> +
> +       * gcc.dg/tree-ssa/forwprop-25.c: New test
> +
>  2013-04-03  Jeff Law  <law@redhat.com>
>
>         PR tree-optimization/56799
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c
> b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c
> new file mode 100644
> index 0000000..cf0c504
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c
> @@ -0,0 +1,43 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O1 -fdump-tree-forwprop1" } */
> +
> +struct rtx_def;
> +typedef struct rtx_def *rtx;
> +typedef const struct rtx_def *const_rtx;
> +enum machine_mode
> +{
> +  MAX_MACHINE_MODE,
> +  NUM_MACHINE_MODES = MAX_MACHINE_MODE
> +};
> +extern const char *const mode_name[NUM_MACHINE_MODES];
> +enum mode_class
> +{ MODE_RANDOM, MODE_CC, MODE_INT, MODE_PARTIAL_INT, MODE_FRACT,
> MODE_UFRACT,
> +    MODE_ACCUM, MODE_UACCUM, MODE_FLOAT, MODE_DECIMAL_FLOAT,
> MODE_COMPLEX_INT,
> +    MODE_COMPLEX_FLOAT, MODE_VECTOR_INT, MODE_VECTOR_FRACT,
> +    MODE_VECTOR_UFRACT, MODE_VECTOR_ACCUM, MODE_VECTOR_UACCUM,
> +    MODE_VECTOR_FLOAT, MAX_MODE_CLASS };
> +extern const unsigned char mode_class[NUM_MACHINE_MODES];
> +extern const unsigned short mode_precision[NUM_MACHINE_MODES];
> +struct rtx_def
> +{
> +  __extension__ enum machine_mode mode:8;
> +};
> +void
> +convert_move (rtx to, rtx from, int unsignedp)
> +{
> +  enum machine_mode to_mode = ((enum machine_mode) (to)->mode);
> +  enum machine_mode from_mode = ((enum machine_mode) (from)->mode);
> +  ((void)
> +   (!((mode_precision[from_mode] != mode_precision[to_mode])
> +      || ((((enum mode_class) mode_class[from_mode]) == MODE_DECIMAL_FLOAT)
> !=
> +         (((enum mode_class) mode_class[to_mode]) ==
> +          MODE_DECIMAL_FLOAT))) ?
> +    fancy_abort ("/home/gcc/virgin-gcc/gcc/expr.c", 380, __FUNCTION__),
> +    0 : 0));
> +}
> +
> +/* { dg-final { scan-tree-dump "Replaced.*!=.*with.*!=.* " "forwprop1"} }
> */
> +/* { dg-final { cleanup-tree-dump "forwprop1" } } */
> +
> +
> +
>
diff mbox

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b8a6900..44797cc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@ 
+2013-04-06  Jeff Law  <law@redhat.com>
+
+	* gimple.c (canonicalize_cond_expr_cond): Rewrite x ^ y into
+	x != y.
+
 2013-04-03  Jeff Law  <law@redhat.com>
 
 	* Makefile.in (lra-constraints.o): Depend on $(OPTABS_H).
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 785c2f0..cdb6f24 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -2958,7 +2958,11 @@  canonicalize_cond_expr_cond (tree t)
       t = build2 (TREE_CODE (top0), TREE_TYPE (t),
 		  TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1));
     }
-
+  /* For x ^ y use x != y.  */
+  else if (TREE_CODE (t) == BIT_XOR_EXPR)
+    t = build2 (NE_EXPR, TREE_TYPE (t),
+		TREE_OPERAND (t, 0), TREE_OPERAND (t, 1));
+  
   if (is_gimple_condexpr (t))
     return t;
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index dc0b745..601ca66 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@ 
+2013-04-06  Jeff Law  <law@redhat.com>
+
+	* gcc.dg/tree-ssa/forwprop-25.c: New test
+
 2013-04-03  Jeff Law  <law@redhat.com>
 
 	PR tree-optimization/56799
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c
new file mode 100644
index 0000000..cf0c504
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c
@@ -0,0 +1,43 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-forwprop1" } */
+
+struct rtx_def;
+typedef struct rtx_def *rtx;
+typedef const struct rtx_def *const_rtx;
+enum machine_mode
+{
+  MAX_MACHINE_MODE,
+  NUM_MACHINE_MODES = MAX_MACHINE_MODE
+};
+extern const char *const mode_name[NUM_MACHINE_MODES];
+enum mode_class
+{ MODE_RANDOM, MODE_CC, MODE_INT, MODE_PARTIAL_INT, MODE_FRACT, MODE_UFRACT,
+    MODE_ACCUM, MODE_UACCUM, MODE_FLOAT, MODE_DECIMAL_FLOAT, MODE_COMPLEX_INT,
+    MODE_COMPLEX_FLOAT, MODE_VECTOR_INT, MODE_VECTOR_FRACT,
+    MODE_VECTOR_UFRACT, MODE_VECTOR_ACCUM, MODE_VECTOR_UACCUM,
+    MODE_VECTOR_FLOAT, MAX_MODE_CLASS };
+extern const unsigned char mode_class[NUM_MACHINE_MODES];
+extern const unsigned short mode_precision[NUM_MACHINE_MODES];
+struct rtx_def
+{
+  __extension__ enum machine_mode mode:8;
+};
+void
+convert_move (rtx to, rtx from, int unsignedp)
+{
+  enum machine_mode to_mode = ((enum machine_mode) (to)->mode);
+  enum machine_mode from_mode = ((enum machine_mode) (from)->mode);
+  ((void)
+   (!((mode_precision[from_mode] != mode_precision[to_mode])
+      || ((((enum mode_class) mode_class[from_mode]) == MODE_DECIMAL_FLOAT) !=
+	  (((enum mode_class) mode_class[to_mode]) ==
+	   MODE_DECIMAL_FLOAT))) ?
+    fancy_abort ("/home/gcc/virgin-gcc/gcc/expr.c", 380, __FUNCTION__),
+    0 : 0));
+}
+
+/* { dg-final { scan-tree-dump "Replaced.*!=.*with.*!=.* " "forwprop1"} } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */
+
+
+