Commit ca3c1028 by Richard Henderson Committed by Richard Henderson

sched-deps.c (sched_analyze_insn): Consolidate scheduling barrier code.

        * sched-deps.c (sched_analyze_insn): Consolidate scheduling
        barrier code.  Add a scheduling barrier if a non-call insn
        can throw internally.

From-SVN: r40915
parent 4f73495e
2001-03-27 Richard Henderson <rth@redhat.com> 2001-03-27 Richard Henderson <rth@redhat.com>
* sched-deps.c (sched_analyze_insn): Consolidate scheduling
barrier code. Add a scheduling barrier if a non-call insn
can throw internally.
* rtlanal.c (rtx_addr_can_trap_p): Virtual registers cannot trap. * rtlanal.c (rtx_addr_can_trap_p): Virtual registers cannot trap.
Auto-inc addresses trap only if their base register does. Auto-inc addresses trap only if their base register does.
......
...@@ -972,6 +972,7 @@ sched_analyze_insn (deps, x, insn, loop_notes) ...@@ -972,6 +972,7 @@ sched_analyze_insn (deps, x, insn, loop_notes)
rtx loop_notes; rtx loop_notes;
{ {
register RTX_CODE code = GET_CODE (x); register RTX_CODE code = GET_CODE (x);
int schedule_barrier_found = 0;
rtx link; rtx link;
int i; int i;
...@@ -1021,22 +1022,10 @@ sched_analyze_insn (deps, x, insn, loop_notes) ...@@ -1021,22 +1022,10 @@ sched_analyze_insn (deps, x, insn, loop_notes)
if (GET_CODE (insn) == JUMP_INSN) if (GET_CODE (insn) == JUMP_INSN)
{ {
rtx next, u, pending, pending_mem; rtx next, u;
next = next_nonnote_insn (insn); next = next_nonnote_insn (insn);
if (next && GET_CODE (next) == BARRIER) if (next && GET_CODE (next) == BARRIER)
{ schedule_barrier_found = 1;
for (i = 0; i < deps->max_reg; i++)
{
struct deps_reg *reg_last = &deps->reg_last[i];
for (u = reg_last->uses; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
for (u = reg_last->sets; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
for (u = reg_last->clobbers; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
}
}
else else
{ {
regset_head tmp; regset_head tmp;
...@@ -1054,33 +1043,19 @@ sched_analyze_insn (deps, x, insn, loop_notes) ...@@ -1054,33 +1043,19 @@ sched_analyze_insn (deps, x, insn, loop_notes)
CLEAR_REG_SET (&tmp); CLEAR_REG_SET (&tmp);
} }
pending = deps->pending_write_insns;
pending_mem = deps->pending_write_mems;
while (pending)
{
add_dependence (insn, XEXP (pending, 0), 0);
pending = XEXP (pending, 1);
pending_mem = XEXP (pending_mem, 1);
}
for (u = deps->last_pending_memory_flush; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
} }
/* If there is a {LOOP,EHREGION}_{BEG,END} note in the middle of a basic /* If there is a {LOOP,EHREGION}_{BEG,END} note in the middle of a basic
block, then we must be sure that no instructions are scheduled across it. block, then we must be sure that no instructions are scheduled across it.
Otherwise, the reg_n_refs info (which depends on loop_depth) would Otherwise, the reg_n_refs info (which depends on loop_depth) would
become incorrect. */ become incorrect. */
if (loop_notes) if (loop_notes)
{ {
int schedule_barrier_found = 0;
rtx link; rtx link;
/* Update loop_notes with any notes from this insn. Also determine /* Update loop_notes with any notes from this insn. Also determine
if any of the notes on the list correspond to instruction scheduling if any of the notes on the list correspond to instruction scheduling
barriers (loop, eh & setjmp notes, but not range notes. */ barriers (loop, eh & setjmp notes, but not range notes). */
link = loop_notes; link = loop_notes;
while (XEXP (link, 1)) while (XEXP (link, 1))
{ {
...@@ -1095,30 +1070,48 @@ sched_analyze_insn (deps, x, insn, loop_notes) ...@@ -1095,30 +1070,48 @@ sched_analyze_insn (deps, x, insn, loop_notes)
} }
XEXP (link, 1) = REG_NOTES (insn); XEXP (link, 1) = REG_NOTES (insn);
REG_NOTES (insn) = loop_notes; REG_NOTES (insn) = loop_notes;
}
/* If this instruction can throw an exception, then moving it changes
where block boundaries fall. This is mighty confusing elsewhere.
Therefore, prevent such an instruction from being moved. */
if (flag_non_call_exceptions && can_throw_internal (insn))
schedule_barrier_found = 1;
/* Add dependencies if a scheduling barrier was found. */ /* Add dependencies if a scheduling barrier was found. */
if (schedule_barrier_found) if (schedule_barrier_found)
{
rtx u, pending, pending_mem;
for (i = 0; i < deps->max_reg; i++)
{ {
for (i = 0; i < deps->max_reg; i++) struct deps_reg *reg_last = &deps->reg_last[i];
{
struct deps_reg *reg_last = &deps->reg_last[i];
rtx u;
for (u = reg_last->uses; u; u = XEXP (u, 1)) for (u = reg_last->uses; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI); add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
for (u = reg_last->sets; u; u = XEXP (u, 1)) for (u = reg_last->sets; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0); add_dependence (insn, XEXP (u, 0), 0);
for (u = reg_last->clobbers; u; u = XEXP (u, 1)) for (u = reg_last->clobbers; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0); add_dependence (insn, XEXP (u, 0), 0);
if (GET_CODE (PATTERN (insn)) != COND_EXEC) if (GET_CODE (PATTERN (insn)) != COND_EXEC)
free_INSN_LIST_list (&reg_last->uses); free_INSN_LIST_list (&reg_last->uses);
} }
reg_pending_sets_all = 1; flush_pending_lists (deps, insn, 0);
flush_pending_lists (deps, insn, 0); pending = deps->pending_write_insns;
pending_mem = deps->pending_write_mems;
while (pending)
{
add_dependence (insn, XEXP (pending, 0), 0);
pending = XEXP (pending, 1);
pending_mem = XEXP (pending_mem, 1);
} }
for (u = deps->last_pending_memory_flush; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
reg_pending_sets_all = 1;
} }
/* Accumulate clobbers until the next set so that it will be output /* Accumulate clobbers until the next set so that it will be output
......
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