aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8/gcc/regcprop.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.8/gcc/regcprop.c')
-rw-r--r--gcc-4.8/gcc/regcprop.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/gcc-4.8/gcc/regcprop.c b/gcc-4.8/gcc/regcprop.c
index 896902f30..8bfb64e40 100644
--- a/gcc-4.8/gcc/regcprop.c
+++ b/gcc-4.8/gcc/regcprop.c
@@ -747,6 +747,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
int n_ops, i, alt, predicated;
bool is_asm, any_replacements;
rtx set;
+ rtx link;
bool replaced[MAX_RECOG_OPERANDS];
bool changed = false;
struct kill_set_value_data ksvd;
@@ -815,6 +816,23 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
if (recog_op_alt[i][alt].earlyclobber)
kill_value (recog_data.operand[i], vd);
+ /* If we have dead sets in the insn, then we need to note these as we
+ would clobbers. */
+ for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
+ {
+ if (REG_NOTE_KIND (link) == REG_UNUSED)
+ {
+ kill_value (XEXP (link, 0), vd);
+ /* Furthermore, if the insn looked like a single-set,
+ but the dead store kills the source value of that
+ set, then we can no-longer use the plain move
+ special case below. */
+ if (set
+ && reg_overlap_mentioned_p (XEXP (link, 0), SET_SRC (set)))
+ set = NULL;
+ }
+ }
+
/* Special-case plain move instructions, since we may well
be able to do the move from a different register class. */
if (set && REG_P (SET_SRC (set)))