Message ID | 4C572979.5020303@t-online.de |
---|---|
State | New |
Headers | show |
On 08/02/10 14:24, Bernd Schmidt wrote: > After the IRA changes to track words separately, the same hard register > may appear to hold more than one live pseudo. This confuses > caller-save.c into turning > > (... reg:DI 18 is used ...) > call somehwere ;; clobber reg:DI 18 > set (reg:SI 19) something else > use (reg:SI 19) > > into > > (... reg:DI 18 is used ...) > save reg:DI 18 > call somehwere ;; clobber reg:DI 18 > set (reg:SI 19) something else > restore REG:SI 19 ;; because the next insn uses it... > use (reg:SI 19) > > Fixed by making it look for stores into regs it thinks it still has to > restore. There's comment elsewhere in caller-save already which > describes a similar problem: > /* Record all registers set in this call insn. These don't > need to be saved. N.B. the call insn might set a subreg > of a multi-hard-reg pseudo; then the pseudo is considered > live during the call, but the subreg that is set > isn't. */ > > For a while I was worried that there might be other places in reload > which could be confused, until I found > /* Similarly, only do this if we can be sure that the death > note is still valid. global can assign some hardreg to > the pseudo referenced in the note and simultaneously a > subword of this hardreg to a different, also live pseudo, > because only another subword of the hardreg is actually > used in the insn. This cannot happen if the pseudo has > been assigned exactly one hardreg. See PR 33732. */ > > and remembered that the IRA change isn't actually a new thing, just a > regression fix for something local-alloc was able to do for a long time. > > Bootstrapped and regression tested on i686-linux; committed. It's been > reported to fix the PA bootstrap problem. OK. jeff
Index: ChangeLog =================================================================== --- ChangeLog (revision 162827) +++ ChangeLog (working copy) @@ -1,3 +1,9 @@ +2010-08-02 Bernd Schmidt <bernds@codesourcery.com> + + PR target/45063 + * caller-save.c (save_call_clobbered_regs): Remove regs from + hard_regs_saved when they are set. + 2010-08-02 Uros Bizjak <ubizjak@gmail.com> PR target/41089 Index: caller-save.c =================================================================== --- caller-save.c (revision 162821) +++ caller-save.c (working copy) @@ -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