mirror of git://gcc.gnu.org/git/gcc.git
combine.c (try_combine): Prefer to delete dead SETs inside a PARALLEL over keeping them.
* combine.c (try_combine): Prefer to delete dead SETs inside a PARALLEL over keeping them. From-SVN: r217865
This commit is contained in:
parent
43ae6da22f
commit
77486f4480
|
|
@ -1,3 +1,8 @@
|
||||||
|
2014-11-20 Segher Boessenkool <segher@kernel.crashing.org>
|
||||||
|
|
||||||
|
* combine.c (try_combine): Prefer to delete dead SETs inside
|
||||||
|
a PARALLEL over keeping them.
|
||||||
|
|
||||||
2014-11-20 Segher Boessenkool <segher@kernel.crashing.org>
|
2014-11-20 Segher Boessenkool <segher@kernel.crashing.org>
|
||||||
|
|
||||||
* combine.c (combine_validate_cost): Always print the insn costs
|
* combine.c (combine_validate_cost): Always print the insn costs
|
||||||
|
|
|
||||||
|
|
@ -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);
|
RTVEC_ELT (newpat_vec_with_clobbers, i) = XVECEXP (newpat, 0, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is the result of combination a valid instruction? */
|
/* We have recognized nothing yet. */
|
||||||
insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
|
insn_code_number = -1;
|
||||||
|
|
||||||
/* If the result isn't valid, see if it is a PARALLEL of two SETs where
|
/* See if this is a PARALLEL of two SETs where one SET's destination is
|
||||||
the second SET's destination is a register that is unused and isn't
|
a register that is unused and this isn't marked as an instruction that
|
||||||
marked as an instruction that might trap in an EH region. In that case,
|
might trap in an EH region. In that case, we just need the other SET.
|
||||||
we just need the first SET. This can occur when simplifying a divmod
|
We prefer this over the PARALLEL.
|
||||||
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
|
This can occur when simplifying a divmod insn. We *must* test for this
|
||||||
updates the register status.
|
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
|
It's pointless doing this if we originally had two sets, one from
|
||||||
i3, and one from i2. Combining then splitting the parallel results
|
i3, and one from i2. Combining then splitting the parallel results
|
||||||
in the original i2 again plus an invalid insn (which we delete).
|
in the original i2 again plus an invalid insn (which we delete).
|
||||||
The net effect is only to move instructions around, which makes
|
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.
|
if (!(added_sets_2 && i1 == 0)
|
||||||
That would not cause incorrect code, but does cause an unneeded
|
|
||||||
insn to remain. */
|
|
||||||
|
|
||||||
if (insn_code_number < 0
|
|
||||||
&& !(added_sets_2 && i1 == 0)
|
|
||||||
&& GET_CODE (newpat) == PARALLEL
|
&& GET_CODE (newpat) == PARALLEL
|
||||||
&& XVECLEN (newpat, 0) == 2
|
&& XVECLEN (newpat, 0) == 2
|
||||||
&& GET_CODE (XVECEXP (newpat, 0, 0)) == SET
|
&& 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 set0 = XVECEXP (newpat, 0, 0);
|
||||||
rtx set1 = XVECEXP (newpat, 0, 1);
|
rtx set1 = XVECEXP (newpat, 0, 1);
|
||||||
|
rtx oldpat = newpat;
|
||||||
|
|
||||||
if (((REG_P (SET_DEST (set1))
|
if (((REG_P (SET_DEST (set1))
|
||||||
&& find_reg_note (i3, REG_UNUSED, 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)
|
if (insn_code_number >= 0)
|
||||||
changed_i3_dest = 1;
|
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
|
/* 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
|
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
|
insns. There are two ways to do this. It can be split using a
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue