This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] tree-vrp.c: Teach VRP that &p->a is nonzero if p is knownto be nonzero.


Hi,

Attached is a patch to teach VRP that &p->a is nonzero if p is known
to be nonzero.

While I was playing with FOR_EACH_EDGE, Andrew Pinski told me that VRP
did not know that &p->a is nonnull when p is nonnull.

This patch teaches VRP to pick up nonzeroness while visiting a
statement whose RHS is of the form &p->a.

One question I have is whether it is safe to ignore the wrapping that
might happen to a pointer.  If I have the following on a 32-bit system

  struct s { int a; int b; } *p;

and p is 0xfffffffc, then &p->b could be 0.  Should I worry about such
a case?  This case is very pathological, but people throw all kinds of
weird stuff at the compiler anyway. :-) If I have to worry about
wrapping, then I suppose we can still do the optimization for &p->a,
which has offset 0.

Testing on cc1-i files shows that VRP folds 230 predicates with this
patch.  Without this patch, VRP folds 215 predicates.  With a TCB-like
pass ordering, we should be able to fold more, but I did not try that
this time.

Note that this patch has no reference to
flag_delete_null_pointer_checks.  The flag is about dereferencing a
pointer.  The proposed optimization has nothing to do with a
dereference although 'p' may be found to be nonnull by a dereference
that happens earlier.

Tested on i686-pc-linux-gnu.  OK to apply?

Kazu Hirata

2005-05-01  Kazu Hirata  <kazu@cs.umass.edu>

	PR tree-optimization/21294
	* tree-vrp.c (vrp_expr_computes_nonzero): New.
	(extract_range_from_expr): Call vrp_expr_computes_nonzero.

2005-05-01  Kazu Hirata  <kazu@cs.umass.edu>

	PR tree-optimization/21294
	* gcc.dg/tree-ssa/pr21294.c: New.

Index: tree-vrp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vrp.c,v
retrieving revision 2.14
diff -u -d -p -r2.14 tree-vrp.c
--- tree-vrp.c	29 Apr 2005 16:22:52 -0000	2.14
+++ tree-vrp.c	1 May 2005 19:15:43 -0000
@@ -717,6 +717,35 @@ extract_range_from_binary_expr (value_ra
 }
 
 
+/* Like expr_computes_nonzero, but this function uses value ranges
+   obtained so far.  */
+
+static bool
+vrp_expr_computes_nonzero (tree expr)
+{
+  if (expr_computes_nonzero (expr))
+    return true;
+
+  /* If we have an expression of the form &X->a, then the expression
+     is nonnull if X is nonnull.  */
+  if (TREE_CODE (expr) == ADDR_EXPR)
+    {
+      tree base = get_base_address (TREE_OPERAND (expr, 0));
+
+      if (base != NULL_TREE
+	  && TREE_CODE (base) == INDIRECT_REF
+	  && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
+	{
+	  value_range *vr = get_value_range (TREE_OPERAND (base, 0));
+	  if (range_is_nonnull (vr))
+	    return true;
+	}
+    }
+
+  return false;
+}
+
+
 /* Extract range information from a unary expression EXPR based on
    the range of its operand and the expression code.  */
 
@@ -833,7 +862,7 @@ extract_range_from_expr (value_range *vr
     extract_range_from_binary_expr (vr, expr);
   else if (TREE_CODE_CLASS (code) == tcc_unary)
     extract_range_from_unary_expr (vr, expr);
-  else if (expr_computes_nonzero (expr))
+  else if (vrp_expr_computes_nonzero (expr))
     set_value_range_to_nonnull (vr, TREE_TYPE (expr));
   else if (TREE_CODE (expr) == INTEGER_CST)
     set_value_range (vr, VR_RANGE, expr, expr);
--- /dev/null	2005-04-29 10:25:17.000000000 -0400
+++ testsuite/gcc.dg/tree-ssa/pr21294.c	2005-05-01 15:13:50.000000000 -0400
@@ -0,0 +1,23 @@
+/* PR tree-optimization/21294
+   VRP did not notice that an address of the form &p->i is nonnull
+   when p is known to be nonnull.  In this testcase, noticing that
+   allows us to eliminate the second "if" statement.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-dominator-opts -fdump-tree-vrp-details" } */
+
+struct f {
+  int i;
+};
+
+int
+foo (struct f *p)
+{
+  if (p != 0)
+    if (&p->i != 0)
+      return 123;
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "Folding predicate" 1 "vrp"} } */
+/* { dg-final { cleanup-tree-dump "vrp" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]