predict loops with multiple exits realistically.
* cfgloopanal.c (single_likely_exit): New function.
* gcc.dg/unroll_5.c: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@192433
138bc75d-0d04-0410-961f-
82ee72b054a4
+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.
}
}
+/* 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;
+}
+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
--- /dev/null
+/* { 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" } } */
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)
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))
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);