diff options
author | Teresa Johnson <tejohnson@google.com> | 2013-01-03 00:56:35 +0000 |
---|---|---|
committer | Teresa Johnson <tejohnson@gcc.gnu.org> | 2013-01-03 00:56:35 +0000 |
commit | e25a671164bb972075ae870d3b50f45f46e85eaf (patch) | |
tree | 30f5b42d2bf373055b9ccc82406aaf7132d801d2 /gcc | |
parent | 778786217358981221cea14a4c543eaa5fba2221 (diff) | |
download | gcc-e25a671164bb972075ae870d3b50f45f46e85eaf.zip gcc-e25a671164bb972075ae870d3b50f45f46e85eaf.tar.gz gcc-e25a671164bb972075ae870d3b50f45f46e85eaf.tar.bz2 |
dumpfile.c (dump_loc): Print filename with location.
2013-01-02 Teresa Johnson <tejohnson@google.com>
* dumpfile.c (dump_loc): Print filename with location.
* tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Use
new location_t parameter to emit complete unroll message with
new dump framework.
(canonicalize_loop_induction_variables): Compute loops location
and pass to try_unroll_loop_completely.
* loop-unroll.c (report_unroll_peel): New function.
(peel_loops_completely): Use new dump format with location
for main dumpfile message, and invoke report_unroll_peel on success.
(decide_unrolling_and_peeling): Ditto.
(decide_peel_once_rolling): Remove old dumpfile message subsumed
by report_unroll_peel.
(decide_peel_completely): Ditto.
(decide_unroll_constant_iterations): Ditto.
(decide_unroll_runtime_iterations): Ditto.
(decide_peel_simple): Ditto.
(decide_unroll_stupid): Ditto.
* cfgloop.c (get_loop_location): New function.
* cfgloop.h (get_loop_location): Declare.
testsuite/
* gcc.dg/tree-ssa/loop-1.c: Update expected dump message.
* gcc.dg/tree-ssa/loop-23.c: Ditto.
* gcc.dg/tree-ssa/cunroll-1.c: Ditto.
* gcc.dg/tree-ssa/cunroll-2.c: Ditto.
* gcc.dg/tree-ssa/cunroll-3.c: Ditto.
* gcc.dg/tree-ssa/cunroll-4.c: Ditto.
* gcc.dg/tree-ssa/cunroll-5.c: Ditto.
* gcc.dg/unroll_1.c: Ditto.
* gcc.dg/unroll_2.c: Ditto.
* gcc.dg/unroll_3.c: Ditto.
* gcc.dg/unroll_4.c: Ditto.
From-SVN: r194829
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 35 | ||||
-rw-r--r-- | gcc/cfgloop.c | 52 | ||||
-rw-r--r-- | gcc/cfgloop.h | 1 | ||||
-rw-r--r-- | gcc/dumpfile.c | 4 | ||||
-rw-r--r-- | gcc/loop-unroll.c | 96 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/loop-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/loop-23.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/unroll_1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/unroll_2.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/unroll_3.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/unroll_4.c | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-ivcanon.c | 42 |
17 files changed, 202 insertions, 50 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 244208d..a6c85b7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,38 @@ +2013-01-02 Teresa Johnson <tejohnson@google.com> + + * dumpfile.c (dump_loc): Print filename with location. + * tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Use + new location_t parameter to emit complete unroll message with + new dump framework. + (canonicalize_loop_induction_variables): Compute loops location + and pass to try_unroll_loop_completely. + * loop-unroll.c (report_unroll_peel): New function. + (peel_loops_completely): Use new dump format with location + for main dumpfile message, and invoke report_unroll_peel on success. + (decide_unrolling_and_peeling): Ditto. + (decide_peel_once_rolling): Remove old dumpfile message subsumed + by report_unroll_peel. + (decide_peel_completely): Ditto. + (decide_unroll_constant_iterations): Ditto. + (decide_unroll_runtime_iterations): Ditto. + (decide_peel_simple): Ditto. + (decide_unroll_stupid): Ditto. + * cfgloop.c (get_loop_location): New function. + * cfgloop.h (get_loop_location): Declare. + + testsuite/ + * gcc.dg/tree-ssa/loop-1.c: Update expected dump message. + * gcc.dg/tree-ssa/loop-23.c: Ditto. + * gcc.dg/tree-ssa/cunroll-1.c: Ditto. + * gcc.dg/tree-ssa/cunroll-2.c: Ditto. + * gcc.dg/tree-ssa/cunroll-3.c: Ditto. + * gcc.dg/tree-ssa/cunroll-4.c: Ditto. + * gcc.dg/tree-ssa/cunroll-5.c: Ditto. + * gcc.dg/unroll_1.c: Ditto. + * gcc.dg/unroll_2.c: Ditto. + * gcc.dg/unroll_3.c: Ditto. + * gcc.dg/unroll_4.c: Ditto. + 2013-01-02 Sriraman Tallam <tmsriram@google.com> * config/i386/i386.c (fold_builtin_cpu): Remove unnecessary checks for diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c index b45493a..c15e649 100644 --- a/gcc/cfgloop.c +++ b/gcc/cfgloop.c @@ -1666,3 +1666,55 @@ loop_exits_from_bb_p (struct loop *loop, basic_block bb) return false; } + +/* Return location corresponding to the loop control condition if possible. */ + +location_t +get_loop_location (struct loop *loop) +{ + rtx insn = NULL; + struct niter_desc *desc = NULL; + edge exit; + + /* For a for or while loop, we would like to return the location + of the for or while statement, if possible. To do this, look + for the branch guarding the loop back-edge. */ + + /* If this is a simple loop with an in_edge, then the loop control + branch is typically at the end of its source. */ + desc = get_simple_loop_desc (loop); + if (desc->in_edge) + { + FOR_BB_INSNS_REVERSE (desc->in_edge->src, insn) + { + if (INSN_P (insn) && INSN_HAS_LOCATION (insn)) + return INSN_LOCATION (insn); + } + } + /* If loop has a single exit, then the loop control branch + must be at the end of its source. */ + if ((exit = single_exit (loop))) + { + FOR_BB_INSNS_REVERSE (exit->src, insn) + { + if (INSN_P (insn) && INSN_HAS_LOCATION (insn)) + return INSN_LOCATION (insn); + } + } + /* Next check the latch, to see if it is non-empty. */ + FOR_BB_INSNS_REVERSE (loop->latch, insn) + { + if (INSN_P (insn) && INSN_HAS_LOCATION (insn)) + return INSN_LOCATION (insn); + } + /* Finally, if none of the above identifies the loop control branch, + return the first location in the loop header. */ + FOR_BB_INSNS (loop->header, insn) + { + if (INSN_P (insn) && INSN_HAS_LOCATION (insn)) + return INSN_LOCATION (insn); + } + /* If all else fails, simply return the current function location. */ + return DECL_SOURCE_LOCATION (current_function_decl); +} + diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index 9e2e02d..81e70d8 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -239,6 +239,7 @@ extern bool loop_exit_edge_p (const struct loop *, const_edge); extern bool loop_exits_to_bb_p (struct loop *, basic_block); extern bool loop_exits_from_bb_p (struct loop *, basic_block); extern void mark_loop_exit_edges (void); +extern location_t get_loop_location (struct loop *loop); /* Loops & cfg manipulation. */ extern basic_block *get_loop_body (const struct loop *); diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c index 2887a57..7e1d6d7 100644 --- a/gcc/dumpfile.c +++ b/gcc/dumpfile.c @@ -265,7 +265,9 @@ dump_loc (int dump_kind, FILE *dfile, source_location loc) DECL_SOURCE_FILE (current_function_decl), DECL_SOURCE_LINE (current_function_decl)); else - fprintf (dfile, "\n%d: ", LOCATION_LINE (loc)); + fprintf (dfile, "\n%s:%d: note: ", + LOCATION_FILE (loc), + LOCATION_LINE (loc)); } } diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c index de319c4..39a7b80 100644 --- a/gcc/loop-unroll.c +++ b/gcc/loop-unroll.c @@ -148,6 +148,61 @@ static void combine_var_copies_in_loop_exit (struct var_to_expand *, basic_block); static rtx get_expansion (struct var_to_expand *); +/* Emit a message summarizing the unroll or peel that will be + performed for LOOP, along with the loop's location LOCUS, if + appropriate given the dump or -fopt-info settings. */ + +static void +report_unroll_peel (struct loop *loop, location_t locus) +{ + struct niter_desc *desc; + int niters = 0; + int report_flags = MSG_OPTIMIZED_LOCATIONS | TDF_RTL | TDF_DETAILS; + + if (!dump_enabled_p ()) + return; + + /* In the special case where the loop never iterated, emit + a different message so that we don't report an unroll by 0. + This matches the equivalent message emitted during tree unrolling. */ + if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY + && !loop->lpt_decision.times) + { + dump_printf_loc (report_flags, locus, + "Turned loop into non-loop; it never loops.\n"); + return; + } + + desc = get_simple_loop_desc (loop); + + if (desc->const_iter) + niters = desc->niter; + else if (loop->header->count) + niters = expected_loop_iterations (loop); + + dump_printf_loc (report_flags, locus, + "%s loop %d times", + (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY + ? "Completely unroll" + : (loop->lpt_decision.decision == LPT_PEEL_SIMPLE + ? "Peel" : "Unroll")), + loop->lpt_decision.times); + if (profile_info) + dump_printf (report_flags, + " (header execution count %d", + (int)loop->header->count); + if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY) + dump_printf (report_flags, + "%s%s iterations %d)", + profile_info ? ", " : " (", + desc->const_iter ? "const" : "average", + niters); + else if (profile_info) + dump_printf (report_flags, ")"); + + dump_printf (report_flags, "\n"); +} + /* Unroll and/or peel (depending on FLAGS) LOOPS. */ void unroll_and_peel_loops (int flags) @@ -234,11 +289,13 @@ peel_loops_completely (int flags) FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST) { loop->lpt_decision.decision = LPT_NONE; + location_t locus = get_loop_location (loop); - if (dump_file) - fprintf (dump_file, - "\n;; *** Considering loop %d for complete peeling ***\n", - loop->num); + if (dump_enabled_p ()) + dump_printf_loc (TDF_RTL, locus, + ";; *** Considering loop %d at BB %d for " + "complete peeling ***\n", + loop->num, loop->header->index); loop->ninsns = num_loop_insns (loop); @@ -248,6 +305,7 @@ peel_loops_completely (int flags) if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY) { + report_unroll_peel (loop, locus); peel_loop_completely (loop); #ifdef ENABLE_CHECKING verify_loop_structure (); @@ -267,9 +325,13 @@ decide_unrolling_and_peeling (int flags) FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST) { loop->lpt_decision.decision = LPT_NONE; + location_t locus = get_loop_location (loop); - if (dump_file) - fprintf (dump_file, "\n;; *** Considering loop %d ***\n", loop->num); + if (dump_enabled_p ()) + dump_printf_loc (TDF_RTL, locus, + ";; *** Considering loop %d at BB %d for " + "unrolling and peeling ***\n", + loop->num, loop->header->index); /* Do not peel cold areas. */ if (optimize_loop_for_size_p (loop)) @@ -309,6 +371,8 @@ decide_unrolling_and_peeling (int flags) decide_unroll_stupid (loop, flags); if (loop->lpt_decision.decision == LPT_NONE) decide_peel_simple (loop, flags); + + report_unroll_peel (loop, locus); } } @@ -348,8 +412,6 @@ decide_peel_once_rolling (struct loop *loop, int flags ATTRIBUTE_UNUSED) } /* Success. */ - if (dump_file) - fprintf (dump_file, ";; Decided to peel exactly once rolling loop\n"); loop->lpt_decision.decision = LPT_PEEL_COMPLETELY; } @@ -429,8 +491,6 @@ decide_peel_completely (struct loop *loop, int flags ATTRIBUTE_UNUSED) } /* Success. */ - if (dump_file) - fprintf (dump_file, ";; Decided to peel loop completely\n"); loop->lpt_decision.decision = LPT_PEEL_COMPLETELY; } @@ -608,10 +668,6 @@ decide_unroll_constant_iterations (struct loop *loop, int flags) loop->lpt_decision.decision = LPT_UNROLL_CONSTANT; loop->lpt_decision.times = best_unroll; - - if (dump_file) - fprintf (dump_file, ";; Decided to unroll the loop %d times (%d copies).\n", - loop->lpt_decision.times, best_copies); } /* Unroll LOOP with constant number of iterations LOOP->LPT_DECISION.TIMES times. @@ -893,10 +949,6 @@ decide_unroll_runtime_iterations (struct loop *loop, int flags) loop->lpt_decision.decision = LPT_UNROLL_RUNTIME; loop->lpt_decision.times = i - 1; - - if (dump_file) - fprintf (dump_file, ";; Decided to unroll the loop %d times.\n", - loop->lpt_decision.times); } /* Splits edge E and inserts the sequence of instructions INSNS on it, and @@ -1305,10 +1357,6 @@ decide_peel_simple (struct loop *loop, int flags) /* Success. */ loop->lpt_decision.decision = LPT_PEEL_SIMPLE; loop->lpt_decision.times = npeel; - - if (dump_file) - fprintf (dump_file, ";; Decided to simply peel the loop %d times.\n", - loop->lpt_decision.times); } /* Peel a LOOP LOOP->LPT_DECISION.TIMES times. The transformation does this: @@ -1460,10 +1508,6 @@ decide_unroll_stupid (struct loop *loop, int flags) loop->lpt_decision.decision = LPT_UNROLL_STUPID; loop->lpt_decision.times = i - 1; - - if (dump_file) - fprintf (dump_file, ";; Decided to unroll the loop stupidly %d times.\n", - loop->lpt_decision.times); } /* Unroll a LOOP LOOP->LPT_DECISION.TIMES times. The transformation does this: diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c index 523250d..6220640 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c @@ -8,6 +8,6 @@ test(int c) a[i]=5; } /* Array bounds says the loop will not roll much. */ -/* { dg-final { scan-tree-dump "Unrolled loop 1 completely .duplicated 2 times.." "cunrolli"} } */ +/* { dg-final { scan-tree-dump "Completely unroll loop 2 times" "cunrolli"} } */ /* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "cunrolli"} } */ /* { dg-final { cleanup-tree-dump "cunrolli" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c index 8a54a80..10f6645 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c @@ -12,5 +12,5 @@ test(int c) } } /* We are not able to get rid of the final conditional because the loop has two exits. */ -/* { dg-final { scan-tree-dump "Unrolled loop 1 completely .duplicated 1 times.." "cunroll"} } */ +/* { dg-final { scan-tree-dump "Completely unroll loop 1 times" "cunroll"} } */ /* { dg-final { cleanup-tree-dump "cunroll" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c index b621432..44de960 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c @@ -11,5 +11,5 @@ test(int c) } /* If we start duplicating headers prior curoll, this loop will have 0 iterations. */ -/* { dg-final { scan-tree-dump "Unrolled loop 1 completely .duplicated 1 times.." "cunrolli"} } */ +/* { dg-final { scan-tree-dump "Completely unroll loop 1 times" "cunrolli"} } */ /* { dg-final { cleanup-tree-dump "cunrolli" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c index e42919c..9b70e95 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c @@ -16,6 +16,6 @@ test(int c) /* We should do this as part of cunrolli, but our cost model do not take into account early exit from the last iteration. */ -/* { dg-final { scan-tree-dump "Turned loop 1 to non-loop; it never loops." "ivcanon"} } */ +/* { dg-final { scan-tree-dump "Turned loop into non-loop; it never loops." "ivcanon"} } */ /* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "ivcanon"} } */ /* { dg-final { cleanup-tree-dump "ivcanon" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c index 8d1a14a..f74e6b5 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c @@ -8,7 +8,7 @@ test(int c) a[i]=5; } /* Basic testcase for complette unrolling. */ -/* { dg-final { scan-tree-dump "Unrolled loop 1 completely .duplicated 5 times.." "cunroll"} } */ +/* { dg-final { scan-tree-dump "Completely unroll loop 5 times" "cunroll"} } */ /* { dg-final { scan-tree-dump "Exit condition of peeled iterations was eliminated." "cunroll"} } */ /* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "cunroll"} } */ /* { dg-final { cleanup-tree-dump "cunroll" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c index 35ff0be..81178ae 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c @@ -33,7 +33,7 @@ int xxx(void) /* { dg-final { scan-tree-dump-times "Added canonical iv to loop 1, 4 iterations" 1 "ivcanon"} } */ /* { dg-final { cleanup-tree-dump "ivcanon" } } */ -/* { dg-final { scan-tree-dump-times "Unrolled loop 1 completely" 1 "cunroll"} } */ +/* { dg-final { scan-tree-dump-times "Completely unroll loop 4 times" 1 "cunroll"} } */ /* { dg-final { cleanup-tree-dump "cunroll" } } */ /* { dg-final { scan-tree-dump-times "foo" 5 "optimized"} } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-23.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-23.c index 466d175..4f42491 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-23.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-23.c @@ -24,6 +24,6 @@ int foo(void) return sum; } -/* { dg-final { scan-tree-dump-times "Unrolled loop 1 completely" 1 "cunroll" } } */ +/* { dg-final { scan-tree-dump-times "Completely unroll loop 3 times" 1 "cunroll" } } */ /* { dg-final { cleanup-tree-dump "cunroll" } } */ diff --git a/gcc/testsuite/gcc.dg/unroll_1.c b/gcc/testsuite/gcc.dg/unroll_1.c index 23e241b..5818635 100644 --- a/gcc/testsuite/gcc.dg/unroll_1.c +++ b/gcc/testsuite/gcc.dg/unroll_1.c @@ -28,5 +28,5 @@ int foo2(void) return 1; } -/* { dg-final { scan-rtl-dump-times "Decided to peel loop completely" 2 "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it never loops" 2 "loop2_unroll" } } */ /* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */ diff --git a/gcc/testsuite/gcc.dg/unroll_2.c b/gcc/testsuite/gcc.dg/unroll_2.c index 12912cf..9333bf9 100644 --- a/gcc/testsuite/gcc.dg/unroll_2.c +++ b/gcc/testsuite/gcc.dg/unroll_2.c @@ -28,6 +28,6 @@ int foo2(void) return 1; } -/* { dg-final { scan-rtl-dump-times "Decided to peel loop completely" 1 "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it never loops" 1 "loop2_unroll" } } */ /* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */ /* { dg-excess-errors "extra notes" } */ diff --git a/gcc/testsuite/gcc.dg/unroll_3.c b/gcc/testsuite/gcc.dg/unroll_3.c index d86ed55..673069f 100644 --- a/gcc/testsuite/gcc.dg/unroll_3.c +++ b/gcc/testsuite/gcc.dg/unroll_3.c @@ -28,6 +28,6 @@ int foo2(void) return 1; } -/* { dg-final { scan-rtl-dump-times "Decided to peel loop completely" 1 "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it never loops" 1 "loop2_unroll" } } */ /* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */ /* { dg-excess-errors "extra notes" } */ diff --git a/gcc/testsuite/gcc.dg/unroll_4.c b/gcc/testsuite/gcc.dg/unroll_4.c index 7c70157..d3fedd0 100644 --- a/gcc/testsuite/gcc.dg/unroll_4.c +++ b/gcc/testsuite/gcc.dg/unroll_4.c @@ -28,6 +28,6 @@ int foo2(void) return 1; } -/* { dg-final { scan-rtl-dump-times "Decided to peel loop completely" 1 "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it never loops" 1 "loop2_unroll" } } */ /* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */ /* { dg-excess-errors "extra notes" } */ diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c index eef613c..1a872a32 100644 --- a/gcc/tree-ssa-loop-ivcanon.c +++ b/gcc/tree-ssa-loop-ivcanon.c @@ -639,22 +639,24 @@ unloop_loops (bitmap loop_closed_ssa_invalidated, /* Tries to unroll LOOP completely, i.e. NITER times. UL determines which loops we are allowed to unroll. - EXIT is the exit of the loop that should be eliminated. + EXIT is the exit of the loop that should be eliminated. MAXITER specfy bound on number of iterations, -1 if it is - not known or too large for HOST_WIDE_INT. */ + not known or too large for HOST_WIDE_INT. The location + LOCUS corresponding to the loop is used when emitting + a summary of the unroll to the dump file. */ static bool try_unroll_loop_completely (struct loop *loop, edge exit, tree niter, enum unroll_level ul, - HOST_WIDE_INT maxiter) + HOST_WIDE_INT maxiter, + location_t locus) { unsigned HOST_WIDE_INT n_unroll, ninsns, max_unroll, unr_insns; gimple cond; struct loop_size size; bool n_unroll_found = false; edge edge_to_cancel = NULL; - int num = loop->num; /* See if we proved number of iterations to be low constant. @@ -862,14 +864,25 @@ try_unroll_loop_completely (struct loop *loop, loops_to_unloop.safe_push (loop); loops_to_unloop_nunroll.safe_push (n_unroll); - if (dump_file && (dump_flags & TDF_DETAILS)) + if (dump_enabled_p ()) { if (!n_unroll) - fprintf (dump_file, "Turned loop %d to non-loop; it never loops.\n", - num); + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, locus, + "Turned loop into non-loop; it never loops.\n"); else - fprintf (dump_file, "Unrolled loop %d completely " - "(duplicated %i times).\n", num, (int)n_unroll); + { + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, locus, + "Completely unroll loop %d times", (int)n_unroll); + if (profile_info) + dump_printf (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, + " (header execution count %d)", + (int)loop->header->count); + dump_printf (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, "\n"); + } + } + + if (dump_file && (dump_flags & TDF_DETAILS)) + { if (exit) fprintf (dump_file, "Exit condition of peeled iterations was " "eliminated.\n"); @@ -898,15 +911,17 @@ canonicalize_loop_induction_variables (struct loop *loop, tree niter; HOST_WIDE_INT maxiter; bool modified = false; + location_t locus = UNKNOWN_LOCATION; niter = number_of_latch_executions (loop); + exit = single_exit (loop); if (TREE_CODE (niter) == INTEGER_CST) - exit = single_exit (loop); + locus = gimple_location (last_stmt (exit->src)); else { /* If the loop has more than one exit, try checking all of them for # of iterations determinable through scev. */ - if (!single_exit (loop)) + if (!exit) niter = find_loop_niter (loop, &exit); /* Finally if everything else fails, try brute force evaluation. */ @@ -915,6 +930,9 @@ canonicalize_loop_induction_variables (struct loop *loop, || TREE_CODE (niter) != INTEGER_CST)) niter = find_loop_niter_by_eval (loop, &exit); + if (exit) + locus = gimple_location (last_stmt (exit->src)); + if (TREE_CODE (niter) != INTEGER_CST) exit = NULL; } @@ -949,7 +967,7 @@ canonicalize_loop_induction_variables (struct loop *loop, populates the loop bounds. */ modified |= remove_redundant_iv_tests (loop); - if (try_unroll_loop_completely (loop, exit, niter, ul, maxiter)) + if (try_unroll_loop_completely (loop, exit, niter, ul, maxiter, locus)) return true; if (create_iv |