From: Jim Wilson Date: Tue, 21 Dec 1993 18:58:10 +0000 (-0800) Subject: (sched_analyze): For CALL_INSN followed by NOTE_INSN_SETJMP note... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=38d42368127ac8d4f82722d68e0ce9d152d2435b;p=platform%2Fupstream%2Fgcc.git (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 --- 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