Commit 853f8f1c by Steven Bosscher

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
parent fa967f34
2012-12-02 Steven Bosscher <steven@gcc.gnu.org> 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. * function.h (struct rtl_data): Remove epilogue_delay_list.
* reorg.c (find_end_label): Simplify always-true test. * reorg.c (find_end_label): Simplify always-true test.
(optimize_skip): Likewise. (optimize_skip): Likewise.
...@@ -1315,9 +1315,12 @@ forward_propagate_and_simplify (df_ref use, rtx def_insn, rtx def_set) ...@@ -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 /* 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 recognized. Either we're already replacing in the note, or we'll
separately try plugging the definition in the note and simplifying. separately try plugging the definition in the note and simplifying.
And only install a REQ_EQUAL note when the destination is a REG, And only install a REQ_EQUAL note when the destination is a REG
as the note would be invalid otherwise. */ that isn't mentioned in USE_SET, as the note would be invalid
set_reg_equal = (note == NULL_RTX && REG_P (SET_DEST (use_set))); 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) if (GET_MODE (*loc) == VOIDmode)
......
...@@ -170,14 +170,14 @@ optab_libfunc (optab optab, enum machine_mode mode) ...@@ -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 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, If the last insn or a previous insn sets TARGET and TARGET is one of OP0
don't add the REG_EQUAL note but return 0. Our caller can then try or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
again, ensuring that TARGET is not one of the operands. */ try again, ensuring that TARGET is not one of the operands. */
static int static int
add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1) 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; rtx note;
gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns)); 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) ...@@ -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) if (GET_CODE (target) == ZERO_EXTRACT)
return 1; 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; for (last_insn = insns;
NEXT_INSN (last_insn) != NULL_RTX; NEXT_INSN (last_insn) != NULL_RTX;
last_insn = NEXT_INSN (last_insn)) 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) ...@@ -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))) || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
return 1; 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) if (GET_RTX_CLASS (code) == RTX_UNARY)
switch (code) switch (code)
{ {
......
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