diff options
author | Jan Hubicka <jh@suse.cz> | 2012-10-14 18:18:26 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2012-10-14 16:18:26 +0000 |
commit | f9bf4777c1f93f733b4e99e44dd176417ed0afca (patch) | |
tree | 14ab7474f3d373fee0bea0afe2d5c0a3d96fa5e5 /gcc | |
parent | ca6729e2ed7b8a1308fdfdec0edcb6e9240f3258 (diff) | |
download | gcc-f9bf4777c1f93f733b4e99e44dd176417ed0afca.zip gcc-f9bf4777c1f93f733b4e99e44dd176417ed0afca.tar.gz gcc-f9bf4777c1f93f733b4e99e44dd176417ed0afca.tar.bz2 |
tree-ssa-loop-niter.c (estimate_numbers_of_iterations_loop): Do not predict loops with multiple exits realistically.
* tree-ssa-loop-niter.c (estimate_numbers_of_iterations_loop): Do not
predict loops with multiple exits realistically.
* cfgloopanal.c (single_likely_exit): New function.
* gcc.dg/unroll_5.c: New testcase.
From-SVN: r192433
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cfgloopanal.c | 37 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/unroll_5.c | 25 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-niter.c | 4 |
5 files changed, 75 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b74a547..a50d9d3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-10-14 Jan Hubicka <jh@suse.cz> + + * tree-ssa-loop-niter.c (estimate_numbers_of_iterations_loop): Do not + predict loops with multiple exits realistically. + * cfgloopanal.c (single_likely_exit): New function. + 2012-10-14 Uros Bizjak <ubizjak@gmail.com> * config/alpha/alpha.md: Remove empty predicates and/or constraints. diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c index cec33fb..c3cf3ed 100644 --- a/gcc/cfgloopanal.c +++ b/gcc/cfgloopanal.c @@ -446,3 +446,40 @@ mark_loop_exit_edges (void) } } +/* Return exit edge if loop has only one exit that is likely + to be executed on runtime (i.e. it is not EH or leading + to noreturn call. */ + +edge +single_likely_exit (struct loop *loop) +{ + edge found = single_exit (loop); + VEC (edge, heap) *exits; + unsigned i; + edge ex; + + if (found) + return found; + exits = get_loop_exit_edges (loop); + FOR_EACH_VEC_ELT (edge, exits, i, ex) + { + if (ex->flags & (EDGE_EH | EDGE_ABNORMAL_CALL)) + continue; + /* The constant of 5 is set in a way so noreturn calls are + ruled out by this test. The static branch prediction algorithm + will not assign such a low probability to conditionals for usual + reasons. */ + if (profile_status != PROFILE_ABSENT + && ex->probability < 5 && !ex->count) + continue; + if (!found) + found = ex; + else + { + VEC_free (edge, heap, exits); + return NULL; + } + } + VEC_free (edge, heap, exits); + return found; +} diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3a7dd93..79aee2f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2012-10-14 Jan Hubicka <jh@suse.cz> + + * gcc.dg/unroll_5.c: New testcase. + 2012-10-14 Paolo Carlini <paolo.carlini@oracle.com> PR c++/52643 diff --git a/gcc/testsuite/gcc.dg/unroll_5.c b/gcc/testsuite/gcc.dg/unroll_5.c new file mode 100644 index 0000000..48259eb --- /dev/null +++ b/gcc/testsuite/gcc.dg/unroll_5.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-rtl-loop2_unroll -funroll-loops" } */ +void abort (void); +int *a; +int t() +{ + int i; + for (i=0;i<1000000;i++) + if (a[i]) + return 1; + return 0; +} +int t2() +{ + int i; + for (i=0;i<3000000;i++) + if (a[i]) + abort (); + return 0; +} +/* { dg-final { scan-rtl-dump-times "upper bound: 999999" 1 "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump-not "realistic bound: 999999" "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump-times "upper bound: 2999999" 1 "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump-times "realistic bound: 2999999" 1 "loop2_unroll" } } */ +/* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */ diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index cdcdb5c..3c39413 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -2965,6 +2965,7 @@ estimate_numbers_of_iterations_loop (struct loop *loop) struct tree_niter_desc niter_desc; edge ex; double_int bound; + edge likely_exit; /* Give up if we already have tried to compute an estimation. */ if (loop->estimate_state != EST_NOT_COMPUTED) @@ -2975,6 +2976,7 @@ estimate_numbers_of_iterations_loop (struct loop *loop) loop->any_estimate = false; exits = get_loop_exit_edges (loop); + likely_exit = single_likely_exit (loop); FOR_EACH_VEC_ELT (edge, exits, i, ex) { if (!number_of_iterations_exit (loop, ex, &niter_desc, false)) @@ -2988,7 +2990,7 @@ estimate_numbers_of_iterations_loop (struct loop *loop) niter); record_estimate (loop, niter, niter_desc.max, last_stmt (ex->src), - true, true, true); + true, ex == likely_exit, true); } VEC_free (edge, heap, exits); |