Set nonnull attribute to ptr_info_def based on VRP
authorKugan Vivekanandarajah <kuganv@linaro.org>
Mon, 17 Oct 2016 23:35:48 +0000 (23:35 +0000)
committerKugan Vivekanandarajah <kugan@gcc.gnu.org>
Mon, 17 Oct 2016 23:35:48 +0000 (23:35 +0000)
Set nonnull attribute to ptr_info_def based on VRP
gcc/ChangeLog:

2016-10-18  Kugan Vivekanandarajah  <kuganv@linaro.org>

* 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  <kuganv@linaro.org>

* gcc.dg/torture/pr39074-2.c: Adjust testcase.
* gcc.dg/torture/pr39074.c: Likewise.

From-SVN: r241287

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr39074-2.c
gcc/testsuite/gcc.dg/torture/pr39074.c
gcc/tree-ssa-alias.h
gcc/tree-ssa-ccp.c
gcc/tree-ssa-structalias.c
gcc/tree-ssanames.c
gcc/tree-ssanames.h
gcc/tree-vrp.c

index dcf210f3511bc23ef4e3f21450f0286c50c52d44..86f48345cbe1249d33b5b59d8c3be650fd20f595 100644 (file)
@@ -1,3 +1,22 @@
+2016-10-18  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+       * 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  <ebotcazou@adacore.com>
 
        * config/i386/i386.h (TARGET_CUSTOM_FUNCTION_DESCRIPTORS): Move to...
index 12bcfa6ade71d70bd7c98b7c569addd65f5b24e1..d59844272cec6e612a6e94326a958a921866f815 100644 (file)
@@ -1,3 +1,8 @@
+2016-10-18  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+       * gcc.dg/torture/pr39074-2.c: Adjust testcase.
+       * gcc.dg/torture/pr39074.c: Likewise.
+
 2016-10-17  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc.dg/Wtrampolines.c: XFAIL warning on ia64-*-* and powerpc64-*-*.
index 740b463debcb1a461aa64ed5e7e63aa42283413f..0693f2d6fced8b78898eeabb892f80a57cda17ac 100644 (file)
@@ -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" } } */
index 31ed499bfda94efd2b16420b6725e621c99081a4..54c444e19a47d1de6a1215eddc4709851ffcfb8f 100644 (file)
@@ -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" } } */
index 6680cc0a1eb674979794dda411638d7ffd67d8d8..27a06fcca2c20bc1373856efff82afb690e1d7d5 100644 (file)
@@ -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 *);
index fe9a31320fa27c9d671b693379e85ed35a4e00e2..61754d8d7588c747229d145ee2fabc4e2cf1083a 100644 (file)
@@ -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);
       }
index 2a4ab2f4dc639cf7e9e40ea45793a93704848256..78f45334785071e9ffdf973eb5177c7732677533 100644 (file)
@@ -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;
 
index 64ab13a20487e95541dcd8d39b4dea4bdd386c23..913d142f0462e1647401bdefa21c2527b153ed5b 100644 (file)
@@ -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
index 4496e1d044c0af0fe92eef08bb6b62cc25a7273a..d39cc9d4e27c46c98176edcee02be7e7339875e9 100644 (file)
@@ -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 *);
index 1aebc722f7ada5bf2f1d4a7fbf3a8c978ea2d354..b11fc64dd8da641304bde9137b7194035c0d6f07 100644 (file)
@@ -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