Undo multi-word optional reloads correctly
Unlike e.g. remove_inheritance_pseudos, undo_optional_reloads didn't deal with subregs, so instead of removing multi-word moves, it replaced the reload pseudo with the original pseudo. Besides the redundant move, that retained the clobber of the dest, that starts a multi-word move. After the remap, the sequence that should have become a no-op move starts by clobbering the original pseudo and then moving its pieces onto themselves. The problem is the clobber: it makes earlier sets of the original pseudo to be regarded as dead: if the optional reload sequence was an output reload, the insn for which the output reload was attempted may be regarded as dead and deleted. I've arranged for undo_optional_reloads to accept SUBREGs and use get_regno, like remove_inheritance_pseudo, adjusted its insn-removal loop to tolerate iterating over a removed clobber, and added logic to catch any left-over reload clobbers that could trigger the problem. for gcc/ChangeLog * lra-constraints.cc (undo_optional_reloads): Recognize and drop insns of multi-word move sequences, tolerate removal iteration on an already-removed clobber, and refuse to substitute original pseudos into clobbers.
This commit is contained in:
parent
dbaabd06aa
commit
12f8dc0b64
1 changed files with 24 additions and 13 deletions
|
@ -7261,15 +7261,17 @@ undo_optional_reloads (void)
|
|||
continue;
|
||||
src = SET_SRC (set);
|
||||
dest = SET_DEST (set);
|
||||
if (! REG_P (src) || ! REG_P (dest))
|
||||
if ((! REG_P (src) && ! SUBREG_P (src))
|
||||
|| (! REG_P (dest) && ! SUBREG_P (dest)))
|
||||
continue;
|
||||
if (REGNO (dest) == regno
|
||||
if (get_regno (dest) == (int) regno
|
||||
/* Ignore insn for optional reloads itself. */
|
||||
&& REGNO (lra_reg_info[regno].restore_rtx) != REGNO (src)
|
||||
&& (get_regno (lra_reg_info[regno].restore_rtx)
|
||||
!= get_regno (src))
|
||||
/* Check only inheritance on last inheritance pass. */
|
||||
&& (int) REGNO (src) >= new_regno_start
|
||||
&& get_regno (src) >= new_regno_start
|
||||
/* Check that the optional reload was inherited. */
|
||||
&& bitmap_bit_p (&lra_inheritance_pseudos, REGNO (src)))
|
||||
&& bitmap_bit_p (&lra_inheritance_pseudos, get_regno (src)))
|
||||
{
|
||||
keep_p = true;
|
||||
break;
|
||||
|
@ -7291,18 +7293,22 @@ undo_optional_reloads (void)
|
|||
bitmap_copy (insn_bitmap, &lra_reg_info[regno].insn_bitmap);
|
||||
EXECUTE_IF_SET_IN_BITMAP (insn_bitmap, 0, uid, bi2)
|
||||
{
|
||||
/* We may have already removed a clobber. */
|
||||
if (!lra_insn_recog_data[uid])
|
||||
continue;
|
||||
insn = lra_insn_recog_data[uid]->insn;
|
||||
if ((set = single_set (insn)) != NULL_RTX)
|
||||
{
|
||||
src = SET_SRC (set);
|
||||
dest = SET_DEST (set);
|
||||
if (REG_P (src) && REG_P (dest)
|
||||
&& ((REGNO (src) == regno
|
||||
&& (REGNO (lra_reg_info[regno].restore_rtx)
|
||||
== REGNO (dest)))
|
||||
|| (REGNO (dest) == regno
|
||||
&& (REGNO (lra_reg_info[regno].restore_rtx)
|
||||
== REGNO (src)))))
|
||||
if ((REG_P (src) || SUBREG_P (src))
|
||||
&& (REG_P (dest) || SUBREG_P (dest))
|
||||
&& ((get_regno (src) == (int) regno
|
||||
&& (get_regno (lra_reg_info[regno].restore_rtx)
|
||||
== get_regno (dest)))
|
||||
|| (get_regno (dest) == (int) regno
|
||||
&& (get_regno (lra_reg_info[regno].restore_rtx)
|
||||
== get_regno (src)))))
|
||||
{
|
||||
if (lra_dump_file != NULL)
|
||||
{
|
||||
|
@ -7310,7 +7316,7 @@ undo_optional_reloads (void)
|
|||
INSN_UID (insn));
|
||||
dump_insn_slim (lra_dump_file, insn);
|
||||
}
|
||||
delete_move_and_clobber (insn, REGNO (dest));
|
||||
delete_move_and_clobber (insn, get_regno (dest));
|
||||
continue;
|
||||
}
|
||||
/* We should not worry about generation memory-memory
|
||||
|
@ -7319,6 +7325,11 @@ undo_optional_reloads (void)
|
|||
we remove the inheritance pseudo and the optional
|
||||
reload. */
|
||||
}
|
||||
if (GET_CODE (PATTERN (insn)) == CLOBBER
|
||||
&& REG_P (SET_DEST (insn))
|
||||
&& get_regno (SET_DEST (insn)) == (int) regno)
|
||||
/* Refuse to remap clobbers to preexisting pseudos. */
|
||||
gcc_unreachable ();
|
||||
lra_substitute_pseudo_within_insn
|
||||
(insn, regno, lra_reg_info[regno].restore_rtx, false);
|
||||
lra_update_insn_regno_info (insn);
|
||||
|
|
Loading…
Add table
Reference in a new issue