From 2cafda86f9b27c172bc7c237581d9275b0e0ddfd Mon Sep 17 00:00:00 2001 From: segher Date: Thu, 20 Nov 2014 14:56:29 +0000 Subject: [PATCH] * combine.c (try_combine): Prefer to delete dead SETs inside a PARALLEL over keeping them. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217865 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 5 +++++ gcc/combine.c | 36 ++++++++++++++++++++---------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e8e68179958..4f89b084708 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2014-11-20 Segher Boessenkool + * combine.c (try_combine): Prefer to delete dead SETs inside + a PARALLEL over keeping them. + +2014-11-20 Segher Boessenkool + * combine.c (combine_validate_cost): Always print the insn costs to the dump file. diff --git a/gcc/combine.c b/gcc/combine.c index d2415f8d2fa..1808f9702fb 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -3265,29 +3265,25 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, RTVEC_ELT (newpat_vec_with_clobbers, i) = XVECEXP (newpat, 0, i); } - /* Is the result of combination a valid instruction? */ - insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); + /* We have recognized nothing yet. */ + insn_code_number = -1; + + /* See if this is a PARALLEL of two SETs where one SET's destination is + a register that is unused and this isn't marked as an instruction that + might trap in an EH region. In that case, we just need the other SET. + We prefer this over the PARALLEL. - /* If the result isn't valid, see if it is a PARALLEL of two SETs where - the second SET's destination is a register that is unused and isn't - marked as an instruction that might trap in an EH region. In that case, - we just need the first SET. This can occur when simplifying a divmod - insn. We *must* test for this case here because the code below that - splits two independent SETs doesn't handle this case correctly when it - updates the register status. + This can occur when simplifying a divmod insn. We *must* test for this + case here because the code below that splits two independent SETs doesn't + handle this case correctly when it updates the register status. It's pointless doing this if we originally had two sets, one from i3, and one from i2. Combining then splitting the parallel results in the original i2 again plus an invalid insn (which we delete). The net effect is only to move instructions around, which makes - debug info less accurate. + debug info less accurate. */ - Also check the case where the first SET's destination is unused. - That would not cause incorrect code, but does cause an unneeded - insn to remain. */ - - if (insn_code_number < 0 - && !(added_sets_2 && i1 == 0) + if (!(added_sets_2 && i1 == 0) && GET_CODE (newpat) == PARALLEL && XVECLEN (newpat, 0) == 2 && GET_CODE (XVECEXP (newpat, 0, 0)) == SET @@ -3296,6 +3292,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, { rtx set0 = XVECEXP (newpat, 0, 0); rtx set1 = XVECEXP (newpat, 0, 1); + rtx oldpat = newpat; if (((REG_P (SET_DEST (set1)) && find_reg_note (i3, REG_UNUSED, SET_DEST (set1))) @@ -3322,8 +3319,15 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, if (insn_code_number >= 0) changed_i3_dest = 1; } + + if (insn_code_number < 0) + newpat = oldpat; } + /* Is the result of combination a valid instruction? */ + if (insn_code_number < 0) + insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); + /* If we were combining three insns and the result is a simple SET with no ASM_OPERANDS that wasn't recognized, try to split it into two insns. There are two ways to do this. It can be split using a -- 2.11.4.GIT