diff options
author | Steven Bosscher <steven@gcc.gnu.org> | 2012-12-02 15:46:26 +0000 |
---|---|---|
committer | Steven Bosscher <steven@gcc.gnu.org> | 2012-12-02 15:46:26 +0000 |
commit | 853f8f1c1ced73b423dc1b56c81f4e78c6e5f734 (patch) | |
tree | 413cf367e7b936822c65e09dddbfcca70f28aceb | |
parent | fa967f341ce38053b0baf106454139e29786d061 (diff) | |
download | gcc-853f8f1c1ced73b423dc1b56c81f4e78c6e5f734.zip gcc-853f8f1c1ced73b423dc1b56c81f4e78c6e5f734.tar.gz gcc-853f8f1c1ced73b423dc1b56c81f4e78c6e5f734.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fwprop.c | 9 | ||||
-rw-r--r-- | gcc/optabs.c | 29 |
3 files changed, 22 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4b6c703..bada8f2 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 0f2ee49..35c82d7 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 353727f..d59a1ea 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) { |