diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cse.c | 40 | ||||
-rw-r--r-- | gcc/fwprop.c | 14 |
3 files changed, 38 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 175b85b..b7914b5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2013-02-07 Eric Botcazou <ebotcazou@adacore.com> + + PR rtl-optimization/56178 + * cse.c (cse_insn): Do not create a REG_EQUAL note if the source is a + SUBREG of a register. Tidy up related block of code. + * fwprop.c (forward_propagate_and_simplify): Do not create a REG_EQUAL + note if the source is a register or a SUBREG of a register. + 2013-02-07 Jakub Jelinek <jakub@redhat.com> PR target/56228 @@ -5311,33 +5311,33 @@ cse_insn (rtx insn) } /* If this is a single SET, we are setting a register, and we have an - equivalent constant, we want to add a REG_NOTE. We don't want - to write a REG_EQUAL note for a constant pseudo since verifying that - that pseudo hasn't been eliminated is a pain. Such a note also - won't help anything. + equivalent constant, we want to add a REG_EQUAL note if the constant + is different from the source. We don't want to do it for a constant + pseudo since verifying that this pseudo hasn't been eliminated is a + pain; moreover such a note won't help anything. Avoid a REG_EQUAL note for (CONST (MINUS (LABEL_REF) (LABEL_REF))) which can be created for a reference to a compile time computable entry in a jump table. */ - - if (n_sets == 1 && src_const && REG_P (dest) + if (n_sets == 1 + && REG_P (dest) + && src_const && !REG_P (src_const) - && ! (GET_CODE (src_const) == CONST - && GET_CODE (XEXP (src_const, 0)) == MINUS - && GET_CODE (XEXP (XEXP (src_const, 0), 0)) == LABEL_REF - && GET_CODE (XEXP (XEXP (src_const, 0), 1)) == LABEL_REF)) + && !(GET_CODE (src_const) == SUBREG + && REG_P (SUBREG_REG (src_const))) + && !(GET_CODE (src_const) == CONST + && GET_CODE (XEXP (src_const, 0)) == MINUS + && GET_CODE (XEXP (XEXP (src_const, 0), 0)) == LABEL_REF + && GET_CODE (XEXP (XEXP (src_const, 0), 1)) == LABEL_REF) + && !rtx_equal_p (src, src_const)) { - /* We only want a REG_EQUAL note if src_const != src. */ - if (! rtx_equal_p (src, src_const)) - { - /* Make sure that the rtx is not shared. */ - src_const = copy_rtx (src_const); + /* Make sure that the rtx is not shared. */ + src_const = copy_rtx (src_const); - /* Record the actual constant value in a REG_EQUAL note, - making a new one if one does not already exist. */ - set_unique_reg_note (insn, REG_EQUAL, src_const); - df_notes_rescan (insn); - } + /* Record the actual constant value in a REG_EQUAL note, + making a new one if one does not already exist. */ + set_unique_reg_note (insn, REG_EQUAL, src_const); + df_notes_rescan (insn); } /* Now deal with the destination. */ diff --git a/gcc/fwprop.c b/gcc/fwprop.c index 6a82dea..17cc62a 100644 --- a/gcc/fwprop.c +++ b/gcc/fwprop.c @@ -1316,10 +1316,16 @@ forward_propagate_and_simplify (df_ref use, rtx def_insn, rtx def_set) separately try plugging the definition in the note and simplifying. 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))); + otherwise. We also don't want to install a note if we are merely + propagating a pseudo since verifying that this pseudo isn't dead + is a pain; moreover such a note won't help anything. */ + set_reg_equal = (note == NULL_RTX + && REG_P (SET_DEST (use_set)) + && !REG_P (src) + && !(GET_CODE (src) == SUBREG + && REG_P (SUBREG_REG (src))) + && !reg_mentioned_p (SET_DEST (use_set), + SET_SRC (use_set))); } if (GET_MODE (*loc) == VOIDmode) |