/* Swing Modulo Scheduling implementation.
- Copyright (C) 2004, 2005, 2006
+ Copyright (C) 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
Contributed by Ayal Zaks and Mustafa Hagog <zaks,mustafa@il.ibm.com>
/* Put the prolog on the entry edge. */
e = loop_preheader_edge (loop);
- split_edge_and_insert (e, get_insns());
+ split_edge_and_insert (e, get_insns ());
end_sequence ();
/* Put the epilogue on the exit edge. */
gcc_assert (single_exit (loop));
e = single_exit (loop);
- split_edge_and_insert (e, get_insns());
+ split_edge_and_insert (e, get_insns ());
end_sequence ();
}
{
if (dump_file)
{
+ rtx insn = BB_END (loop->header);
+
fprintf (dump_file, "SMS loop many exits ");
+ fprintf (dump_file, " %s %d (file, line)\n",
+ insn_file (insn), insn_line (insn));
}
return false;
}
{
if (dump_file)
{
+ rtx insn = BB_END (loop->header);
+
fprintf (dump_file, "SMS loop many BBs. ");
+ fprintf (dump_file, " %s %d (file, line)\n",
+ insn_file (insn), insn_line (insn));
}
return false;
}
}
}
+/* Probability in % that the sms-ed loop rolls enough so that optimized
+ version may be entered. Just a guess. */
+#define PROB_SMS_ENOUGH_ITERATIONS 80
+
/* Main entry point, perform SMS scheduling on the loops of the function
that consist of single basic blocks. */
static void
ddg_ptr *g_arr, g;
int * node_order;
int maxii;
- unsigned i,num_loops;
+ loop_iterator li;
partial_schedule_ptr ps;
struct df *df;
basic_block bb = NULL;
- /* vars to the versioning only if needed*/
- struct loop * nloop;
+ struct loop *loop;
basic_block condition_bb = NULL;
edge latch_edge;
gcov_type trip_count = 0;
loop_optimizer_init (LOOPS_HAVE_PREHEADERS
- | LOOPS_HAVE_MARKED_SINGLE_EXITS);
+ | LOOPS_HAVE_RECORDED_EXITS);
if (!current_loops)
return; /* There are no loops to schedule. */
/* Allocate memory to hold the DDG array one entry for each loop.
We use loop->num as index into this array. */
- g_arr = XCNEWVEC (ddg_ptr, current_loops->num);
-
+ g_arr = XCNEWVEC (ddg_ptr, number_of_loops ());
/* Build DDGs for all the relevant loops and hold them in G_ARR
indexed by the loop index. */
- for (i = 0; i < current_loops->num; i++)
+ FOR_EACH_LOOP (li, loop, 0)
{
rtx head, tail;
rtx count_reg;
- struct loop *loop = current_loops->parray[i];
/* For debugging. */
if ((passes++ > MAX_SMS_LOOP_NUMBER) && (MAX_SMS_LOOP_NUMBER != -1))
{
if (dump_file)
{
+ fprintf (dump_file, " %s %d (file, line)\n",
+ insn_file (tail), insn_line (tail));
fprintf (dump_file, "SMS single-bb-loop\n");
if (profile_info && flag_branch_probabilities)
{
continue;
}
- g_arr[i] = g;
+ g_arr[loop->num] = g;
}
/* Release Data Flow analysis data structures. */
df = NULL;
/* We don't want to perform SMS on new loops - created by versioning. */
- num_loops = current_loops->num;
- /* Go over the built DDGs and perfrom SMS for each one of them. */
- for (i = 0; i < num_loops; i++)
+ FOR_EACH_LOOP (li, loop, 0)
{
rtx head, tail;
rtx count_reg, count_init;
int mii, rec_mii;
unsigned stage_count = 0;
HOST_WIDEST_INT loop_count = 0;
- struct loop *loop = current_loops->parray[i];
- if (! (g = g_arr[i]))
+ if (! (g = g_arr[loop->num]))
continue;
if (dump_file)
if (dump_file)
{
+ fprintf (dump_file, " %s %d (file, line)\n",
+ insn_file (tail), insn_line (tail));
fprintf (dump_file, "SMS single-bb-loop\n");
if (profile_info && flag_branch_probabilities)
{
{
rtx comp_rtx = gen_rtx_fmt_ee (GT, VOIDmode, count_reg,
GEN_INT(stage_count));
+ unsigned prob = (PROB_SMS_ENOUGH_ITERATIONS
+ * REG_BR_PROB_BASE) / 100;
- nloop = loop_version (loop, comp_rtx, &condition_bb, true);
+ loop_version (loop, comp_rtx, &condition_bb,
+ prob, prob, REG_BR_PROB_BASE - prob,
+ true);
}
/* Set new iteration count of loop kernel. */
bool unscheduled_nodes = false;
if (dump_file)
- fprintf(dump_file, "Starting with ii=%d\n", ii);
+ fprintf (dump_file, "Starting with ii=%d\n", ii);
if (try_again_with_larger_ii)
{
try_again_with_larger_ii = false;
}
/* 2. Try scheduling u in window. */
if (dump_file)
- fprintf(dump_file, "Trying to schedule node %d in (%d .. %d) step %d\n",
- u, start, end, step);
+ fprintf (dump_file,
+ "Trying to schedule node %d in (%d .. %d) step %d\n",
+ u, start, end, step);
/* use must_follow & must_precede bitmaps to determine order
of nodes within the cycle. */
SET_BIT (sched_nodes, u);
success = 1;
if (dump_file)
- fprintf(dump_file, "Schedule in %d\n", c);
+ fprintf (dump_file, "Schedule in %d\n", c);
break;
}
}