summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2012-12-02 15:46:26 +0000
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2012-12-02 15:46:26 +0000
commit44433d3b0feeabc2871f72d1edba81522eeb8c48 (patch)
tree413cf367e7b936822c65e09dddbfcca70f28aceb /gcc
parentd052c312c5545c50dee633d0d2a2436ea4e7af21 (diff)
downloadgcc-44433d3b0feeabc2871f72d1edba81522eeb8c48.tar.gz
* optabs.c (add_equal_note): Do not create self-referencing REG_EQUAL
notes. * fwprop.c (forward_propagate_and_simplify): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194054 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/fwprop.c9
-rw-r--r--gcc/optabs.c29
3 files changed, 22 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4b6c703b848..bada8f2acd1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
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.
* reorg.c (find_end_label): Simplify always-true test.
(optimize_skip): Likewise.
diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index 0f2ee49ac14..35c82d7ed7f 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -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)
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 353727f3324..d59a1eae3c1 100644
--- a/gcc/optabs.c
+++ b/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)
{