diff options
author | Jim Wilson <wilson@gcc.gnu.org> | 1993-12-21 10:58:10 -0800 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 1993-12-21 10:58:10 -0800 |
commit | 38d42368127ac8d4f82722d68e0ce9d152d2435b (patch) | |
tree | 87b6ef465511480d1e1e3821701ae84a2ba221f2 /gcc/sched.c | |
parent | 3eb8f14cbc240ac542ac954dccf0fe8569cc1c30 (diff) | |
download | gcc-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.c | 69 |
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 |