diff options
author | Diego Novillo <dnovillo@redhat.com> | 2005-06-02 18:26:07 +0000 |
---|---|---|
committer | Diego Novillo <dnovillo@gcc.gnu.org> | 2005-06-02 14:26:07 -0400 |
commit | 462508dd7e13be8c480f49a684d31b19ac972794 (patch) | |
tree | c4ac2e10f438528f084722813917ea4a3f919688 /gcc | |
parent | 423ceeadf1fe2c682f75e11e6d860bcdea1879fa (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr21582.c | 28 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 56 |
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; } |