Patchwork [RFA] Improve VRP of COND_EXPR_CONDs -- v2

login
register
mail settings
Submitter Jeff Law
Date April 9, 2013, 1:54 a.m.
Message ID <516374E3.8080800@redhat.com>
Download mbox | patch
Permalink /patch/234930/
State New
Headers show

Comments

Jeff Law - April 9, 2013, 1:54 a.m.
This incorporates the concrete suggestions from Steven & Richi -- it 
doesn't do any refactoring of the VRP code.  There's still stuff I'm 
looking at that might directly lead to some refactoring.  In the mean 
time I'm submitting the obvious small improvements.

Bootstrapped and regression tested on x86_64-unknown-linux-gnu.

OK for trunk?

Jeff
commit d6d1e36561b9022bbcdf157a886895f5bb0ef2ae
Author: Jeff Law <law@redhat.com>
Date:   Sat Apr 6 06:46:58 2013 -0600

           * tree-vrp.c (simplify_cond_using_ranges): Simplify test of boolean
           when the boolean was created by converting a wider object which
           had a boolean range.
    
            * gcc.dg/tree-ssa/vrp87.c: New test
Jeff Law - April 9, 2013, 2:10 a.m.
On 04/08/2013 07:54 PM, Jeff Law wrote:
>
> This incorporates the concrete suggestions from Steven & Richi -- it
> doesn't do any refactoring of the VRP code.  There's still stuff I'm
> looking at that might directly lead to some refactoring.  In the mean
> time I'm submitting the obvious small improvements.
>
> Bootstrapped and regression tested on x86_64-unknown-linux-gnu.
>
> OK for trunk?
Just a note, there's a typo "op" should be "op0" in that patch; not sure 
why git gave me the old version since that's something I thought I'd 
patched and squashed out...  Clearly a git user workflow error of some kind.

Jeff
Richard Guenther - April 9, 2013, 9:03 a.m.
On Tue, Apr 9, 2013 at 3:54 AM, Jeff Law <law@redhat.com> wrote:
>
> This incorporates the concrete suggestions from Steven & Richi -- it doesn't
> do any refactoring of the VRP code.  There's still stuff I'm looking at that
> might directly lead to some refactoring.  In the mean time I'm submitting
> the obvious small improvements.
>
> Bootstrapped and regression tested on x86_64-unknown-linux-gnu.
>
> OK for trunk?

Ok.

Thanks,
Richard.

> Jeff
>
> commit d6d1e36561b9022bbcdf157a886895f5bb0ef2ae
> Author: Jeff Law <law@redhat.com>
> Date:   Sat Apr 6 06:46:58 2013 -0600
>
>            * tree-vrp.c (simplify_cond_using_ranges): Simplify test of
> boolean
>            when the boolean was created by converting a wider object which
>            had a boolean range.
>
>             * gcc.dg/tree-ssa/vrp87.c: New test
>
> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
> index 6ee7d9c..110f61e 100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -16,8 +16,14 @@
>
>  2013-04-08  Jeff Law  <law@redhat.com>
>
> +       * tree-vrp.c (simplify_cond_using_ranges): Simplify test of boolean
> +       when the boolean was created by converting a wider object which
> +       had a boolean range.
> +
> +2013-04-08  Jeff Law  <law@redhat.com>
> +
>         * gimple.c (canonicalize_cond_expr_cond): Rewrite x ^ y into x != y.
> -
> +
>  2013-04-08  Richard Biener  <rguenther@suse.de>
>
>         * gimple-pretty-print.c (debug_gimple_stmt): Do not print
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c
> b/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c
> new file mode 100644
> index 0000000..7feff81
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c
> @@ -0,0 +1,81 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-vrp2-details -fdump-tree-cddce2-details" }
> */
> +
> +struct bitmap_head_def;
> +typedef struct bitmap_head_def *bitmap;
> +typedef const struct bitmap_head_def *const_bitmap;
> +
> +
> +typedef unsigned long BITMAP_WORD;
> +typedef struct bitmap_element_def
> +{
> +  struct bitmap_element_def *next;
> +  unsigned int indx;
> +  BITMAP_WORD bits[((128 + (8 * 8 * 1u) - 1) / (8 * 8 * 1u))];
> +} bitmap_element;
> +
> +
> +
> +
> +
> +
> +typedef struct bitmap_head_def
> +{
> +  bitmap_element *first;
> +
> +} bitmap_head;
> +
> +
> +
> +static __inline__ unsigned char
> +bitmap_elt_ior (bitmap dst, bitmap_element * dst_elt,
> +               bitmap_element * dst_prev, const bitmap_element * a_elt,
> +               const bitmap_element * b_elt, unsigned char changed)
> +{
> +
> +  if (a_elt)
> +    {
> +
> +      if (!changed && dst_elt)
> +       {
> +         changed = 1;
> +       }
> +    }
> +  else
> +    {
> +      changed = 1;
> +    }
> +  return changed;
> +}
> +
> +unsigned char
> +bitmap_ior_into (bitmap a, const_bitmap b)
> +{
> +  bitmap_element *a_elt = a->first;
> +  const bitmap_element *b_elt = b->first;
> +  bitmap_element *a_prev = ((void *) 0);
> +  unsigned char changed = 0;
> +
> +  while (b_elt)
> +    {
> +
> +      if (!a_elt || a_elt->indx == b_elt->indx)
> +       changed = bitmap_elt_ior (a, a_elt, a_prev, a_elt, b_elt, changed);
> +      else if (a_elt->indx > b_elt->indx)
> +       changed = 1;
> +      b_elt = b_elt->next;
> +
> +
> +    }
> +
> +  return changed;
> +}
> +
> +/* Verify that VRP simplified an "if" statement.  */
> +/* { dg-final { scan-tree-dump "Folded into: if.*" "vrp2"} } */
> +/* Verify that DCE after VRP2 eliminates a dead conversion
> +   to a (Bool).  */
> +/* { dg-final { scan-tree-dump "Deleting.*_Bool.*;" "cddce2"} } */
> +/* { dg-final { cleanup-tree-dump "vrp2" } } */
> +/* { dg-final { cleanup-tree-dump "cddce2" } } */
> +
> diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
> index 250a506..4520c89 100644
> --- a/gcc/tree-vrp.c
> +++ b/gcc/tree-vrp.c
> @@ -8584,6 +8584,45 @@ simplify_cond_using_ranges (gimple stmt)
>         }
>      }
>
> +  /* If we have a comparison of a SSA_NAME boolean against
> +     a constant (which obviously must be [0..1]), see if the
> +     SSA_NAME was set by a type conversion where the source
> +     of the conversion is another SSA_NAME with a range [0..1].
> +
> +     If so, we can replace the SSA_NAME in the comparison with
> +     the RHS of the conversion.  This will often make the type
> +     conversion dead code which DCE will clean up.  */
> +  if (TREE_CODE (op0) == SSA_NAME
> +      && (TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
> +         || (INTEGRAL_TYPE_P (TREE_TYPE (op))
> +             && TYPE_PRECISION (TREE_TYPE (op0)) == 1))
> +      && TREE_CODE (op1) == INTEGER_CST)
> +    {
> +      gimple def_stmt = SSA_NAME_DEF_STMT (op0);
> +      tree innerop;
> +
> +      if (!is_gimple_assign (def_stmt)
> +         || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
> +       return false;
> +
> +      innerop = gimple_assign_rhs1 (def_stmt);
> +
> +      if (TREE_CODE (innerop) == SSA_NAME)
> +       {
> +         value_range_t *vr = get_value_range (innerop);
> +
> +         if (range_int_cst_p (vr)
> +             && operand_equal_p (vr->min, integer_zero_node, 0)
> +             && operand_equal_p (vr->max, integer_one_node, 0))
> +           {
> +             tree newconst = fold_convert (TREE_TYPE (innerop), op1);
> +             gimple_cond_set_lhs (stmt, innerop);
> +             gimple_cond_set_rhs (stmt, newconst);
> +             return true;
> +           }
> +       }
> +    }
> +
>    return false;
>  }
>
>

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6ee7d9c..110f61e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -16,8 +16,14 @@ 
 
 2013-04-08  Jeff Law  <law@redhat.com>
 
+	* tree-vrp.c (simplify_cond_using_ranges): Simplify test of boolean
+	when the boolean was created by converting a wider object which
+	had a boolean range.
+
+2013-04-08  Jeff Law  <law@redhat.com>
+
 	* gimple.c (canonicalize_cond_expr_cond): Rewrite x ^ y into x != y.
-		        
+
 2013-04-08  Richard Biener  <rguenther@suse.de>
 
 	* gimple-pretty-print.c (debug_gimple_stmt): Do not print
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c
new file mode 100644
index 0000000..7feff81
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c
@@ -0,0 +1,81 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp2-details -fdump-tree-cddce2-details" } */
+
+struct bitmap_head_def;
+typedef struct bitmap_head_def *bitmap;
+typedef const struct bitmap_head_def *const_bitmap;
+
+
+typedef unsigned long BITMAP_WORD;
+typedef struct bitmap_element_def
+{
+  struct bitmap_element_def *next;
+  unsigned int indx;
+  BITMAP_WORD bits[((128 + (8 * 8 * 1u) - 1) / (8 * 8 * 1u))];
+} bitmap_element;
+
+
+
+
+
+
+typedef struct bitmap_head_def
+{
+  bitmap_element *first;
+
+} bitmap_head;
+
+
+
+static __inline__ unsigned char
+bitmap_elt_ior (bitmap dst, bitmap_element * dst_elt,
+		bitmap_element * dst_prev, const bitmap_element * a_elt,
+		const bitmap_element * b_elt, unsigned char changed)
+{
+
+  if (a_elt)
+    {
+
+      if (!changed && dst_elt)
+	{
+	  changed = 1;
+	}
+    }
+  else
+    {
+      changed = 1;
+    }
+  return changed;
+}
+
+unsigned char
+bitmap_ior_into (bitmap a, const_bitmap b)
+{
+  bitmap_element *a_elt = a->first;
+  const bitmap_element *b_elt = b->first;
+  bitmap_element *a_prev = ((void *) 0);
+  unsigned char changed = 0;
+
+  while (b_elt)
+    {
+
+      if (!a_elt || a_elt->indx == b_elt->indx)
+	changed = bitmap_elt_ior (a, a_elt, a_prev, a_elt, b_elt, changed);
+      else if (a_elt->indx > b_elt->indx)
+	changed = 1;
+      b_elt = b_elt->next;
+
+
+    }
+
+  return changed;
+}
+
+/* Verify that VRP simplified an "if" statement.  */
+/* { dg-final { scan-tree-dump "Folded into: if.*" "vrp2"} } */
+/* Verify that DCE after VRP2 eliminates a dead conversion
+   to a (Bool).  */
+/* { dg-final { scan-tree-dump "Deleting.*_Bool.*;" "cddce2"} } */
+/* { dg-final { cleanup-tree-dump "vrp2" } } */
+/* { dg-final { cleanup-tree-dump "cddce2" } } */
+
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 250a506..4520c89 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -8584,6 +8584,45 @@  simplify_cond_using_ranges (gimple stmt)
 	}
     }
 
+  /* If we have a comparison of a SSA_NAME boolean against
+     a constant (which obviously must be [0..1]), see if the
+     SSA_NAME was set by a type conversion where the source
+     of the conversion is another SSA_NAME with a range [0..1].
+
+     If so, we can replace the SSA_NAME in the comparison with
+     the RHS of the conversion.  This will often make the type
+     conversion dead code which DCE will clean up.  */
+  if (TREE_CODE (op0) == SSA_NAME
+      && (TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
+	  || (INTEGRAL_TYPE_P (TREE_TYPE (op))
+	      && TYPE_PRECISION (TREE_TYPE (op0)) == 1))
+      && TREE_CODE (op1) == INTEGER_CST)
+    {
+      gimple def_stmt = SSA_NAME_DEF_STMT (op0);
+      tree innerop;
+
+      if (!is_gimple_assign (def_stmt)
+	  || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
+	return false;
+
+      innerop = gimple_assign_rhs1 (def_stmt);
+
+      if (TREE_CODE (innerop) == SSA_NAME)
+	{
+	  value_range_t *vr = get_value_range (innerop);
+
+	  if (range_int_cst_p (vr)
+	      && operand_equal_p (vr->min, integer_zero_node, 0)
+	      && operand_equal_p (vr->max, integer_one_node, 0))
+	    {
+	      tree newconst = fold_convert (TREE_TYPE (innerop), op1);
+	      gimple_cond_set_lhs (stmt, innerop);
+	      gimple_cond_set_rhs (stmt, newconst);
+	      return true;
+	    }
+	}
+    }
+
   return false;
 }