aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorDiego Novillo <dnovillo@redhat.com>2005-06-02 18:26:07 +0000
committerDiego Novillo <dnovillo@gcc.gnu.org>2005-06-02 14:26:07 -0400
commit462508dd7e13be8c480f49a684d31b19ac972794 (patch)
treec4ac2e10f438528f084722813917ea4a3f919688 /gcc/tree-vrp.c
parent423ceeadf1fe2c682f75e11e6d860bcdea1879fa (diff)
downloadgcc-462508dd7e13be8c480f49a684d31b19ac972794.zip
gcc-462508dd7e13be8c480f49a684d31b19ac972794.tar.gz
gcc-462508dd7e13be8c480f49a684d31b19ac972794.tar.bz2
re PR tree-optimization/21582 ((optimisation) VRP pass could/should use non-null function attribute)
PR 21582 * tree-vrp.c (nonnull_arg_p): New. (get_value_range): Call it. testsuite/ChangeLog PR 21582 * gcc.dg/tree-ssa/pr21582.c: New test. From-SVN: r100505
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index f712cb3..e6087a5 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -165,6 +165,50 @@ expr_computes_nonzero (tree expr)
}
+/* Return true if ARG is marked with the nonnull attribute in the
+ current function signature. */
+
+static bool
+nonnull_arg_p (tree arg)
+{
+ tree t, attrs, fntype;
+ unsigned HOST_WIDE_INT arg_num;
+
+ gcc_assert (TREE_CODE (arg) == PARM_DECL && POINTER_TYPE_P (TREE_TYPE (arg)));
+
+ fntype = TREE_TYPE (current_function_decl);
+ attrs = lookup_attribute ("nonnull", TYPE_ATTRIBUTES (fntype));
+
+ /* If "nonnull" wasn't specified, we know nothing about the argument. */
+ if (attrs == NULL_TREE)
+ return false;
+
+ /* If "nonnull" applies to all the arguments, then ARG is non-null. */
+ if (TREE_VALUE (attrs) == NULL_TREE)
+ return true;
+
+ /* Get the position number for ARG in the function signature. */
+ for (arg_num = 1, t = DECL_ARGUMENTS (current_function_decl);
+ t;
+ t = TREE_CHAIN (t), arg_num++)
+ {
+ if (t == arg)
+ break;
+ }
+
+ gcc_assert (t == arg);
+
+ /* Now see if ARG_NUM is mentioned in the nonnull list. */
+ for (t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t))
+ {
+ if (compare_tree_int (TREE_VALUE (t), arg_num) == 0)
+ return true;
+ }
+
+ return false;
+}
+
+
/* Set value range VR to {T, MIN, MAX, EQUIV}. */
static void
@@ -291,7 +335,17 @@ get_value_range (tree var)
in VAR's type. */
sym = SSA_NAME_VAR (var);
if (var == var_ann (sym)->default_def)
- set_value_range_to_varying (vr);
+ {
+ /* Try to use the "nonnull" attribute to create ~[0, 0]
+ anti-ranges for pointers. Note that this is only valid with
+ default definitions of PARM_DECLs. */
+ if (TREE_CODE (sym) == PARM_DECL
+ && POINTER_TYPE_P (TREE_TYPE (sym))
+ && nonnull_arg_p (sym))
+ set_value_range_to_nonnull (vr, TREE_TYPE (sym));
+ else
+ set_value_range_to_varying (vr);
+ }
return vr;
}