aboutsummaryrefslogtreecommitdiff
path: root/gcc/sched.c
diff options
context:
space:
mode:
authorJim Wilson <wilson@gcc.gnu.org>1993-12-21 10:58:10 -0800
committerJim Wilson <wilson@gcc.gnu.org>1993-12-21 10:58:10 -0800
commit38d42368127ac8d4f82722d68e0ce9d152d2435b (patch)
tree87b6ef465511480d1e1e3821701ae84a2ba221f2 /gcc/sched.c
parent3eb8f14cbc240ac542ac954dccf0fe8569cc1c30 (diff)
downloadgcc-38d42368127ac8d4f82722d68e0ce9d152d2435b.zip
gcc-38d42368127ac8d4f82722d68e0ce9d152d2435b.tar.gz
gcc-38d42368127ac8d4f82722d68e0ce9d152d2435b.tar.bz2
(sched_analyze): For CALL_INSN followed by NOTE_INSN_SETJMP note...
(sched_analyze): For CALL_INSN followed by NOTE_INSN_SETJMP note, make it depend on all registers not just hard registers, and add a REG_DEAD -1 note. (unlink_notes): Don't save away NOTE_INSN_SETJMP notes. (schedule_block): After scheduling CALL_INSN, check for REG_DEAD -1 note. If find it, delete it, and output a NOTE_INSN_SETJMP note. From-SVN: r6254
Diffstat (limited to 'gcc/sched.c')
-rw-r--r--gcc/sched.c69
1 files changed, 56 insertions, 13 deletions
diff --git a/gcc/sched.c b/gcc/sched.c
index ac0b7a5..78af990 100644
--- a/gcc/sched.c
+++ b/gcc/sched.c
@@ -2098,18 +2098,45 @@ sched_analyze (head, tail)
past a void call (i.e. it does not explicitly set the hard
return reg). */
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (call_used_regs[i] || global_regs[i])
- {
- for (u = reg_last_uses[i]; u; u = XEXP (u, 1))
- add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
- reg_last_uses[i] = 0;
- if (reg_last_sets[i])
- add_dependence (insn, reg_last_sets[i], REG_DEP_ANTI);
- reg_last_sets[i] = insn;
- /* Insn, being a CALL_INSN, magically depends on
- `last_function_call' already. */
- }
+ /* If this call is followed by a NOTE_INSN_SETJMP, then assume that
+ all registers, not just hard registers, may be clobbered by this
+ call. */
+
+ /* Insn, being a CALL_INSN, magically depends on
+ `last_function_call' already. */
+
+ if (NEXT_INSN (insn) && GET_CODE (NEXT_INSN (insn)) == NOTE
+ && NOTE_LINE_NUMBER (NEXT_INSN (insn)) == NOTE_INSN_SETJMP)
+ {
+ int max_reg = max_reg_num ();
+ for (i = 0; i < max_reg; i++)
+ {
+ for (u = reg_last_uses[i]; u; u = XEXP (u, 1))
+ add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
+ reg_last_uses[i] = 0;
+ if (reg_last_sets[i])
+ add_dependence (insn, reg_last_sets[i], 0);
+ reg_last_sets[i] = insn;
+ }
+
+ /* Add a fake REG_NOTE which we will later convert
+ back into a NOTE_INSN_SETJMP note. */
+ REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD, constm1_rtx,
+ REG_NOTES (insn));
+ }
+ else
+ {
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (call_used_regs[i] || global_regs[i])
+ {
+ for (u = reg_last_uses[i]; u; u = XEXP (u, 1))
+ add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
+ reg_last_uses[i] = 0;
+ if (reg_last_sets[i])
+ add_dependence (insn, reg_last_sets[i], REG_DEP_ANTI);
+ reg_last_sets[i] = insn;
+ }
+ }
/* For each insn which shouldn't cross a call, add a dependence
between that insn and this call insn. */
@@ -2885,7 +2912,11 @@ unlink_notes (insn, tail)
if (write_symbols != NO_DEBUG && NOTE_LINE_NUMBER (insn) > 0)
/* Record line-number notes so they can be reused. */
LINE_NOTE (insn) = insn;
- else
+
+ /* Don't save away NOTE_INSN_SETJMPs, because they must remain
+ immediately after the call they follow. We use a fake
+ (REG_DEAD (const_int -1)) note to remember them. */
+ else if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_SETJMP)
{
/* Insert the note at the end of the notes list. */
PREV_INSN (insn) = note_list;
@@ -3702,6 +3733,18 @@ schedule_block (b, file)
PREV_INSN (last) = insn;
last = insn;
+ /* Check to see if we need to re-emit a NOTE_INSN_SETJMP here. */
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ rtx note = find_reg_note (insn, REG_DEAD, constm1_rtx);
+
+ if (note)
+ {
+ emit_note_after (NOTE_INSN_SETJMP, insn);
+ remove_note (insn, note);
+ }
+ }
+
/* Everything that precedes INSN now either becomes "ready", if
it can execute immediately before INSN, or "pending", if
there must be a delay. Give INSN high enough priority that