optabs.c (add_equal_note): Do not create self-referencing REG_EQUAL notes.
* optabs.c (add_equal_note): Do not create self-referencing REG_EQUAL notes. * fwprop.c (forward_propagate_and_simplify): Likewise. From-SVN: r194054
This commit is contained in:
parent
fa967f341c
commit
853f8f1c1c
3 changed files with 22 additions and 22 deletions
|
@ -1,3 +1,9 @@
|
|||
2012-12-02 Steven Bosscher <steven@gcc.gnu.org>
|
||||
|
||||
* optabs.c (add_equal_note): Do not create self-referencing REG_EQUAL
|
||||
notes.
|
||||
* fwprop.c (forward_propagate_and_simplify): Likewise.
|
||||
|
||||
2012-12-02 Steven Bosscher <steven@gcc.gnu.org>
|
||||
|
||||
* function.h (struct rtl_data): Remove epilogue_delay_list.
|
||||
|
|
|
@ -1315,9 +1315,12 @@ forward_propagate_and_simplify (df_ref use, rtx def_insn, rtx def_set)
|
|||
/* Do not replace an existing REG_EQUAL note if the insn is not
|
||||
recognized. Either we're already replacing in the note, or we'll
|
||||
separately try plugging the definition in the note and simplifying.
|
||||
And only install a REQ_EQUAL note when the destination is a REG,
|
||||
as the note would be invalid otherwise. */
|
||||
set_reg_equal = (note == NULL_RTX && REG_P (SET_DEST (use_set)));
|
||||
And only install a REQ_EQUAL note when the destination is a REG
|
||||
that isn't mentioned in USE_SET, as the note would be invalid
|
||||
otherwise. */
|
||||
set_reg_equal = (note == NULL_RTX && REG_P (SET_DEST (use_set))
|
||||
&& ! reg_mentioned_p (SET_DEST (use_set),
|
||||
SET_SRC (use_set)));
|
||||
}
|
||||
|
||||
if (GET_MODE (*loc) == VOIDmode)
|
||||
|
|
29
gcc/optabs.c
29
gcc/optabs.c
|
@ -170,14 +170,14 @@ optab_libfunc (optab optab, enum machine_mode mode)
|
|||
|
||||
If the last insn does not set TARGET, don't do anything, but return 1.
|
||||
|
||||
If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
|
||||
don't add the REG_EQUAL note but return 0. Our caller can then try
|
||||
again, ensuring that TARGET is not one of the operands. */
|
||||
If the last insn or a previous insn sets TARGET and TARGET is one of OP0
|
||||
or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
|
||||
try again, ensuring that TARGET is not one of the operands. */
|
||||
|
||||
static int
|
||||
add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
|
||||
{
|
||||
rtx last_insn, insn, set;
|
||||
rtx last_insn, set;
|
||||
rtx note;
|
||||
|
||||
gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
|
||||
|
@ -192,6 +192,12 @@ add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
|
|||
if (GET_CODE (target) == ZERO_EXTRACT)
|
||||
return 1;
|
||||
|
||||
/* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
|
||||
a value changing in the insn, so the note would be invalid for CSE. */
|
||||
if (reg_overlap_mentioned_p (target, op0)
|
||||
|| (op1 && reg_overlap_mentioned_p (target, op1)))
|
||||
return 0;
|
||||
|
||||
for (last_insn = insns;
|
||||
NEXT_INSN (last_insn) != NULL_RTX;
|
||||
last_insn = NEXT_INSN (last_insn))
|
||||
|
@ -207,21 +213,6 @@ add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
|
|||
|| ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
|
||||
return 1;
|
||||
|
||||
/* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
|
||||
besides the last insn. */
|
||||
if (reg_overlap_mentioned_p (target, op0)
|
||||
|| (op1 && reg_overlap_mentioned_p (target, op1)))
|
||||
{
|
||||
insn = PREV_INSN (last_insn);
|
||||
while (insn != NULL_RTX)
|
||||
{
|
||||
if (reg_set_p (target, insn))
|
||||
return 0;
|
||||
|
||||
insn = PREV_INSN (insn);
|
||||
}
|
||||
}
|
||||
|
||||
if (GET_RTX_CLASS (code) == RTX_UNARY)
|
||||
switch (code)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue