mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-13 14:51:18 +08:00
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
This commit is contained in:
parent
7787862173
commit
e25a671164
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 *);
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } */
|
||||
|
@ -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" } */
|
||||
|
@ -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" } */
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user