diff options
author | kan <kan@FreeBSD.org> | 2003-08-22 02:56:07 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2003-08-22 02:56:07 +0000 |
commit | 08db0e4d745472adc9c30de407304713c78e950e (patch) | |
tree | aa86de970d24a76b30b53157cf41e9d09ffe4d51 /contrib/gcc/flow.c | |
parent | 7b704871fdac058719f34a1e6b9de71ee76c5be4 (diff) | |
download | FreeBSD-src-08db0e4d745472adc9c30de407304713c78e950e.zip FreeBSD-src-08db0e4d745472adc9c30de407304713c78e950e.tar.gz |
Gcc 3.3.1-release.
Diffstat (limited to 'contrib/gcc/flow.c')
-rw-r--r-- | contrib/gcc/flow.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/contrib/gcc/flow.c b/contrib/gcc/flow.c index 3389766..7882b25 100644 --- a/contrib/gcc/flow.c +++ b/contrib/gcc/flow.c @@ -1757,8 +1757,10 @@ propagate_one_insn (pbi, insn) if (GET_CODE (insn) == CALL_INSN) { - int i; + regset live_at_end; + bool sibcall_p; rtx note, cond; + int i; cond = NULL_RTX; if (GET_CODE (PATTERN (insn)) == COND_EXEC) @@ -1783,9 +1785,19 @@ propagate_one_insn (pbi, insn) mark_set_1 (pbi, CLOBBER, XEXP (XEXP (note, 0), 0), cond, insn, pbi->flags); - /* Calls change all call-used and global registers. */ + /* Calls change all call-used and global registers; sibcalls do not + clobber anything that must be preserved at end-of-function, + except for return values. */ + + sibcall_p = SIBLING_CALL_P (insn); + live_at_end = EXIT_BLOCK_PTR->global_live_at_start; for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i)) + if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i) + && ! (sibcall_p + && REGNO_REG_SET_P (live_at_end, i) + && ! refers_to_regno_p (i, i+1, + current_function_return_rtx, + (rtx *) 0))) { /* We do not want REG_UNUSED notes for these registers. */ mark_set_1 (pbi, CLOBBER, regno_reg_rtx[i], cond, insn, |