diff options
author | wilson <wilson@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-10-05 23:24:18 +0000 |
---|---|---|
committer | wilson <wilson@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-10-05 23:24:18 +0000 |
commit | 0b43d1b24866cb86b5440744dc54b82ebf7fb125 (patch) | |
tree | c4fb33b2bcd24213c4329edef7116967bd34aa25 /gcc/function.c | |
parent | 4a0e2d42652a3252dd5830e43b43d312e6568a99 (diff) | |
download | gcc-0b43d1b24866cb86b5440744dc54b82ebf7fb125.tar.gz |
Fix IA-64 REG_LIBCALL dangling reference.
* function.c (fixup_var_refs_1, case SET): When gen_move_insn returns a
SEQUENCE, call emit_insn_before, copy PATTERN and REG_NOTES of last
sequence insn to INSN, and delete last sequence insn.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36735 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/function.c')
-rw-r--r-- | gcc/function.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/gcc/function.c b/gcc/function.c index f05711487b6..f5814109211 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2324,7 +2324,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements) && GET_MODE (var) == promoted_mode && x == single_set (insn)) { - rtx pat; + rtx pat, last; replacement = find_fixup_replacement (replacements, SET_SRC (x)); if (replacement->new) @@ -2350,10 +2350,22 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements) pat = gen_move_insn (SET_DEST (x), SET_SRC (x)); if (GET_CODE (pat) == SEQUENCE) { - emit_insn_after (pat, insn); - PUT_CODE (insn, NOTE); - NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; - NOTE_SOURCE_FILE (insn) = 0; + last = emit_insn_before (pat, insn); + + /* INSN might have REG_RETVAL or other important notes, so + we need to store the pattern of the last insn in the + sequence into INSN similarly to the normal case. LAST + should not have REG_NOTES, but we allow them if INSN has + no REG_NOTES. */ + if (REG_NOTES (last) && REG_NOTES (insn)) + abort (); + if (REG_NOTES (last)) + REG_NOTES (insn) = REG_NOTES (last); + PATTERN (insn) = PATTERN (last); + + PUT_CODE (last, NOTE); + NOTE_LINE_NUMBER (last) = NOTE_INSN_DELETED; + NOTE_SOURCE_FILE (last) = 0; } else PATTERN (insn) = pat; @@ -2370,7 +2382,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements) && GET_MODE (var) == promoted_mode && x == single_set (insn)) { - rtx pat; + rtx pat, last; if (GET_CODE (SET_DEST (x)) == SUBREG) SET_DEST (x) = fixup_memory_subreg (SET_DEST (x), insn, 0); @@ -2383,10 +2395,22 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements) pat = gen_move_insn (SET_DEST (x), SET_SRC (x)); if (GET_CODE (pat) == SEQUENCE) { - emit_insn_after (pat, insn); - PUT_CODE (insn, NOTE); - NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; - NOTE_SOURCE_FILE (insn) = 0; + last = emit_insn_before (pat, insn); + + /* INSN might have REG_RETVAL or other important notes, so + we need to store the pattern of the last insn in the + sequence into INSN similarly to the normal case. LAST + should not have REG_NOTES, but we allow them if INSN has + no REG_NOTES. */ + if (REG_NOTES (last) && REG_NOTES (insn)) + abort (); + if (REG_NOTES (last)) + REG_NOTES (insn) = REG_NOTES (last); + PATTERN (insn) = PATTERN (last); + + PUT_CODE (last, NOTE); + NOTE_LINE_NUMBER (last) = NOTE_INSN_DELETED; + NOTE_SOURCE_FILE (last) = 0; } else PATTERN (insn) = pat; |