diff options
author | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-08-02 20:17:59 +0000 |
---|---|---|
committer | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-08-02 20:17:59 +0000 |
commit | d762f8cc9189feaf8b49058f5bb42aa0ec6f2514 (patch) | |
tree | 0ffc9ab78ee641e805a69ce10d99a3c7d5a26661 /gcc/caller-save.c | |
parent | f439e54374b0f977641470856962727262fc7a0a (diff) | |
download | ppe42-gcc-d762f8cc9189feaf8b49058f5bb42aa0ec6f2514.tar.gz ppe42-gcc-d762f8cc9189feaf8b49058f5bb42aa0ec6f2514.zip |
PR target/45063
* caller-save.c (save_call_clobbered_regs): Remove regs from
hard_regs_saved when they are set.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162828 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/caller-save.c')
-rw-r--r-- | gcc/caller-save.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/gcc/caller-save.c b/gcc/caller-save.c index af9b2da8975..60c47477e89 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -763,6 +763,7 @@ save_call_clobbered_regs (void) if (n_regs_saved) { int regno; + HARD_REG_SET this_insn_sets; if (code == JUMP_INSN) /* Restore all registers if this is a JUMP_INSN. */ @@ -777,7 +778,17 @@ save_call_clobbered_regs (void) for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (referenced_regs, regno)) - regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS, save_mode); + regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS, + save_mode); + /* If a saved register is set after the call, this means we no + longer should restore it. This can happen when parts of a + multi-word pseudo do not conflict with other pseudos, so + IRA may allocate the same hard register for both. One may + be live across the call, while the other is set + afterwards. */ + CLEAR_HARD_REG_SET (this_insn_sets); + note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets); + AND_COMPL_HARD_REG_SET (hard_regs_saved, this_insn_sets); } if (code == CALL_INSN |