Hi,

This patch tries to add nonnull_p attribute to ptr_info_def. As it stands, range_info_def is bigger in size than ptr_info_def. Therefore adding nonnull_p should not change the size.

I am setting this based on the VRP analysis. Right there is no uses for this. But the idea is, this can be used in IPA-VRP such that redundant check for NULL can be eliminated.

Bootstrapped and regression tested on x86_64-linux-gnu. Is this OK for trunk.

Thanks,
Kugan


gcc/ChangeLog:

2016-08-08  Kugan Vivekanandarajah  <kug...@linaro.org>

        * tree-ssanames.c (set_ptr_nonnull): New.
        (get_ptr_nonnull): Likewise.
        * tree-ssanames.h (struct ptr_info_def): Add nonnull_p attribute.
        * tree-vrp.c (vrp_finalize): Call set_ptr_nonnull.
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 91a8f97..19c9027 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -374,6 +374,27 @@ 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, bool nonnull_p)
+{
+  gcc_assert (POINTER_TYPE_P (TREE_TYPE (name)));
+  struct ptr_info_def *pi = get_ptr_info (name);
+  pi->nonnull_p = nonnull_p;;
+}
+
+/* Return nonnull attribute of pointer NAME.  */
+bool
+get_ptr_nonnull (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;
+  return pi->nonnull_p;
+}
+
 /* Change non-zero bits bitmask of NAME.  */
 
 void
diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h
index c81b1a1..6e34433 100644
--- a/gcc/tree-ssanames.h
+++ b/gcc/tree-ssanames.h
@@ -43,6 +43,9 @@ struct GTY(()) ptr_info_def
      above alignment.  Access only through the same helper functions as align
      above.  */
   unsigned int misalign;
+  /* When this pointer is knonw to be nnonnull this would be true otherwise
+     false.  */
+  bool  nonnull_p;
 };
 
 /* Value range information for SSA_NAMEs representing non-pointer variables.  
*/
@@ -89,6 +92,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 name, bool nonnull_p);
+extern bool get_ptr_nonnull (tree name);
 
 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 7c7ad91..40c4d48 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -10352,18 +10352,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, true);
+       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,

Reply via email to