mirror of git://gcc.gnu.org/git/gcc.git
modulo-sched.c (get_sched_window): Use just one loop for predecessors and one loop for successors.
gcc/ * modulo-sched.c (get_sched_window): Use just one loop for predecessors and one loop for successors. Fix upper bound of memory range. From-SVN: r177555
This commit is contained in:
parent
d855a67e7d
commit
fe43febc8c
|
@ -1,3 +1,8 @@
|
||||||
|
2011-08-08 Richard Sandiford <richard.sandiford@linaro.org>
|
||||||
|
|
||||||
|
* modulo-sched.c (get_sched_window): Use just one loop for predecessors
|
||||||
|
and one loop for successors. Fix upper bound of memory range.
|
||||||
|
|
||||||
2011-08-06 Uros Bizjak <ubizjak@gmail.com>
|
2011-08-06 Uros Bizjak <ubizjak@gmail.com>
|
||||||
|
|
||||||
PR target/50001
|
PR target/50001
|
||||||
|
|
|
@ -1630,9 +1630,11 @@ sms_schedule (void)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_sched_window (partial_schedule_ptr ps, ddg_node_ptr u_node,
|
get_sched_window (partial_schedule_ptr ps, ddg_node_ptr u_node,
|
||||||
sbitmap sched_nodes, int ii, int *start_p, int *step_p, int *end_p)
|
sbitmap sched_nodes, int ii, int *start_p, int *step_p,
|
||||||
|
int *end_p)
|
||||||
{
|
{
|
||||||
int start, step, end;
|
int start, step, end;
|
||||||
|
int early_start, late_start;
|
||||||
ddg_edge_ptr e;
|
ddg_edge_ptr e;
|
||||||
sbitmap psp = sbitmap_alloc (ps->g->num_nodes);
|
sbitmap psp = sbitmap_alloc (ps->g->num_nodes);
|
||||||
sbitmap pss = sbitmap_alloc (ps->g->num_nodes);
|
sbitmap pss = sbitmap_alloc (ps->g->num_nodes);
|
||||||
|
@ -1640,6 +1642,8 @@ get_sched_window (partial_schedule_ptr ps, ddg_node_ptr u_node,
|
||||||
sbitmap u_node_succs = NODE_SUCCESSORS (u_node);
|
sbitmap u_node_succs = NODE_SUCCESSORS (u_node);
|
||||||
int psp_not_empty;
|
int psp_not_empty;
|
||||||
int pss_not_empty;
|
int pss_not_empty;
|
||||||
|
int count_preds;
|
||||||
|
int count_succs;
|
||||||
|
|
||||||
/* 1. compute sched window for u (start, end, step). */
|
/* 1. compute sched window for u (start, end, step). */
|
||||||
sbitmap_zero (psp);
|
sbitmap_zero (psp);
|
||||||
|
@ -1647,214 +1651,121 @@ get_sched_window (partial_schedule_ptr ps, ddg_node_ptr u_node,
|
||||||
psp_not_empty = sbitmap_a_and_b_cg (psp, u_node_preds, sched_nodes);
|
psp_not_empty = sbitmap_a_and_b_cg (psp, u_node_preds, sched_nodes);
|
||||||
pss_not_empty = sbitmap_a_and_b_cg (pss, u_node_succs, sched_nodes);
|
pss_not_empty = sbitmap_a_and_b_cg (pss, u_node_succs, sched_nodes);
|
||||||
|
|
||||||
if (psp_not_empty && !pss_not_empty)
|
/* We first compute a forward range (start <= end), then decide whether
|
||||||
{
|
to reverse it. */
|
||||||
int early_start = INT_MIN;
|
early_start = INT_MIN;
|
||||||
|
late_start = INT_MAX;
|
||||||
|
start = INT_MIN;
|
||||||
|
end = INT_MAX;
|
||||||
|
step = 1;
|
||||||
|
|
||||||
end = INT_MAX;
|
count_preds = 0;
|
||||||
for (e = u_node->in; e != 0; e = e->next_in)
|
count_succs = 0;
|
||||||
{
|
|
||||||
ddg_node_ptr v_node = e->src;
|
|
||||||
|
|
||||||
if (dump_file)
|
/* Calculate early_start and limit end. Both bounds are inclusive. */
|
||||||
{
|
if (psp_not_empty)
|
||||||
fprintf (dump_file, "\nProcessing edge: ");
|
for (e = u_node->in; e != 0; e = e->next_in)
|
||||||
print_ddg_edge (dump_file, e);
|
{
|
||||||
|
ddg_node_ptr v_node = e->src;
|
||||||
|
|
||||||
|
if (dump_file)
|
||||||
|
{
|
||||||
|
fprintf (dump_file, "\nProcessing edge: ");
|
||||||
|
print_ddg_edge (dump_file, e);
|
||||||
|
fprintf (dump_file,
|
||||||
|
"\nScheduling %d (%d) in psp_not_empty,"
|
||||||
|
" checking p %d (%d): ", u_node->cuid,
|
||||||
|
INSN_UID (u_node->insn), v_node->cuid, INSN_UID
|
||||||
|
(v_node->insn));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TEST_BIT (sched_nodes, v_node->cuid))
|
||||||
|
{
|
||||||
|
int p_st = SCHED_TIME (v_node);
|
||||||
|
|
||||||
|
early_start = MAX (early_start,
|
||||||
|
p_st + e->latency - (e->distance * ii));
|
||||||
|
|
||||||
|
if (e->data_type == MEM_DEP)
|
||||||
|
end = MIN (end, p_st + ii - 1);
|
||||||
|
|
||||||
|
if (e->type == TRUE_DEP && e->data_type == REG_DEP)
|
||||||
|
count_preds++;
|
||||||
|
|
||||||
|
if (dump_file)
|
||||||
fprintf (dump_file,
|
fprintf (dump_file,
|
||||||
"\nScheduling %d (%d) in psp_not_empty,"
|
"pred st = %d; early_start = %d; latency: %d;"
|
||||||
" checking p %d (%d): ", u_node->cuid,
|
" end: %d\n", p_st, early_start, e->latency, end);
|
||||||
INSN_UID (u_node->insn), v_node->cuid, INSN_UID
|
|
||||||
(v_node->insn));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TEST_BIT (sched_nodes, v_node->cuid))
|
}
|
||||||
{
|
else if (dump_file)
|
||||||
int p_st = SCHED_TIME (v_node);
|
fprintf (dump_file, "the node is not scheduled\n");
|
||||||
|
}
|
||||||
|
|
||||||
early_start =
|
/* Calculate late_start and limit start. Both bounds are inclusive. */
|
||||||
MAX (early_start, p_st + e->latency - (e->distance * ii));
|
if (pss_not_empty)
|
||||||
|
for (e = u_node->out; e != 0; e = e->next_out)
|
||||||
|
{
|
||||||
|
ddg_node_ptr v_node = e->dest;
|
||||||
|
|
||||||
if (dump_file)
|
if (dump_file)
|
||||||
fprintf (dump_file,
|
{
|
||||||
"pred st = %d; early_start = %d; latency: %d",
|
fprintf (dump_file, "\nProcessing edge:");
|
||||||
p_st, early_start, e->latency);
|
print_ddg_edge (dump_file, e);
|
||||||
|
fprintf (dump_file,
|
||||||
|
"\nScheduling %d (%d) in pss_not_empty,"
|
||||||
|
" checking s %d (%d): ", u_node->cuid,
|
||||||
|
INSN_UID (u_node->insn), v_node->cuid, INSN_UID
|
||||||
|
(v_node->insn));
|
||||||
|
}
|
||||||
|
|
||||||
if (e->data_type == MEM_DEP)
|
if (TEST_BIT (sched_nodes, v_node->cuid))
|
||||||
end = MIN (end, SCHED_TIME (v_node) + ii - 1);
|
{
|
||||||
}
|
int s_st = SCHED_TIME (v_node);
|
||||||
else if (dump_file)
|
|
||||||
fprintf (dump_file, "the node is not scheduled\n");
|
|
||||||
}
|
|
||||||
start = early_start;
|
|
||||||
end = MIN (end, early_start + ii);
|
|
||||||
/* Schedule the node close to it's predecessors. */
|
|
||||||
step = 1;
|
|
||||||
|
|
||||||
if (dump_file)
|
late_start = MIN (late_start,
|
||||||
fprintf (dump_file,
|
s_st - e->latency + (e->distance * ii));
|
||||||
"\nScheduling %d (%d) in a window (%d..%d) with step %d\n",
|
|
||||||
u_node->cuid, INSN_UID (u_node->insn), start, end, step);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (!psp_not_empty && pss_not_empty)
|
if (e->data_type == MEM_DEP)
|
||||||
|
start = MAX (start, s_st - ii + 1);
|
||||||
|
|
||||||
|
if (e->type == TRUE_DEP && e->data_type == REG_DEP)
|
||||||
|
count_succs++;
|
||||||
|
|
||||||
|
if (dump_file)
|
||||||
|
fprintf (dump_file,
|
||||||
|
"succ st = %d; late_start = %d; latency = %d;"
|
||||||
|
" start=%d", s_st, late_start, e->latency, start);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (dump_file)
|
||||||
|
fprintf (dump_file, "the node is not scheduled\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a target scheduling window no bigger than ii. */
|
||||||
|
if (early_start == INT_MIN && late_start == INT_MAX)
|
||||||
|
early_start = SCHED_ASAP (u_node);
|
||||||
|
else if (early_start == INT_MIN)
|
||||||
|
early_start = late_start - (ii - 1);
|
||||||
|
late_start = MIN (late_start, early_start + (ii - 1));
|
||||||
|
|
||||||
|
/* Apply memory dependence limits. */
|
||||||
|
start = MAX (start, early_start);
|
||||||
|
end = MIN (end, late_start);
|
||||||
|
|
||||||
|
/* If there are at least as many successors as predecessors, schedule the
|
||||||
|
node close to its successors. */
|
||||||
|
if (pss_not_empty && count_succs >= count_preds)
|
||||||
{
|
{
|
||||||
int late_start = INT_MAX;
|
int tmp = end;
|
||||||
|
end = start;
|
||||||
end = INT_MIN;
|
start = tmp;
|
||||||
for (e = u_node->out; e != 0; e = e->next_out)
|
|
||||||
{
|
|
||||||
ddg_node_ptr v_node = e->dest;
|
|
||||||
|
|
||||||
if (dump_file)
|
|
||||||
{
|
|
||||||
fprintf (dump_file, "\nProcessing edge:");
|
|
||||||
print_ddg_edge (dump_file, e);
|
|
||||||
fprintf (dump_file,
|
|
||||||
"\nScheduling %d (%d) in pss_not_empty,"
|
|
||||||
" checking s %d (%d): ", u_node->cuid,
|
|
||||||
INSN_UID (u_node->insn), v_node->cuid, INSN_UID
|
|
||||||
(v_node->insn));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TEST_BIT (sched_nodes, v_node->cuid))
|
|
||||||
{
|
|
||||||
int s_st = SCHED_TIME (v_node);
|
|
||||||
|
|
||||||
late_start = MIN (late_start,
|
|
||||||
s_st - e->latency + (e->distance * ii));
|
|
||||||
|
|
||||||
if (dump_file)
|
|
||||||
fprintf (dump_file,
|
|
||||||
"succ st = %d; late_start = %d; latency = %d",
|
|
||||||
s_st, late_start, e->latency);
|
|
||||||
|
|
||||||
if (e->data_type == MEM_DEP)
|
|
||||||
end = MAX (end, SCHED_TIME (v_node) - ii + 1);
|
|
||||||
if (dump_file)
|
|
||||||
fprintf (dump_file, "end = %d\n", end);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (dump_file)
|
|
||||||
fprintf (dump_file, "the node is not scheduled\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
start = late_start;
|
|
||||||
end = MAX (end, late_start - ii);
|
|
||||||
/* Schedule the node close to it's successors. */
|
|
||||||
step = -1;
|
step = -1;
|
||||||
|
|
||||||
if (dump_file)
|
|
||||||
fprintf (dump_file,
|
|
||||||
"\nScheduling %d (%d) in a window (%d..%d) with step %d\n",
|
|
||||||
u_node->cuid, INSN_UID (u_node->insn), start, end, step);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (psp_not_empty && pss_not_empty)
|
/* Now that we've finalized the window, make END an exclusive rather
|
||||||
{
|
than an inclusive bound. */
|
||||||
int early_start = INT_MIN;
|
end += step;
|
||||||
int late_start = INT_MAX;
|
|
||||||
int count_preds = 0;
|
|
||||||
int count_succs = 0;
|
|
||||||
|
|
||||||
start = INT_MIN;
|
|
||||||
end = INT_MAX;
|
|
||||||
for (e = u_node->in; e != 0; e = e->next_in)
|
|
||||||
{
|
|
||||||
ddg_node_ptr v_node = e->src;
|
|
||||||
|
|
||||||
if (dump_file)
|
|
||||||
{
|
|
||||||
fprintf (dump_file, "\nProcessing edge:");
|
|
||||||
print_ddg_edge (dump_file, e);
|
|
||||||
fprintf (dump_file,
|
|
||||||
"\nScheduling %d (%d) in psp_pss_not_empty,"
|
|
||||||
" checking p %d (%d): ", u_node->cuid, INSN_UID
|
|
||||||
(u_node->insn), v_node->cuid, INSN_UID
|
|
||||||
(v_node->insn));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TEST_BIT (sched_nodes, v_node->cuid))
|
|
||||||
{
|
|
||||||
int p_st = SCHED_TIME (v_node);
|
|
||||||
|
|
||||||
early_start = MAX (early_start,
|
|
||||||
p_st + e->latency
|
|
||||||
- (e->distance * ii));
|
|
||||||
|
|
||||||
if (dump_file)
|
|
||||||
fprintf (dump_file,
|
|
||||||
"pred st = %d; early_start = %d; latency = %d",
|
|
||||||
p_st, early_start, e->latency);
|
|
||||||
|
|
||||||
if (e->type == TRUE_DEP && e->data_type == REG_DEP)
|
|
||||||
count_preds++;
|
|
||||||
|
|
||||||
if (e->data_type == MEM_DEP)
|
|
||||||
end = MIN (end, SCHED_TIME (v_node) + ii - 1);
|
|
||||||
}
|
|
||||||
else if (dump_file)
|
|
||||||
fprintf (dump_file, "the node is not scheduled\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
for (e = u_node->out; e != 0; e = e->next_out)
|
|
||||||
{
|
|
||||||
ddg_node_ptr v_node = e->dest;
|
|
||||||
|
|
||||||
if (dump_file)
|
|
||||||
{
|
|
||||||
fprintf (dump_file, "\nProcessing edge:");
|
|
||||||
print_ddg_edge (dump_file, e);
|
|
||||||
fprintf (dump_file,
|
|
||||||
"\nScheduling %d (%d) in psp_pss_not_empty,"
|
|
||||||
" checking s %d (%d): ", u_node->cuid, INSN_UID
|
|
||||||
(u_node->insn), v_node->cuid, INSN_UID
|
|
||||||
(v_node->insn));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TEST_BIT (sched_nodes, v_node->cuid))
|
|
||||||
{
|
|
||||||
int s_st = SCHED_TIME (v_node);
|
|
||||||
|
|
||||||
late_start = MIN (late_start,
|
|
||||||
s_st - e->latency
|
|
||||||
+ (e->distance * ii));
|
|
||||||
|
|
||||||
if (dump_file)
|
|
||||||
fprintf (dump_file,
|
|
||||||
"succ st = %d; late_start = %d; latency = %d",
|
|
||||||
s_st, late_start, e->latency);
|
|
||||||
|
|
||||||
if (e->type == TRUE_DEP && e->data_type == REG_DEP)
|
|
||||||
count_succs++;
|
|
||||||
|
|
||||||
if (e->data_type == MEM_DEP)
|
|
||||||
start = MAX (start, SCHED_TIME (v_node) - ii + 1);
|
|
||||||
}
|
|
||||||
else if (dump_file)
|
|
||||||
fprintf (dump_file, "the node is not scheduled\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
start = MAX (start, early_start);
|
|
||||||
end = MIN (end, MIN (early_start + ii, late_start + 1));
|
|
||||||
step = 1;
|
|
||||||
/* If there are more successors than predecessors schedule the
|
|
||||||
node close to it's successors. */
|
|
||||||
if (count_succs >= count_preds)
|
|
||||||
{
|
|
||||||
int old_start = start;
|
|
||||||
|
|
||||||
start = end - 1;
|
|
||||||
end = old_start - 1;
|
|
||||||
step = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else /* psp is empty && pss is empty. */
|
|
||||||
{
|
|
||||||
start = SCHED_ASAP (u_node);
|
|
||||||
end = start + ii;
|
|
||||||
step = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*start_p = start;
|
*start_p = start;
|
||||||
*step_p = step;
|
*step_p = step;
|
||||||
|
@ -1867,10 +1778,10 @@ get_sched_window (partial_schedule_ptr ps, ddg_node_ptr u_node,
|
||||||
if (dump_file)
|
if (dump_file)
|
||||||
fprintf (dump_file, "\nEmpty window: start=%d, end=%d, step=%d\n",
|
fprintf (dump_file, "\nEmpty window: start=%d, end=%d, step=%d\n",
|
||||||
start, end, step);
|
start, end, step);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate MUST_PRECEDE/MUST_FOLLOW bitmaps of U_NODE; which is the
|
/* Calculate MUST_PRECEDE/MUST_FOLLOW bitmaps of U_NODE; which is the
|
||||||
|
|
Loading…
Reference in New Issue