diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2016-05-30 12:40:33 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2016-05-30 10:40:33 +0000 |
commit | 98bdbb39a6676776c528f3b51ce740669c06d708 (patch) | |
tree | 70d2283e17b094627b83cbfbd240e80625f370dd /gcc/tree-ssa-loop-ivcanon.c | |
parent | d5cf3d8da6ef568929fc8bdfc1809593ff1988a8 (diff) | |
download | gcc-98bdbb39a6676776c528f3b51ce740669c06d708.zip gcc-98bdbb39a6676776c528f3b51ce740669c06d708.tar.gz gcc-98bdbb39a6676776c528f3b51ce740669c06d708.tar.bz2 |
predict.h (force_edge_cold): Declare.
* predict.h (force_edge_cold): Declare.
* predict.c (force_edge_cold): New function.
* tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Fix profile
updating.
(canonicalize_loop_induction_variables): Fix formating.
* gcc.dg/tree-ssa/cunroll-12.c: New testcase.
* gcc.dg/tree-ssa/cunroll-13.c: New testcase.
* gcc.dg/tree-ssa/cunroll-14.c: New testcase.
From-SVN: r236874
Diffstat (limited to 'gcc/tree-ssa-loop-ivcanon.c')
-rw-r--r-- | gcc/tree-ssa-loop-ivcanon.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c index de447f4..4673d02 100644 --- a/gcc/tree-ssa-loop-ivcanon.c +++ b/gcc/tree-ssa-loop-ivcanon.c @@ -730,8 +730,14 @@ try_unroll_loop_completely (struct loop *loop, if (ul == UL_SINGLE_ITER) return false; + /* EXIT can be removed only if we are sure it passes first N_UNROLL + iterations. */ + bool remove_exit = (exit && niter + && TREE_CODE (niter) == INTEGER_CST + && wi::leu_p (n_unroll, wi::to_widest (niter))); + large = tree_estimate_loop_size - (loop, exit, edge_to_cancel, &size, + (loop, remove_exit ? exit : NULL, edge_to_cancel, &size, PARAM_VALUE (PARAM_MAX_COMPLETELY_PEELED_INSNS)); ninsns = size.overall; if (large) @@ -837,8 +843,20 @@ try_unroll_loop_completely (struct loop *loop, initialize_original_copy_tables (); wont_exit = sbitmap_alloc (n_unroll + 1); - bitmap_ones (wont_exit); - bitmap_clear_bit (wont_exit, 0); + if (exit && niter + && TREE_CODE (niter) == INTEGER_CST + && wi::leu_p (n_unroll, wi::to_widest (niter))) + { + bitmap_ones (wont_exit); + if (wi::eq_p (wi::to_widest (niter), n_unroll) + || edge_to_cancel) + bitmap_clear_bit (wont_exit, 0); + } + else + { + exit = NULL; + bitmap_clear (wont_exit); + } if (!gimple_duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop), n_unroll, wont_exit, @@ -869,6 +887,7 @@ try_unroll_loop_completely (struct loop *loop, if (edge_to_cancel) { gcond *cond = as_a <gcond *> (last_stmt (edge_to_cancel->src)); + force_edge_cold (edge_to_cancel, true); if (edge_to_cancel->flags & EDGE_TRUE_VALUE) gimple_cond_make_false (cond); else @@ -1112,8 +1131,8 @@ canonicalize_loop_induction_variables (struct loop *loop, if (dump_file && (dump_flags & TDF_DETAILS) && likely_max_loop_iterations_int (loop) >= 0) { - fprintf (dump_file, "Loop likely %d iterates at most %i times.\n", loop->num, - (int)likely_max_loop_iterations_int (loop)); + fprintf (dump_file, "Loop %d likely iterates at most %i times.\n", + loop->num, (int)likely_max_loop_iterations_int (loop)); } /* Remove exits that are known to be never taken based on loop bound. |