From 735b8f9fc4b14384b246b39dfccbf529402b7791 Mon Sep 17 00:00:00 2001 From: Kugan Vivekanandarajah Date: Mon, 17 Oct 2016 23:35:48 +0000 Subject: [PATCH] Set nonnull attribute to ptr_info_def based on VRP Set nonnull attribute to ptr_info_def based on VRP gcc/ChangeLog: 2016-10-18 Kugan Vivekanandarajah * tree-ssa-alias.h (pt_solution_singleton_or_null_p): Renamed from pt_solution_singleton_p. * tree-ssa-ccp.c (fold_builtin_alloca_with_align): Use renamed pt_solution_singleton_or_null_p from pt_solution_singleton_p. * tree-ssa-structalias.c (find_what_p_points_to): Preserve pointer nonnull computed by VRP. Also Conservatively set pt.null to 1. (pt_solution_reset): Conservatively set pt.null to 1. (pt_solution_singleton_or_null_p): Renamed from pt_solution_singleton_p. * tree-ssanames.h (set_ptr_nonnull): Declare. (get_ptr_nonnull): Likewise. * tree-ssanames.c (set_ptr_nonnull): New. (get_ptr_nonnull): Likewise. * tree-vrp.c (vrp_finalize): Set ptr that are nonnull. (evrp_dom_walker::before_dom_children): Likewise. gcc/testsuite/ChangeLog: 2016-10-18 Kugan Vivekanandarajah * gcc.dg/torture/pr39074-2.c: Adjust testcase. * gcc.dg/torture/pr39074.c: Likewise. From-SVN: r241287 --- gcc/ChangeLog | 19 ++++++++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/torture/pr39074-2.c | 2 +- gcc/testsuite/gcc.dg/torture/pr39074.c | 2 +- gcc/tree-ssa-alias.h | 2 +- gcc/tree-ssa-ccp.c | 2 +- gcc/tree-ssa-structalias.c | 12 +++++-- gcc/tree-ssanames.c | 29 ++++++++++++++++ gcc/tree-ssanames.h | 2 ++ gcc/tree-vrp.c | 44 ++++++++++++++++-------- 10 files changed, 98 insertions(+), 21 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dcf210f3511..86f48345cbe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2016-10-18 Kugan Vivekanandarajah + + * tree-ssa-alias.h (pt_solution_singleton_or_null_p): Renamed from + pt_solution_singleton_p. + * tree-ssa-ccp.c (fold_builtin_alloca_with_align): Use renamed + pt_solution_singleton_or_null_p from pt_solution_singleton_p. + * tree-ssa-structalias.c (find_what_p_points_to): Preserve + pointer nonnull computed by VRP. + Also Conservatively set pt.null to 1. + (pt_solution_reset): Conservatively set pt.null to 1. + (pt_solution_singleton_or_null_p): Renamed from + pt_solution_singleton_p. + * tree-ssanames.h (set_ptr_nonnull): Declare. + (get_ptr_nonnull): Likewise. + * tree-ssanames.c (set_ptr_nonnull): New. + (get_ptr_nonnull): Likewise. + * tree-vrp.c (vrp_finalize): Set ptr that are nonnull. + (evrp_dom_walker::before_dom_children): Likewise. + 2016-10-17 Eric Botcazou * config/i386/i386.h (TARGET_CUSTOM_FUNCTION_DESCRIPTORS): Move to... diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 12bcfa6ade7..d59844272ce 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-10-18 Kugan Vivekanandarajah + + * gcc.dg/torture/pr39074-2.c: Adjust testcase. + * gcc.dg/torture/pr39074.c: Likewise. + 2016-10-17 Eric Botcazou * gcc.dg/Wtrampolines.c: XFAIL warning on ia64-*-* and powerpc64-*-*. diff --git a/gcc/testsuite/gcc.dg/torture/pr39074-2.c b/gcc/testsuite/gcc.dg/torture/pr39074-2.c index 740b463debc..0693f2d6fce 100644 --- a/gcc/testsuite/gcc.dg/torture/pr39074-2.c +++ b/gcc/testsuite/gcc.dg/torture/pr39074-2.c @@ -31,4 +31,4 @@ int main() } /* { dg-final { scan-tree-dump "y.._. = { i }" "alias" } } */ -/* { dg-final { scan-tree-dump "y.._., points-to vars: { D..... }" "alias" } } */ +/* { dg-final { scan-tree-dump "y.._., points-to NULL, points-to vars: { D..... }" "alias" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/pr39074.c b/gcc/testsuite/gcc.dg/torture/pr39074.c index 31ed499bfda..54c444e19a4 100644 --- a/gcc/testsuite/gcc.dg/torture/pr39074.c +++ b/gcc/testsuite/gcc.dg/torture/pr39074.c @@ -30,4 +30,4 @@ int main() } /* { dg-final { scan-tree-dump "y.._. = { i }" "alias" } } */ -/* { dg-final { scan-tree-dump "y.._., points-to vars: { D..... }" "alias" } } */ +/* { dg-final { scan-tree-dump "y.._., points-to NULL, points-to vars: { D..... }" "alias" } } */ diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h index 6680cc0a1eb..27a06fcca2c 100644 --- a/gcc/tree-ssa-alias.h +++ b/gcc/tree-ssa-alias.h @@ -146,7 +146,7 @@ extern void dump_alias_stats (FILE *); /* In tree-ssa-structalias.c */ extern unsigned int compute_may_aliases (void); extern bool pt_solution_empty_p (struct pt_solution *); -extern bool pt_solution_singleton_p (struct pt_solution *, unsigned *); +extern bool pt_solution_singleton_or_null_p (struct pt_solution *, unsigned *); extern bool pt_solution_includes_global (struct pt_solution *); extern bool pt_solution_includes (struct pt_solution *, const_tree); extern bool pt_solutions_intersect (struct pt_solution *, struct pt_solution *); diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index fe9a31320fa..61754d8d758 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -2135,7 +2135,7 @@ fold_builtin_alloca_with_align (gimple *stmt) { bool singleton_p; unsigned uid; - singleton_p = pt_solution_singleton_p (&pi->pt, &uid); + singleton_p = pt_solution_singleton_or_null_p (&pi->pt, &uid); gcc_assert (singleton_p); SET_DECL_PT_UID (var, uid); } diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 2a4ab2f4dc6..78f45334785 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -6451,6 +6451,7 @@ find_what_p_points_to (tree fndecl, tree p) struct ptr_info_def *pi; tree lookup_p = p; varinfo_t vi; + bool nonnull = get_ptr_nonnull (p); /* For parameters, get at the points-to set for the actual parm decl. */ @@ -6466,6 +6467,12 @@ find_what_p_points_to (tree fndecl, tree p) pi = get_ptr_info (p); pi->pt = find_what_var_points_to (fndecl, vi); + /* Conservatively set to NULL from PTA (to true). */ + pi->pt.null = 1; + /* Preserve pointer nonnull computed by VRP. See get_ptr_nonnull + in gcc/tree-ssaname.c for more information. */ + if (nonnull) + set_ptr_nonnull (p); } @@ -6505,6 +6512,7 @@ pt_solution_reset (struct pt_solution *pt) { memset (pt, 0, sizeof (struct pt_solution)); pt->anything = true; + pt->null = true; } /* Set the points-to solution *PT to point only to the variables @@ -6599,10 +6607,10 @@ pt_solution_empty_p (struct pt_solution *pt) return the var uid in *UID. */ bool -pt_solution_singleton_p (struct pt_solution *pt, unsigned *uid) +pt_solution_singleton_or_null_p (struct pt_solution *pt, unsigned *uid) { if (pt->anything || pt->nonlocal || pt->escaped || pt->ipa_escaped - || pt->null || pt->vars == NULL + || pt->vars == NULL || !bitmap_single_bit_set_p (pt->vars)) return false; diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index 64ab13a2048..913d142f046 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -374,6 +374,35 @@ get_range_info (const_tree name, wide_int *min, wide_int *max) return SSA_NAME_RANGE_TYPE (name); } +/* Set nonnull attribute to pointer NAME. */ + +void +set_ptr_nonnull (tree name) +{ + gcc_assert (POINTER_TYPE_P (TREE_TYPE (name))); + struct ptr_info_def *pi = get_ptr_info (name); + pi->pt.null = 0; +} + +/* Return nonnull attribute of pointer NAME. */ +bool +get_ptr_nonnull (const_tree name) +{ + gcc_assert (POINTER_TYPE_P (TREE_TYPE (name))); + struct ptr_info_def *pi = SSA_NAME_PTR_INFO (name); + if (pi == NULL) + return false; + /* TODO Now pt->null is conservatively set to true in PTA + analysis. vrp is the only pass (including ipa-vrp) + that clears pt.null via set_ptr_nonull when it knows + for sure. PTA will preserves the pt.null value set by VRP. + + When PTA analysis is improved, pt.anything, pt.nonlocal + and pt.escaped may also has to be considered before + deciding that pointer cannot point to NULL. */ + return !pi->pt.null; +} + /* Change non-zero bits bitmask of NAME. */ void diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h index 4496e1d044c..d39cc9d4e27 100644 --- a/gcc/tree-ssanames.h +++ b/gcc/tree-ssanames.h @@ -88,6 +88,8 @@ extern void set_ptr_info_alignment (struct ptr_info_def *, unsigned int, extern void adjust_ptr_info_misalignment (struct ptr_info_def *, unsigned int); extern struct ptr_info_def *get_ptr_info (tree); +extern void set_ptr_nonnull (tree); +extern bool get_ptr_nonnull (const_tree); extern tree copy_ssa_name_fn (struct function *, tree, gimple *); extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *); diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 1aebc722f7a..b11fc64dd8d 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -10601,18 +10601,24 @@ vrp_finalize (bool warn_array_bounds_p) { tree name = ssa_name (i); - if (!name - || POINTER_TYPE_P (TREE_TYPE (name)) - || (vr_value[i]->type == VR_VARYING) - || (vr_value[i]->type == VR_UNDEFINED)) - continue; + if (!name + || (vr_value[i]->type == VR_VARYING) + || (vr_value[i]->type == VR_UNDEFINED) + || (TREE_CODE (vr_value[i]->min) != INTEGER_CST) + || (TREE_CODE (vr_value[i]->max) != INTEGER_CST)) + continue; - if ((TREE_CODE (vr_value[i]->min) == INTEGER_CST) - && (TREE_CODE (vr_value[i]->max) == INTEGER_CST) - && (vr_value[i]->type == VR_RANGE - || vr_value[i]->type == VR_ANTI_RANGE)) - set_range_info (name, vr_value[i]->type, vr_value[i]->min, - vr_value[i]->max); + if (POINTER_TYPE_P (TREE_TYPE (name)) + && ((vr_value[i]->type == VR_RANGE + && range_includes_zero_p (vr_value[i]->min, + vr_value[i]->max) == 0) + || (vr_value[i]->type == VR_ANTI_RANGE + && range_includes_zero_p (vr_value[i]->min, + vr_value[i]->max) == 1))) + set_ptr_nonnull (name); + else if (!POINTER_TYPE_P (TREE_TYPE (name))) + set_range_info (name, vr_value[i]->type, vr_value[i]->min, + vr_value[i]->max); } substitute_and_fold (op_with_constant_singleton_value_range, @@ -10821,17 +10827,25 @@ evrp_dom_walker::before_dom_children (basic_block bb) def_operand_p def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF); /* Set the SSA with the value range. */ if (def_p - && TREE_CODE (DEF_FROM_PTR (def_p)) == SSA_NAME - && INTEGRAL_TYPE_P (TREE_TYPE (DEF_FROM_PTR (def_p)))) + && TREE_CODE (DEF_FROM_PTR (def_p)) == SSA_NAME) { tree def = DEF_FROM_PTR (def_p); value_range *vr = get_value_range (def); - if ((vr->type == VR_RANGE - || vr->type == VR_ANTI_RANGE) + if (INTEGRAL_TYPE_P (TREE_TYPE (DEF_FROM_PTR (def_p))) + && (vr->type == VR_RANGE + || vr->type == VR_ANTI_RANGE) && (TREE_CODE (vr->min) == INTEGER_CST) && (TREE_CODE (vr->max) == INTEGER_CST)) set_range_info (def, vr->type, vr->min, vr->max); + else if (POINTER_TYPE_P (TREE_TYPE (DEF_FROM_PTR (def_p))) + && ((vr->type == VR_RANGE + && range_includes_zero_p (vr->min, + vr->max) == 0) + || (vr->type == VR_ANTI_RANGE + && range_includes_zero_p (vr->min, + vr->max) == 1))) + set_ptr_nonnull (def); } } else -- 2.30.2