aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2006-03-08 15:07:37 -0700
committerJeff Law <law@gcc.gnu.org>2006-03-08 15:07:37 -0700
commit60c9ad4691a758d23173ffad0f95e4b1a6c8c4b8 (patch)
treefe11681f27645614115303f8349df8e8836f7a42 /gcc
parentd6c122f73bdb73f53e4ebf913e5c0e402860f429 (diff)
downloadgcc-60c9ad4691a758d23173ffad0f95e4b1a6c8c4b8.zip
gcc-60c9ad4691a758d23173ffad0f95e4b1a6c8c4b8.tar.gz
gcc-60c9ad4691a758d23173ffad0f95e4b1a6c8c4b8.tar.bz2
tree-vrp.c (infer_value_range): Only count pointer uses and dereferences if -fdelete-null-pointer-checks is enabled.
* 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. * 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. From-SVN: r111848
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr26406.C14
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c2
-rw-r--r--gcc/tree-vrp.c57
6 files changed, 76 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c88bc83..cacec9a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c5eb679..bf0df23 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..c2d1605
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr26406.C
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c
index 753e668..ded6ef7 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c
index ebdce22..8b53d81 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c
@@ -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" } } */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 7342d29..e126fea 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -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;
+ }
}
}