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,