From 581f18857bd28bf20e979e0b24f0c9cfade61003 Mon Sep 17 00:00:00 2001 From: law Date: Wed, 8 Mar 2006 22:07:37 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@111848 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 11 ++++++ gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/g++.dg/tree-ssa/pr26406.C | 14 ++++++++ gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c | 2 +- gcc/tree-vrp.c | 57 ++++++++++++++++++++++-------- 6 files changed, 76 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr26406.C 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 + + * 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 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 + + * 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 * 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; + } } } -- 2.7.4