Commit d72372e4 by Mostafa Hagog Committed by Mostafa Hagog

common.opt (freschedule-modulo-scheduled-loops): New flag.

2004-08-08  Mostafa Hagog  <mustafa@il.ibm.com>
	Ayal Zaks <zaks@il.ibm.com>

	* common.opt (freschedule-modulo-scheduled-loops): New flag.
	* final.c (final_scan_insn): Handle NOTE_DISABLE_SCHED_OF_BLOCK.
	* modulo-sched.c (sms_schedule): Emit a note to disable scheduling
	when -freschedule-modulo-scheduled-loops flag is not specified.
	(sms_schedule_by_order, ps_insn_advance_column, add_node_to_ps,
	add_node_to_ps, ps_has_conflicts, ps_add_node_check_conflicts):
	More accurate placing of insn in row of partial schedule.
	(ps_insn_find_column): New function.
	* rtl.h (NOTE_DISABLE_SCHED_OF_BLOCK): New note.
	* sched-rgn.c (sched_is_disabled_for_current_region_p): New.
	(schedule_region): Use sched_is_disabled_for_current_region_p.
	* docs/invoke.texi: Document -freschedule-modulo-scheduled-loops.

Co-Authored-By: Ayal Zaks <zaks@il.ibm.com>

From-SVN: r85696
parent 94538bd1
2004-08-08 Mostafa Hagog <mustafa@il.ibm.com>
Ayal Zaks <zaks@il.ibm.com>
* common.opt (freschedule-modulo-scheduled-loops): New flag.
* final.c (final_scan_insn): Handle NOTE_DISABLE_SCHED_OF_BLOCK.
* modulo-sched.c (sms_schedule): Emit a note to disable scheduling
when -freschedule-modulo-scheduled-loops flag is not specified.
(sms_schedule_by_order, ps_insn_advance_column, add_node_to_ps,
add_node_to_ps, ps_has_conflicts, ps_add_node_check_conflicts):
More accurate placing of insn in row of partial schedule.
(ps_insn_find_column): New function.
* rtl.h (NOTE_DISABLE_SCHED_OF_BLOCK): New note.
* sched-rgn.c (sched_is_disabled_for_current_region_p): New.
(schedule_region): Use sched_is_disabled_for_current_region_p.
* docs/invoke.texi: Document -freschedule-modulo-scheduled-loops.
2004-08-07 H.J. Lu <hongjiu.lu@intel.com> 2004-08-07 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.c (ix86_expand_clrmem): Revert the last * config/i386/i386.c (ix86_expand_clrmem): Revert the last
......
...@@ -543,6 +543,10 @@ fnew-ra ...@@ -543,6 +543,10 @@ fnew-ra
Common Report Var(flag_new_regalloc) Common Report Var(flag_new_regalloc)
Use graph-coloring register allocation Use graph-coloring register allocation
freschedule-modulo-scheduled-loops
Common Report Var(flag_resched_modulo_sched)
Enable/Disable the traditional scheduling in loops that already passed modulo scheduling
fnon-call-exceptions fnon-call-exceptions
Common Report Var(flag_non_call_exceptions) Common Report Var(flag_non_call_exceptions)
Support synchronous non-call exceptions Support synchronous non-call exceptions
......
...@@ -308,8 +308,8 @@ in the following sections. ...@@ -308,8 +308,8 @@ in the following sections.
-fsched-spec-load-dangerous @gol -fsched-spec-load-dangerous @gol
-fsched-stalled-insns=@var{n} -sched-stalled-insns-dep=@var{n} @gol -fsched-stalled-insns=@var{n} -sched-stalled-insns-dep=@var{n} @gol
-fsched2-use-superblocks @gol -fsched2-use-superblocks @gol
-fsched2-use-traces -fsignaling-nans @gol -fsched2-use-traces -freschedule-modulo-scheduled-loops @gol
-fsingle-precision-constant @gol -fsignaling-nans -fsingle-precision-constant @gol
-fstrength-reduce -fstrict-aliasing -ftracer -fthread-jumps @gol -fstrength-reduce -fstrict-aliasing -ftracer -fthread-jumps @gol
-funroll-all-loops -funroll-loops -fpeel-loops @gol -funroll-all-loops -funroll-loops -fpeel-loops @gol
-funswitch-loops -fold-unroll-loops -fold-unroll-all-loops @gol -funswitch-loops -fold-unroll-loops -fold-unroll-all-loops @gol
...@@ -4393,6 +4393,12 @@ reality and hurt the performance. This only makes ...@@ -4393,6 +4393,12 @@ reality and hurt the performance. This only makes
sense when scheduling after register allocation, i.e.@: with sense when scheduling after register allocation, i.e.@: with
@option{-fschedule-insns2} or at @option{-O2} or higher. @option{-fschedule-insns2} or at @option{-O2} or higher.
@item -freschedule-modulo-scheduled-loops
@opindex fscheduling-in-modulo-scheduled-loops
The modulo scheduling comes before the traditional scheduling, if a loop was modulo scheduled
we may want to prevent the later scheduling passes from changing its schedule, we use this
option to control that.
@item -fcaller-saves @item -fcaller-saves
@opindex fcaller-saves @opindex fcaller-saves
Enable values to be allocated in registers that will be clobbered by Enable values to be allocated in registers that will be clobbered by
......
...@@ -1704,6 +1704,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, ...@@ -1704,6 +1704,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
case NOTE_INSN_FUNCTION_END: case NOTE_INSN_FUNCTION_END:
case NOTE_INSN_REPEATED_LINE_NUMBER: case NOTE_INSN_REPEATED_LINE_NUMBER:
case NOTE_INSN_EXPECTED_VALUE: case NOTE_INSN_EXPECTED_VALUE:
case NOTE_DISABLE_SCHED_OF_BLOCK:
break; break;
case NOTE_INSN_UNLIKELY_EXECUTED_CODE: case NOTE_INSN_UNLIKELY_EXECUTED_CODE:
......
...@@ -152,7 +152,9 @@ void free_partial_schedule (partial_schedule_ptr); ...@@ -152,7 +152,9 @@ void free_partial_schedule (partial_schedule_ptr);
void reset_partial_schedule (partial_schedule_ptr, int new_ii); void reset_partial_schedule (partial_schedule_ptr, int new_ii);
void print_partial_schedule (partial_schedule_ptr, FILE *); void print_partial_schedule (partial_schedule_ptr, FILE *);
ps_insn_ptr ps_add_node_check_conflicts (partial_schedule_ptr, ps_insn_ptr ps_add_node_check_conflicts (partial_schedule_ptr,
ddg_node_ptr node, int cycle); ddg_node_ptr node, int cycle,
sbitmap must_precede,
sbitmap must_follow);
void rotate_partial_schedule (partial_schedule_ptr, int); void rotate_partial_schedule (partial_schedule_ptr, int);
void set_row_column_for_ps (partial_schedule_ptr); void set_row_column_for_ps (partial_schedule_ptr);
...@@ -874,7 +876,7 @@ sms_schedule (FILE *dump_file) ...@@ -874,7 +876,7 @@ sms_schedule (FILE *dump_file)
continue; continue;
/* For debugging. */ /* For debugging. */
if (passes++ > MAX_SMS_LOOP_NUMBER && MAX_SMS_LOOP_NUMBER != -1) if ((passes++ > MAX_SMS_LOOP_NUMBER) && (MAX_SMS_LOOP_NUMBER != -1))
{ {
if (dump_file) if (dump_file)
fprintf (dump_file, "SMS reached MAX_PASSES... \n"); fprintf (dump_file, "SMS reached MAX_PASSES... \n");
...@@ -1086,8 +1088,8 @@ sms_schedule (FILE *dump_file) ...@@ -1086,8 +1088,8 @@ sms_schedule (FILE *dump_file)
int i; int i;
start_sequence (); start_sequence ();
/* Copy the original loop code before modifying it - so we can use /* Copy the original loop code before modifying it -
it later. */ so we can use it later. */
for (i = 0; i < ps->g->num_nodes; i++) for (i = 0; i < ps->g->num_nodes; i++)
duplicate_insn_chain (ps->g->nodes[i].first_note, duplicate_insn_chain (ps->g->nodes[i].first_note,
ps->g->nodes[i].insn); ps->g->nodes[i].insn);
...@@ -1106,6 +1108,13 @@ sms_schedule (FILE *dump_file) ...@@ -1106,6 +1108,13 @@ sms_schedule (FILE *dump_file)
set_columns_for_ps (ps); set_columns_for_ps (ps);
permute_partial_schedule (ps, g->closing_branch->first_note); permute_partial_schedule (ps, g->closing_branch->first_note);
/* Mark this loop as software pipelined so the later
scheduling passes doesn't touch it. */
if (! flag_resched_modulo_sched)
emit_note_before (NOTE_DISABLE_SCHED_OF_BLOCK,
g->closing_branch->insn);
generate_reg_moves (ps); generate_reg_moves (ps);
if (dump_file) if (dump_file)
print_node_sched_params (dump_file, g->num_nodes); print_node_sched_params (dump_file, g->num_nodes);
...@@ -1217,6 +1226,9 @@ sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order, FILE *du ...@@ -1217,6 +1226,9 @@ sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order, FILE *du
sbitmap sched_nodes = sbitmap_alloc (num_nodes); sbitmap sched_nodes = sbitmap_alloc (num_nodes);
sbitmap psp = sbitmap_alloc (num_nodes); sbitmap psp = sbitmap_alloc (num_nodes);
sbitmap pss = sbitmap_alloc (num_nodes); sbitmap pss = sbitmap_alloc (num_nodes);
sbitmap must_precede = sbitmap_alloc (num_nodes);
sbitmap must_follow = sbitmap_alloc (num_nodes);
partial_schedule_ptr ps = create_partial_schedule (ii, g, DFA_HISTORY); partial_schedule_ptr ps = create_partial_schedule (ii, g, DFA_HISTORY);
while (try_again_with_larger_ii && ii < maxii) while (try_again_with_larger_ii && ii < maxii)
...@@ -1258,9 +1270,11 @@ sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order, FILE *du ...@@ -1258,9 +1270,11 @@ sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order, FILE *du
ddg_node_ptr v_node = e->src; ddg_node_ptr v_node = e->src;
if (TEST_BIT (sched_nodes, v_node->cuid)) if (TEST_BIT (sched_nodes, v_node->cuid))
{ {
early_start = MAX (early_start, int node_st = SCHED_TIME (v_node)
SCHED_TIME (v_node) + e->latency - (e->distance * ii);
+ e->latency - (e->distance * ii));
early_start = MAX (early_start, node_st);
if (e->data_type == MEM_DEP) if (e->data_type == MEM_DEP)
end = MIN (end, SCHED_TIME (v_node) + ii - 1); end = MIN (end, SCHED_TIME (v_node) + ii - 1);
} }
...@@ -1341,11 +1355,31 @@ sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order, FILE *du ...@@ -1341,11 +1355,31 @@ sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order, FILE *du
fprintf(dump_file, "Trying to schedule node %d in (%d .. %d) step %d\n", fprintf(dump_file, "Trying to schedule node %d in (%d .. %d) step %d\n",
u, start, end, step); u, start, end, step);
/* use must_follow & must_precede bitmaps to determine order
of nodes within the cycle. */
sbitmap_zero (must_precede);
sbitmap_zero (must_follow);
for (e = u_node->in; e != 0; e = e->next_in)
if (TEST_BIT (sched_nodes, e->src->cuid)
&& e->latency == (ii * e->distance)
&& start == SCHED_TIME (e->src))
SET_BIT (must_precede, e->src->cuid);
for (e = u_node->out; e != 0; e = e->next_out)
if (TEST_BIT (sched_nodes, e->dest->cuid)
&& e->latency == (ii * e->distance)
&& end == SCHED_TIME (e->dest))
SET_BIT (must_follow, e->dest->cuid);
success = 0; success = 0;
if ((step > 0 && start < end) || (step < 0 && start > end)) if ((step > 0 && start < end) || (step < 0 && start > end))
for (c = start; c != end; c += step) for (c = start; c != end; c += step)
{ {
ps_insn_ptr psi = ps_add_node_check_conflicts (ps, u_node, c); ps_insn_ptr psi;
psi = ps_add_node_check_conflicts (ps, u_node, c,
must_precede,
must_follow);
if (psi) if (psi)
{ {
...@@ -1884,13 +1918,80 @@ remove_node_from_ps (partial_schedule_ptr ps, ps_insn_ptr ps_i) ...@@ -1884,13 +1918,80 @@ remove_node_from_ps (partial_schedule_ptr ps, ps_insn_ptr ps_i)
return true; return true;
} }
/* Unlike what literature describes for modulo scheduling (which focuses
on VLIW machines) the order of the instructions inside a cycle is
important. Given the bitmaps MUST_FOLLOW and MUST_PRECEDE we know
where the current instruction should go relative to the already
scheduled instructions in the given cycle. Go over these
instructions and find the first possible column to put it in. */
static bool
ps_insn_find_column (partial_schedule_ptr ps, ps_insn_ptr ps_i,
sbitmap must_precede, sbitmap must_follow)
{
ps_insn_ptr next_ps_i;
ps_insn_ptr first_must_follow = NULL;
ps_insn_ptr last_must_precede = NULL;
int row;
if (! ps_i)
return false;
row = SMODULO (ps_i->cycle, ps->ii);
/* Find the first must follow and the last must precede
and insert the node immediatly after the must precede
but make sure that it there is no must follow after it. */
for (next_ps_i = ps->rows[row];
next_ps_i;
next_ps_i = next_ps_i->next_in_row)
{
if (TEST_BIT (must_follow, next_ps_i->node->cuid)
&& ! first_must_follow)
first_must_follow = next_ps_i;
if (TEST_BIT (must_precede, next_ps_i->node->cuid))
{
/* If we have already met a node that must follow, then
there is no possible column. */
if (first_must_follow)
return false;
else
last_must_precede = next_ps_i;
}
}
/* Now insert the node after INSERT_AFTER_PSI. */
if (! last_must_precede)
{
ps_i->next_in_row = ps->rows[row];
ps_i->prev_in_row = NULL;
if (ps_i->next_in_row)
ps_i->next_in_row->prev_in_row = ps_i;
ps->rows[row] = ps_i;
}
else
{
ps_i->next_in_row = last_must_precede->next_in_row;
last_must_precede->next_in_row = ps_i;
ps_i->prev_in_row = last_must_precede;
if (ps_i->next_in_row)
ps_i->next_in_row->prev_in_row = ps_i;
}
return true;
}
/* Advances the PS_INSN one column in its current row; returns false /* Advances the PS_INSN one column in its current row; returns false
in failure and true in success. */ 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 static int
ps_insn_advance_column (partial_schedule_ptr ps, ps_insn_ptr ps_i) ps_insn_advance_column (partial_schedule_ptr ps, ps_insn_ptr ps_i,
sbitmap must_follow)
{ {
ps_insn_ptr prev, next; ps_insn_ptr prev, next;
int row; int row;
ddg_node_ptr next_node;
if (!ps || !ps_i) if (!ps || !ps_i)
return false; return false;
...@@ -1900,17 +2001,12 @@ ps_insn_advance_column (partial_schedule_ptr ps, ps_insn_ptr ps_i) ...@@ -1900,17 +2001,12 @@ ps_insn_advance_column (partial_schedule_ptr ps, ps_insn_ptr ps_i)
if (! ps_i->next_in_row) if (! ps_i->next_in_row)
return false; return false;
next_node = ps_i->next_in_row->node;
/* Check if next_in_row is dependent on ps_i, both having same sched /* Check if next_in_row is dependent on ps_i, both having same sched
times (typically ANTI_DEP). If so, ps_i cannot skip over it. */ times (typically ANTI_DEP). If so, ps_i cannot skip over it. */
if (ps_i->cycle == ps_i->next_in_row->cycle) if (TEST_BIT (must_follow, next_node->cuid))
{ return false;
ddg_edge_ptr e;
ddg_node_ptr next_node = ps_i->next_in_row->node;
for (e = ps_i->node->out; e; e = e->next_out)
if (e->dest == next_node)
return false;
}
/* Advace PS_I over its next_in_row in the doubly linked list. */ /* Advace PS_I over its next_in_row in the doubly linked list. */
prev = ps_i->prev_in_row; prev = ps_i->prev_in_row;
...@@ -1935,14 +2031,17 @@ ps_insn_advance_column (partial_schedule_ptr ps, ps_insn_ptr ps_i) ...@@ -1935,14 +2031,17 @@ 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. /* 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. */ 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 static ps_insn_ptr
add_node_to_ps (partial_schedule_ptr ps, ddg_node_ptr node, int cycle) add_node_to_ps (partial_schedule_ptr ps, ddg_node_ptr node, int cycle,
sbitmap must_precede, sbitmap must_follow)
{ {
ps_insn_ptr ps_i, next_ps_i, advance_after; ps_insn_ptr ps_i;
int rest_count = 1; int rest_count = 1;
int row = SMODULO (cycle, ps->ii); int row = SMODULO (cycle, ps->ii);
ddg_edge_ptr e;
if (ps->rows[row] if (ps->rows[row]
&& ps->rows[row]->row_rest_count >= issue_rate) && ps->rows[row]->row_rest_count >= issue_rate)
...@@ -1952,30 +2051,14 @@ add_node_to_ps (partial_schedule_ptr ps, ddg_node_ptr node, int cycle) ...@@ -1952,30 +2051,14 @@ add_node_to_ps (partial_schedule_ptr ps, ddg_node_ptr node, int cycle)
rest_count += ps->rows[row]->row_rest_count; rest_count += ps->rows[row]->row_rest_count;
ps_i = create_ps_insn (node, rest_count, cycle); ps_i = create_ps_insn (node, rest_count, cycle);
ps_i->next_in_row = ps->rows[row];
ps_i->prev_in_row = NULL; /* Finds and inserts PS_I according to MUST_FOLLOW and
if (ps_i->next_in_row) MUST_PRECEDE. */
ps_i->next_in_row->prev_in_row = ps_i; if (! ps_insn_find_column (ps, ps_i, must_precede, must_follow))
ps->rows[row] = ps_i; {
free (ps_i);
/* Check if n is dependent on an insn already in row, having same cycle return NULL;
(typically ANTI_DEP). If so, n must skip over it. */ }
advance_after = NULL;
for (next_ps_i = ps_i->next_in_row;
next_ps_i;
next_ps_i = next_ps_i->next_in_row)
if (next_ps_i->cycle == cycle)
for (e = node->in; e; e = e->next_in)
if (e->src == next_ps_i->node)
advance_after = next_ps_i;
if (advance_after)
while (ps_i->prev_in_row != advance_after)
if (!ps_insn_advance_column (ps, ps_i))
{
remove_node_from_ps (ps, ps_i);
return NULL;
}
return ps_i; return ps_i;
} }
...@@ -2049,16 +2132,20 @@ ps_has_conflicts (partial_schedule_ptr ps, int from, int to) ...@@ -2049,16 +2132,20 @@ ps_has_conflicts (partial_schedule_ptr ps, int from, int to)
/* Checks if the given node causes resource conflicts when added to PS at /* 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 cycle C. If not the node is added to PS and returned; otherwise zero
is returned. */ 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_insn_ptr
ps_add_node_check_conflicts (partial_schedule_ptr ps, ddg_node_ptr n, int c) ps_add_node_check_conflicts (partial_schedule_ptr ps, ddg_node_ptr n,
int c, sbitmap must_precede,
sbitmap must_follow)
{ {
int has_conflicts = 0; int has_conflicts = 0;
ps_insn_ptr ps_i; ps_insn_ptr ps_i;
/* First add the node to the PS, if this succeeds check for conflicts, /* First add the node to the PS, if this succeeds check for
trying different issue slots in the same row. */ conflicts, trying different issue slots in the same row. */
if (! (ps_i = add_node_to_ps (ps, n, c))) if (! (ps_i = add_node_to_ps (ps, n, c, must_precede, must_follow)))
return NULL; /* Failed to insert the node at the given cycle. */ return NULL; /* Failed to insert the node at the given cycle. */
has_conflicts = ps_has_conflicts (ps, c, c) has_conflicts = ps_has_conflicts (ps, c, c)
...@@ -2071,7 +2158,7 @@ ps_add_node_check_conflicts (partial_schedule_ptr ps, ddg_node_ptr n, int c) ...@@ -2071,7 +2158,7 @@ ps_add_node_check_conflicts (partial_schedule_ptr ps, ddg_node_ptr n, int c)
scheduled in without conflicts. */ scheduled in without conflicts. */
while (has_conflicts) while (has_conflicts)
{ {
if (! ps_insn_advance_column (ps, ps_i)) if (! ps_insn_advance_column (ps, ps_i, must_follow))
break; break;
has_conflicts = ps_has_conflicts (ps, c, c) has_conflicts = ps_has_conflicts (ps, c, c)
|| (ps->history > 0 || (ps->history > 0
......
...@@ -983,6 +983,12 @@ enum insn_note ...@@ -983,6 +983,12 @@ enum insn_note
/* Generated at the start of a duplicated exit test. */ /* Generated at the start of a duplicated exit test. */
NOTE_INSN_LOOP_VTOP, NOTE_INSN_LOOP_VTOP,
/* Mark that a block shouldn't be scheduled. This is currently
used in modulo scheduling. Modulo scheduling adds this note
to the blocks of the modulo-scheduled loops to disable scheduling
them in the later traditional scheduling passes. */
NOTE_DISABLE_SCHED_OF_BLOCK,
/* This kind of note is generated at the end of the function body, /* This kind of note is generated at the end of the function body,
just before the return insn or return label. In an optimizing just before the return insn or return label. In an optimizing
compilation it is deleted by the first jump optimization, after compilation it is deleted by the first jump optimization, after
......
...@@ -117,6 +117,7 @@ static int *out_edges; ...@@ -117,6 +117,7 @@ static int *out_edges;
static int is_cfg_nonregular (void); static int is_cfg_nonregular (void);
static int build_control_flow (struct edge_list *); static int build_control_flow (struct edge_list *);
static void new_edge (int, int); static void new_edge (int, int);
static bool sched_is_disabled_for_current_region_p (void);
/* A region is the main entity for interblock scheduling: insns /* A region is the main entity for interblock scheduling: insns
are allowed to move between blocks in the same region, along are allowed to move between blocks in the same region, along
...@@ -2332,6 +2333,37 @@ debug_dependencies (void) ...@@ -2332,6 +2333,37 @@ debug_dependencies (void)
fprintf (sched_dump, "\n"); fprintf (sched_dump, "\n");
} }
/* Returns true if all the basic blocks of the current region have
NOTE_DISABLE_SCHED_OF_BLOCK which means not to schedule that region. */
static bool
sched_is_disabled_for_current_region_p (void)
{
rtx first_bb_insn, last_bb_insn, insn;
int bb;
for (bb = 0; bb < current_nr_blocks; bb++)
{
bool disable_sched = false;
/* Searching for NOTE_DISABLE_SCHED_OF_BLOCK note between the
start and end of the basic block. */
get_block_head_tail (BB_TO_BLOCK (bb), &first_bb_insn,
&last_bb_insn);
for (insn = last_bb_insn; insn != NULL && insn != first_bb_insn;
insn = PREV_INSN (insn))
if (GET_CODE (insn) == NOTE
&& (NOTE_LINE_NUMBER (insn)
== NOTE_DISABLE_SCHED_OF_BLOCK))
{
disable_sched = true;
break;
}
if (! disable_sched)
return false;
}
return true;
}
/* Schedule a region. A region is either an inner loop, a loop-free /* Schedule a region. A region is either an inner loop, a loop-free
subroutine, or a single basic block. Each bb in the region is subroutine, or a single basic block. Each bb in the region is
scheduled after its flow predecessors. */ scheduled after its flow predecessors. */
...@@ -2347,6 +2379,11 @@ schedule_region (int rgn) ...@@ -2347,6 +2379,11 @@ schedule_region (int rgn)
current_nr_blocks = RGN_NR_BLOCKS (rgn); current_nr_blocks = RGN_NR_BLOCKS (rgn);
current_blocks = RGN_BLOCKS (rgn); current_blocks = RGN_BLOCKS (rgn);
/* Don't schedule region that is marked by
NOTE_DISABLE_SCHED_OF_BLOCK. */
if (sched_is_disabled_for_current_region_p ())
return;
init_deps_global (); init_deps_global ();
/* Initializations for region data dependence analysis. */ /* Initializations for region data dependence analysis. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment