diff options
author | Jeff Law <law@redhat.com> | 2005-07-28 10:12:03 -0600 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2005-07-28 10:12:03 -0600 |
commit | d579f20bb15e25f8f2038e5bd63bcab24f8df969 (patch) | |
tree | 4f30582e4a9ca2127fb82c5f528d9bbdb9dce62d /gcc | |
parent | 3353ebf08ac8c1d5ed1162eddb327b21a119ee34 (diff) | |
download | gcc-d579f20bb15e25f8f2038e5bd63bcab24f8df969.zip gcc-d579f20bb15e25f8f2038e5bd63bcab24f8df969.tar.gz gcc-d579f20bb15e25f8f2038e5bd63bcab24f8df969.tar.bz2 |
tree-vrp.c (test_for_singularity): Extracted from ...
* tree-vrp.c (test_for_singularity): Extracted from ...
(simplify_cond_using_ranges): Attempt to simplify a relational
test to NE_EXPR. Dump information when a COND_EXPR is simplified.
* gcc.dg/tree-ssa/vrp17.c: Update expected output.
* gcc.dg/tree-ssa/vrp18.c: New test.
From-SVN: r102489
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/vrp17.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/vrp18.c | 34 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 138 |
5 files changed, 144 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 404286c..e9f5558 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-07-28 Jeff Law <law@redhat.com> + + * tree-vrp.c (test_for_singularity): Extracted from ... + (simplify_cond_using_ranges): Attempt to simplify a relational + test to NE_EXPR. Dump information when a COND_EXPR is simplified. + 2005-07-28 Dorit Nuzman <dorit@il.ibm.com> PR tree-optimization/22506 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 16c797a..d2382f3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-07-28 Jeff Law <law@redhat.com> + + * gcc.dg/tree-ssa/vrp17.c: Update expected output. + * gcc.dg/tree-ssa/vrp18.c: New test. + 2005-07-28 Dorit Nuzman <dorit@il.ibm.com> * gcc.dg/vect/vect-reduc-1char.c: Fix data to fit in char. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp17.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp17.c index 3df4acd..217929d 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp17.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp17.c @@ -27,6 +27,6 @@ gimplify_for_stmt (tree stmt) abort (); } -/* { dg-final { scan-tree-dump-times "== 3" 1 "vrp" } } */ +/* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp" } } */ /* { dg-final { cleanup-tree-dump "vrp" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp18.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp18.c new file mode 100644 index 0000000..366c079 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp18.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-vrp" } */ + +static int blocksize = 4096; + +int bar (int); + +void foo (void) +{ + int toread; + int bytes; + static char eof_reached = 0; + + toread = blocksize; + bytes = 1; + + while (toread != 0) + { + bytes = bar (toread); + if (bytes <= 0) + { + if (bytes < 0) + continue; + break; + } + toread -= bytes; + } + + if (bytes == 0) + eof_reached = 1; +} + +/* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp" } } */ +/* { dg-final { cleanup-tree-dump "vrp" } } */ diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index af79ba4..be5f8b8 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -3616,6 +3616,66 @@ simplify_abs_using_ranges (tree stmt, tree rhs) } } +/* We are comparing trees OP0 and OP1 using COND_CODE. OP0 has + a known value range VR. + + If there is one and only one value which will satisfy the + conditional, then return that value. Else return NULL. */ + +static tree +test_for_singularity (enum tree_code cond_code, tree op0, + tree op1, value_range_t *vr) +{ + tree min = NULL; + tree max = NULL; + + /* Extract minimum/maximum values which satisfy the + the conditional as it was written. */ + if (cond_code == LE_EXPR || cond_code == LT_EXPR) + { + min = TYPE_MIN_VALUE (TREE_TYPE (op0)); + + max = op1; + if (cond_code == LT_EXPR) + { + tree one = build_int_cst (TREE_TYPE (op0), 1); + max = fold (build (MINUS_EXPR, TREE_TYPE (op0), max, one)); + } + } + else if (cond_code == GE_EXPR || cond_code == GT_EXPR) + { + max = TYPE_MAX_VALUE (TREE_TYPE (op0)); + + min = op1; + if (cond_code == GT_EXPR) + { + tree one = build_int_cst (TREE_TYPE (op0), 1); + max = fold (build (PLUS_EXPR, TREE_TYPE (op0), max, one)); + } + } + + /* Now refine the minimum and maximum values using any + value range information we have for op0. */ + if (min && max) + { + if (compare_values (vr->min, min) == -1) + min = min; + else + min = vr->min; + if (compare_values (vr->max, max) == 1) + max = max; + else + max = vr->max; + + /* If the new min/max values have converged to a + single value, then there is only one value which + can satisfy the condition, return that value. */ + if (min == max && is_gimple_min_invariant (min)) + return min; + } + return NULL; +} + /* Simplify a conditional using a relational operator to an equality test if the range information indicates only one value can satisfy the original conditional. */ @@ -3640,58 +3700,56 @@ simplify_cond_using_ranges (tree stmt) able to simplify this conditional. */ if (vr->type == VR_RANGE) { - tree min = NULL; - tree max = NULL; + tree new = test_for_singularity (cond_code, op0, op1, vr); - /* Extract minimum/maximum values which satisfy the - the conditional as it was written. */ - if (cond_code == LE_EXPR || cond_code == LT_EXPR) + if (new) { - min = TYPE_MIN_VALUE (TREE_TYPE (op0)); - - max = op1; - if (cond_code == LT_EXPR) + if (dump_file) { - tree one = build_int_cst (TREE_TYPE (op0), 1); - max = fold (build (MINUS_EXPR, TREE_TYPE (op0), max, one)); + fprintf (dump_file, "Simplified relational "); + print_generic_expr (dump_file, cond, 0); + fprintf (dump_file, " into "); } - } - else if (cond_code == GE_EXPR || cond_code == GT_EXPR) - { - max = TYPE_MAX_VALUE (TREE_TYPE (op0)); - min = op1; - if (cond_code == GT_EXPR) + COND_EXPR_COND (stmt) + = build (EQ_EXPR, boolean_type_node, op0, new); + update_stmt (stmt); + + if (dump_file) { - tree one = build_int_cst (TREE_TYPE (op0), 1); - max = fold (build (PLUS_EXPR, TREE_TYPE (op0), max, one)); + print_generic_expr (dump_file, COND_EXPR_COND (stmt), 0); + fprintf (dump_file, "\n"); } + return; + } - /* Now refine the minimum and maximum values using any - value range information we have for op0. */ - if (min && max) + /* Try again after inverting the condition. We only deal + with integral types here, so no need to worry about + issues with inverting FP comparisons. */ + cond_code = invert_tree_comparison (cond_code, false); + new = test_for_singularity (cond_code, op0, op1, vr); + + if (new) { - if (compare_values (vr->min, min) == -1) - min = min; - else - min = vr->min; - if (compare_values (vr->max, max) == 1) - max = max; - else - max = vr->max; - - /* If the new min/max values have converged to a - single value, then there is only one value which - can satisfy the condition. Rewrite the condition - to test for equality. */ - if (min == max - && is_gimple_min_invariant (min)) + if (dump_file) { - COND_EXPR_COND (stmt) - = build (EQ_EXPR, boolean_type_node, op0, min); - update_stmt (stmt); + fprintf (dump_file, "Simplified relational "); + print_generic_expr (dump_file, cond, 0); + fprintf (dump_file, " into "); } + + COND_EXPR_COND (stmt) + = build (NE_EXPR, boolean_type_node, op0, new); + update_stmt (stmt); + + if (dump_file) + { + print_generic_expr (dump_file, COND_EXPR_COND (stmt), 0); + fprintf (dump_file, "\n"); + } + return; + } } } |