Index: gcc/gcc/modulo-sched.c |
diff --git a/gcc/gcc/modulo-sched.c b/gcc/gcc/modulo-sched.c |
index 7134bfc0d00c5fe658769b0cdacfc9a4b6df7b4c..cc9f788a8a7b94227369550ee2108c3d47736b5b 100644 |
--- a/gcc/gcc/modulo-sched.c |
+++ b/gcc/gcc/modulo-sched.c |
@@ -96,7 +96,7 @@ along with GCC; see the file COPYING3. If not see |
Currently SMS relies on the do-loop pattern to recognize such loops, |
where (1) the control part comprises of all insns defining and/or |
using a certain 'count' register and (2) the loop count can be |
- adjusted by modifying this register prior to the loop. |
+ adjusted by modifying this register prior to the loop. |
TODO: Rely on cfgloop analysis instead. */ |
/* This page defines partial-schedule structures and functions for |
@@ -168,7 +168,7 @@ struct undo_replace_buff_elem |
}; |
- |
+ |
static partial_schedule_ptr create_partial_schedule (int ii, ddg_ptr, int history); |
static void free_partial_schedule (partial_schedule_ptr); |
static void reset_partial_schedule (partial_schedule_ptr, int new_ii); |
@@ -270,11 +270,12 @@ static struct haifa_sched_info sms_sched_info = |
NULL, |
sms_print_insn, |
NULL, |
+ NULL, /* insn_finishes_block_p */ |
NULL, NULL, |
NULL, NULL, |
0, 0, |
- NULL, NULL, NULL, |
+ NULL, NULL, NULL, |
0 |
}; |
@@ -348,12 +349,12 @@ const_iteration_count (rtx count_reg, basic_block pre_header, |
get_ebb_head_tail (pre_header, pre_header, &head, &tail); |
for (insn = tail; insn != PREV_INSN (head); insn = PREV_INSN (insn)) |
- if (INSN_P (insn) && single_set (insn) && |
+ if (NONDEBUG_INSN_P (insn) && single_set (insn) && |
rtx_equal_p (count_reg, SET_DEST (single_set (insn)))) |
{ |
rtx pat = single_set (insn); |
- if (GET_CODE (SET_SRC (pat)) == CONST_INT) |
+ if (CONST_INT_P (SET_SRC (pat))) |
{ |
*count = INTVAL (SET_SRC (pat)); |
return insn; |
@@ -372,9 +373,9 @@ static int |
res_MII (ddg_ptr g) |
{ |
if (targetm.sched.sms_res_mii) |
- return targetm.sched.sms_res_mii (g); |
- |
- return (g->num_nodes / issue_rate); |
+ return targetm.sched.sms_res_mii (g); |
+ |
+ return ((g->num_nodes - g->num_debug) / issue_rate); |
} |
@@ -704,7 +705,7 @@ generate_prolog_epilog (partial_schedule_ptr ps, struct loop *loop, |
int i; |
int last_stage = PS_STAGE_COUNT (ps) - 1; |
edge e; |
- |
+ |
/* Generate the prolog, inserting its insns on the loop-entry edge. */ |
start_sequence (); |
@@ -726,7 +727,7 @@ generate_prolog_epilog (partial_schedule_ptr ps, struct loop *loop, |
for (i = 0; i < last_stage; i++) |
duplicate_insns_of_cycles (ps, 0, i, 1, count_reg); |
- |
+ |
/* Put the prolog on the entry edge. */ |
e = loop_preheader_edge (loop); |
split_edge_and_insert (e, get_insns ()); |
@@ -738,7 +739,7 @@ generate_prolog_epilog (partial_schedule_ptr ps, struct loop *loop, |
for (i = 0; i < last_stage; i++) |
duplicate_insns_of_cycles (ps, i + 1, last_stage, 0, count_reg); |
- |
+ |
/* Put the epilogue on the exit edge. */ |
gcc_assert (single_exit (loop)); |
e = single_exit (loop); |
@@ -768,7 +769,7 @@ loop_single_full_bb_p (struct loop *loop) |
for (; head != NEXT_INSN (tail); head = NEXT_INSN (head)) |
{ |
if (NOTE_P (head) || LABEL_P (head) |
- || (INSN_P (head) && JUMP_P (head))) |
+ || (INSN_P (head) && (DEBUG_INSN_P (head) || JUMP_P (head)))) |
continue; |
empty_bb = false; |
break; |
@@ -808,7 +809,7 @@ loop_canon_p (struct loop *loop) |
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)); |
@@ -821,7 +822,7 @@ loop_canon_p (struct loop *loop) |
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)); |
@@ -1010,7 +1011,7 @@ sms_schedule (void) |
/* Don't handle BBs with calls or barriers, or !single_set insns, |
or auto-increment insns (to avoid creating invalid reg-moves |
- for the auto-increment insns). |
+ for the auto-increment insns). |
??? Should handle auto-increment insns. |
??? Should handle insns defining subregs. */ |
for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn)) |
@@ -1019,7 +1020,7 @@ sms_schedule (void) |
if (CALL_P (insn) |
|| BARRIER_P (insn) |
- || (INSN_P (insn) && !JUMP_P (insn) |
+ || (NONDEBUG_INSN_P (insn) && !JUMP_P (insn) |
&& !single_set (insn) && GET_CODE (PATTERN (insn)) != USE) |
|| (FIND_REG_INC_NOTE (insn, NULL_RTX) != 0) |
|| (INSN_P (insn) && (set = single_set (insn)) |
@@ -1037,7 +1038,7 @@ sms_schedule (void) |
fprintf (dump_file, "SMS loop-with-barrier\n"); |
else if (FIND_REG_INC_NOTE (insn, NULL_RTX) != 0) |
fprintf (dump_file, "SMS reg inc\n"); |
- else if ((INSN_P (insn) && !JUMP_P (insn) |
+ else if ((NONDEBUG_INSN_P (insn) && !JUMP_P (insn) |
&& !single_set (insn) && GET_CODE (PATTERN (insn)) != USE)) |
fprintf (dump_file, "SMS loop-with-not-single-set\n"); |
else |
@@ -1156,12 +1157,14 @@ sms_schedule (void) |
ps = sms_schedule_by_order (g, mii, maxii, node_order); |
- if (ps) |
+ if (ps){ |
stage_count = PS_STAGE_COUNT (ps); |
+ gcc_assert(stage_count >= 1); |
+ } |
/* Stage count of 1 means that there is no interleaving between |
iterations, let the scheduling passes do the job. */ |
- if (stage_count < 1 |
+ if (stage_count <= 1 |
|| (count_init && (loop_count <= stage_count)) |
|| (flag_branch_probabilities && (trip_count <= stage_count))) |
{ |
@@ -1195,14 +1198,14 @@ sms_schedule (void) |
the closing_branch was scheduled and should appear in the last (ii-1) |
row. Otherwise, we are free to schedule the branch, and we let nodes |
that were scheduled at the first PS_MIN_CYCLE cycle appear in the first |
- row; this should reduce stage_count to minimum. |
+ row; this should reduce stage_count to minimum. |
TODO: Revisit the issue of scheduling the insns of the |
control part relative to the branch when the control part |
has more than one insn. */ |
normalize_sched_times (ps); |
rotate_partial_schedule (ps, PS_MIN_CYCLE (ps)); |
set_columns_for_ps (ps); |
- |
+ |
canon_loop (loop); |
/* case the BCT count is not known , Do loop-versioning */ |
@@ -1238,7 +1241,7 @@ sms_schedule (void) |
print_node_sched_params (dump_file, g->num_nodes, g); |
/* Generate prolog and epilog. */ |
generate_prolog_epilog (ps, loop, count_reg, count_init); |
- |
+ |
free_undo_replace_buff (reg_move_replaces); |
} |
@@ -1374,7 +1377,7 @@ get_sched_window (partial_schedule_ptr ps, int *nodes_order, int i, |
ddg_node_ptr v_node = e->src; |
if (dump_file) |
- { |
+ { |
fprintf (dump_file, "\nProcessing edge: "); |
print_ddg_edge (dump_file, e); |
fprintf (dump_file, |
@@ -1392,7 +1395,7 @@ get_sched_window (partial_schedule_ptr ps, int *nodes_order, int i, |
MAX (early_start, p_st + e->latency - (e->distance * ii)); |
if (dump_file) |
- fprintf (dump_file, |
+ fprintf (dump_file, |
"pred st = %d; early_start = %d; latency: %d", |
p_st, early_start, e->latency); |
@@ -1441,7 +1444,7 @@ get_sched_window (partial_schedule_ptr ps, int *nodes_order, int i, |
s_st - e->latency + (e->distance * ii)); |
if (dump_file) |
- fprintf (dump_file, |
+ fprintf (dump_file, |
"succ st = %d; late_start = %d; latency = %d", |
s_st, late_start, e->latency); |
@@ -1500,7 +1503,7 @@ get_sched_window (partial_schedule_ptr ps, int *nodes_order, int i, |
- (e->distance * ii)); |
if (dump_file) |
- fprintf (dump_file, |
+ fprintf (dump_file, |
"pred st = %d; early_start = %d; latency = %d", |
p_st, early_start, e->latency); |
@@ -1538,7 +1541,7 @@ get_sched_window (partial_schedule_ptr ps, int *nodes_order, int i, |
+ (e->distance * ii)); |
if (dump_file) |
- fprintf (dump_file, |
+ fprintf (dump_file, |
"succ st = %d; late_start = %d; latency = %d", |
s_st, late_start, e->latency); |
@@ -1662,7 +1665,7 @@ calculate_must_precede_follow (ddg_node_ptr u_node, int start, int end, |
&& e->latency == 0 |
we use the fact that latency is non-negative: |
SCHED_TIME (e->dest) + (e->distance * ii) >= |
- SCHED_TIME (e->dest) - e->latency + (e->distance * ii)) >= |
+ SCHED_TIME (e->dest) - e->latency + (e->distance * ii)) >= |
last_cycle_in_window |
and check only if |
SCHED_TIME (e->dest) + (e->distance * ii) == last_cycle_in_window */ |
@@ -1751,7 +1754,7 @@ sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order) |
ddg_node_ptr u_node = &ps->g->nodes[u]; |
rtx insn = u_node->insn; |
- if (!INSN_P (insn)) |
+ if (!NONDEBUG_INSN_P (insn)) |
{ |
RESET_BIT (tobe_scheduled, u); |
continue; |
@@ -1832,11 +1835,14 @@ sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order) |
} |
num_splits++; |
+ /* The scheduling window is exclusive of 'end' |
+ whereas compute_split_window() expects an inclusive, |
+ ordered range. */ |
if (step == 1) |
- split_row = compute_split_row (sched_nodes, start, end, |
+ split_row = compute_split_row (sched_nodes, start, end - 1, |
ps->ii, u_node); |
else |
- split_row = compute_split_row (sched_nodes, end, start, |
+ split_row = compute_split_row (sched_nodes, end + 1, start, |
ps->ii, u_node); |
ps_insert_empty_row (ps, split_row, sched_nodes); |
@@ -2074,10 +2080,10 @@ check_nodes_order (int *node_order, int num_nodes) |
SET_BIT (tmp, u); |
} |
- |
+ |
if (dump_file) |
fprintf (dump_file, "\n"); |
- |
+ |
sbitmap_free (tmp); |
} |
@@ -2616,8 +2622,8 @@ ps_insn_find_column (partial_schedule_ptr ps, ps_insn_ptr ps_i, |
} |
/* Advances the PS_INSN one column in its current row; returns false |
- in failure and true in success. Bit N is set in MUST_FOLLOW if |
- the node with cuid N must be come after the node pointed to by |
+ in failure and true in success. Bit N is set in MUST_FOLLOW if |
+ the node with cuid N must be come after the node pointed to by |
PS_I when scheduled in the same cycle. */ |
static int |
ps_insn_advance_column (partial_schedule_ptr ps, ps_insn_ptr ps_i, |
@@ -2665,9 +2671,9 @@ ps_insn_advance_column (partial_schedule_ptr ps, ps_insn_ptr ps_i, |
} |
/* Inserts a DDG_NODE to the given partial schedule at the given cycle. |
- Returns 0 if this is not possible and a PS_INSN otherwise. Bit N is |
- set in MUST_PRECEDE/MUST_FOLLOW if the node with cuid N must be come |
- before/after (respectively) the node pointed to by PS_I when scheduled |
+ Returns 0 if this is not possible and a PS_INSN otherwise. Bit N is |
+ set in MUST_PRECEDE/MUST_FOLLOW if the node with cuid N must be come |
+ before/after (respectively) the node pointed to by PS_I when scheduled |
in the same cycle. */ |
static ps_insn_ptr |
add_node_to_ps (partial_schedule_ptr ps, ddg_node_ptr node, int cycle, |
@@ -2737,7 +2743,7 @@ ps_has_conflicts (partial_schedule_ptr ps, int from, int to) |
{ |
rtx insn = crr_insn->node->insn; |
- if (!INSN_P (insn)) |
+ if (!NONDEBUG_INSN_P (insn)) |
continue; |
/* Check if there is room for the current insn. */ |
@@ -2768,8 +2774,8 @@ ps_has_conflicts (partial_schedule_ptr ps, int from, int to) |
/* Checks if the given node causes resource conflicts when added to PS at |
cycle C. If not the node is added to PS and returned; otherwise zero |
- is returned. Bit N is set in MUST_PRECEDE/MUST_FOLLOW if the node with |
- cuid N must be come before/after (respectively) the node pointed to by |
+ is returned. Bit N is set in MUST_PRECEDE/MUST_FOLLOW if the node with |
+ cuid N must be come before/after (respectively) the node pointed to by |
PS_I when scheduled in the same cycle. */ |
ps_insn_ptr |
ps_add_node_check_conflicts (partial_schedule_ptr ps, ddg_node_ptr n, |