Commit 31418d35 by Ian Lance Taylor

Remove REG_DEAD notes when eliminating a set in the reload CSE pass

From-SVN: r13886
parent c7063b9a
...@@ -400,7 +400,7 @@ static void reload_cse_invalidate_mem PROTO((rtx)); ...@@ -400,7 +400,7 @@ static void reload_cse_invalidate_mem PROTO((rtx));
static void reload_cse_invalidate_rtx PROTO((rtx, rtx)); static void reload_cse_invalidate_rtx PROTO((rtx, rtx));
static void reload_cse_regs PROTO((rtx)); static void reload_cse_regs PROTO((rtx));
static int reload_cse_regno_equal_p PROTO((int, rtx, enum machine_mode)); static int reload_cse_regno_equal_p PROTO((int, rtx, enum machine_mode));
static int reload_cse_noop_set_p PROTO((rtx)); static int reload_cse_noop_set_p PROTO((rtx, rtx));
static void reload_cse_simplify_set PROTO((rtx, rtx)); static void reload_cse_simplify_set PROTO((rtx, rtx));
static void reload_cse_check_clobber PROTO((rtx, rtx)); static void reload_cse_check_clobber PROTO((rtx, rtx));
static void reload_cse_record_set PROTO((rtx, rtx)); static void reload_cse_record_set PROTO((rtx, rtx));
...@@ -7844,11 +7844,8 @@ reload_cse_regs (first) ...@@ -7844,11 +7844,8 @@ reload_cse_regs (first)
body = PATTERN (insn); body = PATTERN (insn);
if (GET_CODE (body) == SET) if (GET_CODE (body) == SET)
{ {
if (reload_cse_noop_set_p (body)) if (reload_cse_noop_set_p (body, insn))
{ {
/* If we were preserving death notes, then we would want
to remove any existing death note for the register
being set. */
PUT_CODE (insn, NOTE); PUT_CODE (insn, NOTE);
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
NOTE_SOURCE_FILE (insn) = 0; NOTE_SOURCE_FILE (insn) = 0;
...@@ -7868,13 +7865,10 @@ reload_cse_regs (first) ...@@ -7868,13 +7865,10 @@ reload_cse_regs (first)
the entire PARALLEL. */ the entire PARALLEL. */
for (i = XVECLEN (body, 0) - 1; i >= 0; --i) for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
if (GET_CODE (XVECEXP (body, 0, i)) != SET if (GET_CODE (XVECEXP (body, 0, i)) != SET
|| ! reload_cse_noop_set_p (XVECEXP (body, 0, i))) || ! reload_cse_noop_set_p (XVECEXP (body, 0, i), insn))
break; break;
if (i < 0) if (i < 0)
{ {
/* If we were preserving death notes, then we would want
to remove any existing death notes for the registers
being set. */
PUT_CODE (insn, NOTE); PUT_CODE (insn, NOTE);
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
NOTE_SOURCE_FILE (insn) = 0; NOTE_SOURCE_FILE (insn) = 0;
...@@ -7957,15 +7951,18 @@ reload_cse_regno_equal_p (regno, val, mode) ...@@ -7957,15 +7951,18 @@ reload_cse_regno_equal_p (regno, val, mode)
return 0; return 0;
} }
/* See whether a single SET instruction is a nooop. */ /* See whether a single set is a noop. SET is the set instruction we
are should check, and INSN is the instruction from which it came. */
static int static int
reload_cse_noop_set_p (set) reload_cse_noop_set_p (set, insn)
rtx set; rtx set;
rtx insn;
{ {
rtx src, dest; rtx src, dest;
enum machine_mode dest_mode; enum machine_mode dest_mode;
int dreg, sreg; int dreg, sreg;
int ret;
src = SET_SRC (set); src = SET_SRC (set);
dest = SET_DEST (set); dest = SET_DEST (set);
...@@ -7977,27 +7974,38 @@ reload_cse_noop_set_p (set) ...@@ -7977,27 +7974,38 @@ reload_cse_noop_set_p (set)
dreg = true_regnum (dest); dreg = true_regnum (dest);
sreg = true_regnum (src); sreg = true_regnum (src);
/* Check for setting a register to itself. In this case, we don't
have to worry about REG_DEAD notes. */
if (dreg >= 0 && dreg == sreg)
return 1;
ret = 0;
if (dreg >= 0) if (dreg >= 0)
{ {
/* Check for setting a register to itself. */ /* Check for setting a register to itself. */
if (dreg == sreg) if (dreg == sreg)
return 1; ret = 1;
/* Check for setting a register to a value which we already know /* Check for setting a register to a value which we already know
is in the register. */ is in the register. */
if (reload_cse_regno_equal_p (dreg, src, dest_mode)) else if (reload_cse_regno_equal_p (dreg, src, dest_mode))
return 1; ret = 1;
/* Check for setting a register DREG to another register SREG /* Check for setting a register DREG to another register SREG
where SREG is equal to a value which is already in DREG. */ where SREG is equal to a value which is already in DREG. */
if (sreg >= 0) else if (sreg >= 0)
{ {
rtx x; rtx x;
for (x = reg_values[sreg]; x; x = XEXP (x, 1)) for (x = reg_values[sreg]; x; x = XEXP (x, 1))
{
if (XEXP (x, 0) != 0 if (XEXP (x, 0) != 0
&& reload_cse_regno_equal_p (dreg, XEXP (x, 0), dest_mode)) && reload_cse_regno_equal_p (dreg, XEXP (x, 0), dest_mode))
return 1; {
ret = 1;
break;
}
}
} }
} }
else if (GET_CODE (dest) == MEM) else if (GET_CODE (dest) == MEM)
...@@ -8007,10 +8015,33 @@ reload_cse_noop_set_p (set) ...@@ -8007,10 +8015,33 @@ reload_cse_noop_set_p (set)
if (sreg >= 0 if (sreg >= 0
&& reload_cse_regno_equal_p (sreg, dest, dest_mode) && reload_cse_regno_equal_p (sreg, dest, dest_mode)
&& ! side_effects_p (dest)) && ! side_effects_p (dest))
return 1; ret = 1;
} }
return 0; /* If we can delete this SET, then we need to look for an earlier
REG_DEAD note on DREG, and remove it if it exists. */
if (ret)
{
if (! find_regno_note (insn, REG_UNUSED, dreg))
{
rtx trial;
for (trial = prev_nonnote_insn (insn);
(trial
&& GET_CODE (trial) != CODE_LABEL
&& GET_CODE (trial) != BARRIER);
trial = prev_nonnote_insn (trial))
{
if (find_regno_note (trial, REG_DEAD, dreg))
{
remove_death (dreg, trial);
break;
}
}
}
}
return ret;
} }
/* Try to simplify a single SET instruction. SET is the set pattern. /* Try to simplify a single SET instruction. SET is the set pattern.
...@@ -8065,9 +8096,31 @@ reload_cse_simplify_set (set, insn) ...@@ -8065,9 +8096,31 @@ reload_cse_simplify_set (set, insn)
push_obstacks (&reload_obstack, &reload_obstack); push_obstacks (&reload_obstack, &reload_obstack);
if (validated) if (validated)
{
/* We need to look for an earlier REG_DEAD note on I,
and remove it if it exists. */
if (! find_regno_note (insn, REG_UNUSED, i))
{
rtx trial;
for (trial = prev_nonnote_insn (insn);
(trial
&& GET_CODE (trial) != CODE_LABEL
&& GET_CODE (trial) != BARRIER);
trial = prev_nonnote_insn (trial))
{
if (find_regno_note (trial, REG_DEAD, i))
{
remove_death (i, trial);
break;
}
}
}
return; return;
} }
} }
}
} }
/* These two variables are used to pass information from /* These two variables are used to pass information from
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment