aboutsummaryrefslogtreecommitdiff
path: root/gcc
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
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')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr21582.c28
-rw-r--r--gcc/tree-vrp.c56
4 files changed, 94 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fa38950..5182b34 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-06-02 Diego Novillo <dnovillo@redhat.com>
+
+ PR 21582
+ * tree-vrp.c (nonnull_arg_p): New.
+ (get_value_range): Call it.
+
2005-06-02 Eric Christopher <echristo@redhat.com>
* config/mips/mips.h (processor_type): Remove PROCESSOR_DEFAULT,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 224ed08..5d508e5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2005-06-02 Diego Novillo <dnovillo@redhat.com>
+
+ PR 21582
+ * gcc.dg/tree-ssa/pr21582.c: New test.
+
2005-06-02 Nathan Sidwell <nathan@codesourcery.com>
PR c++/21280
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21582.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21582.c
new file mode 100644
index 0000000..eee5d94
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21582.c
@@ -0,0 +1,28 @@
+/* { dg-do link } */
+/* { dg-options "-O2 -fdump-tree-vrp" } */
+
+static inline void do_thing(char *s, int *p, char *q)
+{
+ /* This should be folded away. */
+ if (s == 0 || q == 0)
+ link_error ();
+
+ /* This should not be folded as 'p' is not marked nonnull. */
+ if (p)
+ *p = 3;
+}
+
+void __attribute__((nonnull (1, 3))) do_other_thing(char *s, int *p, char *q)
+{
+ do_thing(s, p, q);
+}
+
+int i;
+
+main()
+{
+ do_other_thing ("xxx", &i, "yyy");
+}
+
+/* { dg-final { scan-tree-dump-times "Folding predicate p_.*" 0 "vrp" } } */
+/* { dg-final { cleanup-tree-dump "vrp" } } */
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;
}