summaryrefslogtreecommitdiff
path: root/gcc/loop-unroll.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/loop-unroll.c')
-rw-r--r--gcc/loop-unroll.c96
1 files changed, 70 insertions, 26 deletions
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
index de319c4f1d7..39a7b80bdb3 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: