* tree-vrp.c (infer_value_range): Only count pointer uses
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Mar 2006 22:07:37 +0000 (22:07 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Mar 2006 22:07:37 +0000 (22:07 +0000)
and dereferences if -fdelete-null-pointer-checks is enabled.

* tree-vrp.c (find_assert_locations): Infer value ranges for
single use pointers, but do not create ASSERT_EXPRs for them.
When a non-null range is inferred for a pointer, backwards
propagate that range to other equivalent pointers through the
use-def chain.

* gcc.dg/tree-ssa/20030730-1.c: No longer expected to fail.
* gcc.dg/tree-ssa/20030730-2.c: No longer expected to fail.
* g++.dg/tree-ssa/pr26406.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@111848 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/pr26406.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c
gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c
gcc/tree-vrp.c

index c88bc83..cacec9a 100644 (file)
@@ -1,3 +1,14 @@
+2006-03-08  Jeff Law  <law@redhat.com>
+
+       * tree-vrp.c (infer_value_range): Only count pointer uses
+       and dereferences if -fdelete-null-pointer-checks is enabled.
+
+       * tree-vrp.c (find_assert_locations): Infer value ranges for
+       single use pointers, but do not create ASSERT_EXPRs for them.
+       When a non-null range is inferred for a pointer, backwards
+       propagate that range to other equivalent pointers through the
+       use-def chain.
+
 2006-03-08  Paolo Bonzini  <bonzini@gnu.org>
 
        PR bootstrap/26500
index c5eb679..bf0df23 100644 (file)
@@ -1,3 +1,9 @@
+2006-03-08  Jeff Law  <law@redhat.com>
+
+       * gcc.dg/tree-ssa/20030730-1.c: No longer expected to fail.
+       * gcc.dg/tree-ssa/20030730-2.c: No longer expected to fail.
+       * g++.dg/tree-ssa/pr26406.C: New test.
+
 2006-03-07  Jeff Law  <law@redhat.com>
 
        * gcc.dg/tree-ssa/20030730-1.c: Temporarily xfail.
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr26406.C b/gcc/testsuite/g++.dg/tree-ssa/pr26406.C
new file mode 100644 (file)
index 0000000..c2d1605
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int *f(int *b)
+{
+  int * a = new int[104];
+  *a = 1;
+  if (a == 0)
+    return b;
+  return a;
+}
+
+/* { dg-final { scan-tree-dump-not "if" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
index 753e668..ded6ef7 100644 (file)
@@ -19,6 +19,6 @@ foo (int attr_kind, unsigned long offset)
 }
 
 /* There should be no IF conditionals.  */
-/* { dg-final { scan-tree-dump-times "if " 0 "dom3" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "if " 0 "dom3" } } */
                                                                                 
 /* { dg-final { cleanup-tree-dump "dom3" } } */
index ebdce22..8b53d81 100644 (file)
@@ -19,6 +19,6 @@ foo (int attr_kind, unsigned long offset)
 }
 
 /* There should be no IF conditionals.  */
-/* { dg-final { scan-tree-dump-times "if " 0 "dom3" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "if " 0 "dom3" } } */
 
 /* { dg-final { cleanup-tree-dump "dom3" } } */
index 7342d29..e126fea 100644 (file)
@@ -2440,16 +2440,16 @@ infer_value_range (tree stmt, tree op, enum tree_code *comp_code_p, tree *val_p)
   if (stmt_ends_bb_p (stmt) && EDGE_COUNT (bb_for_stmt (stmt)->succs) == 0)
     return false;
 
-  if (POINTER_TYPE_P (TREE_TYPE (op)))
+  /* We can only assume that a pointer dereference will yield
+     non-NULL if -fdelete-null-pointer-checks is enabled.  */
+  if (flag_delete_null_pointer_checks && POINTER_TYPE_P (TREE_TYPE (op)))
     {
       bool is_store;
       unsigned num_uses, num_derefs;
 
       count_uses_and_derefs (op, stmt, &num_uses, &num_derefs, &is_store);
-      if (num_derefs > 0 && flag_delete_null_pointer_checks)
+      if (num_derefs > 0)
        {
-         /* We can only assume that a pointer dereference will yield
-            non-NULL if -fdelete-null-pointer-checks is enabled.  */
          *val_p = build_int_cst (TREE_TYPE (op), 0);
          *comp_code_p = NE_EXPR;
          return true;
@@ -2952,21 +2952,50 @@ find_assert_locations (basic_block bb)
             operands it was looking for was present in the sub-graph.  */
          SET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));
 
-         /* If OP is used only once, namely in this STMT, don't
-            bother creating an ASSERT_EXPR for it.  Such an
-            ASSERT_EXPR would do nothing but increase compile time.
-            Experiments show that with this simple check, we can save
-            more than 20% of ASSERT_EXPRs.  */
-         if (has_single_use (op))
-           continue;
-
          /* If OP is used in such a way that we can infer a value
             range for it, and we don't find a previous assertion for
             it, create a new assertion location node for OP.  */
          if (infer_value_range (stmt, op, &comp_code, &value))
            {
-             register_new_assert_for (op, comp_code, value, bb, NULL, si);
-             need_assert = true;
+             /* If we are able to infer a non-zero value range for OP,
+                then walk backwards through the use-def chain to see if OP
+                was set via a typecast.
+
+                If so, then we can also infer a nonzero value range
+                for the operand of the NOP_EXPR.  */
+             if (comp_code == NE_EXPR && integer_zerop (value))
+               {
+                 tree t = op;
+                 tree def_stmt = SSA_NAME_DEF_STMT (t);
+       
+                 while (TREE_CODE (def_stmt) == MODIFY_EXPR
+                        && TREE_CODE (TREE_OPERAND (def_stmt, 1)) == NOP_EXPR
+                        && TREE_CODE (TREE_OPERAND (TREE_OPERAND (def_stmt, 1), 0)) == SSA_NAME
+                        && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (def_stmt, 1), 0))))
+                   {
+                     t = TREE_OPERAND (TREE_OPERAND (def_stmt, 1), 0);
+                     def_stmt = SSA_NAME_DEF_STMT (t);
+
+                     /* Note we want to register the assert for the
+                        operand of the NOP_EXPR after SI, not after the
+                        conversion.  */
+                     if (! has_single_use (t))
+                       {
+                         register_new_assert_for (t, comp_code, value,
+                                                  bb, NULL, si);
+                         need_assert = true;
+                       }
+                   }
+               }
+
+             /* If OP is used only once, namely in this STMT, don't
+                bother creating an ASSERT_EXPR for it.  Such an
+                ASSERT_EXPR would do nothing but increase compile time.  */
+             if (!has_single_use (op))
+               {
+                 register_new_assert_for (op, comp_code, value, bb, NULL, si);
+                 need_assert = true;
+               }
            }
        }