aboutsummaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index 786a840..7f10c67 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -14219,6 +14219,46 @@ distribute_notes (rtx notes, rtx_insn *from_insn, rtx_insn *i3, rtx_insn *i2,
PUT_REG_NOTE_KIND (note, REG_DEAD);
place = i3;
}
+
+ /* A SET or CLOBBER of the REG_UNUSED reg has been removed,
+ but we can't tell which at this point. We must reset any
+ expectations we had about the value that was previously
+ stored in the reg. ??? Ideally, we'd adjust REG_N_SETS
+ and, if appropriate, restore its previous value, but we
+ don't have enough information for that at this point. */
+ else
+ {
+ record_value_for_reg (XEXP (note, 0), NULL, NULL_RTX);
+
+ /* Otherwise, if this register is now referenced in i2
+ then the register used to be modified in one of the
+ original insns. If it was i3 (say, in an unused
+ parallel), it's now completely gone, so the note can
+ be discarded. But if it was modified in i2, i1 or i0
+ and we still reference it in i2, then we're
+ referencing the previous value, and since the
+ register was modified and REG_UNUSED, we know that
+ the previous value is now dead. So, if we only
+ reference the register in i2, we change the note to
+ REG_DEAD, to reflect the previous value. However, if
+ we're also setting or clobbering the register as
+ scratch, we know (because the register was not
+ referenced in i3) that it's unused, just as it was
+ unused before, and we place the note in i2. */
+ if (from_insn != i3 && i2 && INSN_P (i2)
+ && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
+ {
+ if (!reg_set_p (XEXP (note, 0), PATTERN (i2)))
+ PUT_REG_NOTE_KIND (note, REG_DEAD);
+ if (! (REG_P (XEXP (note, 0))
+ ? find_regno_note (i2, REG_NOTE_KIND (note),
+ REGNO (XEXP (note, 0)))
+ : find_reg_note (i2, REG_NOTE_KIND (note),
+ XEXP (note, 0))))
+ place = i2;
+ }
+ }
+
break;
case REG_EQUAL: