From d6e840eed2559f03c82cdb203cc2339c4a5c6425 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Sun, 27 Apr 2008 16:27:08 +0000 Subject: re PR tree-optimization/18754 (unrolling happens too late/SRA does not happen late enough) 2008-04-27 Richard Guenther PR tree-optimization/18754 PR tree-optimization/34223 * tree-pass.h (pass_complete_unrolli): Declare. * tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Print loop size before and after unconditionally of UL_NO_GROWTH in effect. Rewrite loop into loop closed SSA form if it is not already. (tree_unroll_loops_completely): Re-structure to iterate over innermost loops with intermediate CFG cleanups. Unroll outermost loops only if requested or the code does not grow doing so. * tree-ssa-loop.c (gate_tree_vectorize): Don't shortcut if no loops are available. (tree_vectorize): Instead do so here. (tree_complete_unroll): Also unroll outermost loops. (tree_complete_unroll_inner): New function. (gate_tree_complete_unroll_inner): Likewise. (pass_complete_unrolli): New pass. * tree-ssa-loop-manip.c (find_uses_to_rename_use): Only record uses outside of the loop. (tree_duplicate_loop_to_header_edge): Only verify loop-closed SSA form if it is available. * tree-flow.h (tree_unroll_loops_completely): Add extra parameter. * passes.c (init_optimization_passes): Schedule complete inner loop unrolling pass before the first CCP pass after final inlining. * gcc.dg/tree-ssa/loop-36.c: New testcase. * gcc.dg/tree-ssa/loop-37.c: Likewise. * gcc.dg/vect/vect-118.c: Likewise. * gcc.dg/Wunreachable-8.c: XFAIL bogus warning. * gcc.dg/vect/vect-66.c: Increase loop trip count. * gcc.dg/vect/no-section-anchors-vect-66.c: Likewise. * gcc.dg/vect/no-section-anchors-vect-69.c: Likewise. * gcc.dg/vect/vect-76.c: Likewise. * gcc.dg/vect/vect-outer-6.c: Likewise. * gcc.dg/vect/vect-outer-1.c: Likewise. * gcc.dg/vect/vect-outer-1a.c: Likewise. * gcc.dg/vect/vect-11a.c: Likewise. * gcc.dg/vect/vect-shift-1.c: Likewise. * gcc.target/i386/vectorize1.c: Likewise. From-SVN: r134730 --- gcc/tree-ssa-loop-ivcanon.c | 74 ++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 31 deletions(-) (limited to 'gcc/tree-ssa-loop-ivcanon.c') diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c index 5e9e248..1472b0d 100644 --- a/gcc/tree-ssa-loop-ivcanon.c +++ b/gcc/tree-ssa-loop-ivcanon.c @@ -187,23 +187,20 @@ try_unroll_loop_completely (struct loop *loop, > (unsigned) PARAM_VALUE (PARAM_MAX_COMPLETELY_PEELED_INSNS)) return false; - if (ul == UL_NO_GROWTH) + unr_insns = estimated_unrolled_size (ninsns, n_unroll); + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, " Loop size: %d\n", (int) ninsns); + fprintf (dump_file, " Estimated size after unrolling: %d\n", + (int) unr_insns); + } + + if (ul == UL_NO_GROWTH + && unr_insns > ninsns) { - unr_insns = estimated_unrolled_size (ninsns, n_unroll); - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, " Loop size: %d\n", (int) ninsns); - fprintf (dump_file, " Estimated size after unrolling: %d\n", - (int) unr_insns); - } - - if (unr_insns > ninsns) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "Not unrolling loop %d:\n", loop->num); - return false; - } + fprintf (dump_file, "Not unrolling loop %d.\n", loop->num); + return false; } } @@ -339,30 +336,45 @@ canonicalize_induction_variables (void) size of the code does not increase. */ unsigned int -tree_unroll_loops_completely (bool may_increase_size) +tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer) { loop_iterator li; struct loop *loop; - bool changed = false; + bool changed; enum unroll_level ul; - FOR_EACH_LOOP (li, loop, 0) + do { - if (may_increase_size && maybe_hot_bb_p (loop->header)) - ul = UL_ALL; - else - ul = UL_NO_GROWTH; - changed |= canonicalize_loop_induction_variables (loop, - false, ul, - !flag_tree_loop_ivcanon); - } + changed = false; - /* Clean up the information about numbers of iterations, since complete - unrolling might have invalidated it. */ - scev_reset (); + FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST) + { + if (may_increase_size && maybe_hot_bb_p (loop->header) + /* Unroll outermost loops only if asked to do so or they do + not cause code growth. */ + && (unroll_outer + || loop_outer (loop_outer (loop)))) + ul = UL_ALL; + else + ul = UL_NO_GROWTH; + changed |= canonicalize_loop_induction_variables + (loop, false, ul, !flag_tree_loop_ivcanon); + } + + if (changed) + { + /* This will take care of removing completely unrolled loops + from the loop structures so we can continue unrolling now + innermost loops. */ + cleanup_tree_cfg (); + + /* Clean up the information about numbers of iterations, since + complete unrolling might have invalidated it. */ + scev_reset (); + } + } + while (changed); - if (changed) - return TODO_cleanup_cfg; return 0; } -- cgit v1.1