aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
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/tree-vrp.c
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/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c57
1 files changed, 43 insertions, 14 deletions
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;
+ }
}
}