Commit 2123a9a5 by Richard Sandiford Committed by Richard Sandiford

[58/77] Use scalar_int_mode in a try_combine optimisation

This patch uses scalar_int_modes for:

  /* If I2 is setting a pseudo to a constant and I3 is setting some
     sub-part of it to another constant, merge them by making a new
     constant.  */

This was already implicit, but the danger with checking only
CONST_SCALAR_INT_P is that it can include CC values too.

2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* combine.c (try_combine): Use is_a <scalar_int_mode> when
	trying to combine a full-register integer set with a subreg
	integer set.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>

From-SVN: r251510
parent d93d3864
...@@ -2,6 +2,14 @@ ...@@ -2,6 +2,14 @@
Alan Hayward <alan.hayward@arm.com> Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com> David Sherwood <david.sherwood@arm.com>
* combine.c (try_combine): Use is_a <scalar_int_mode> when
trying to combine a full-register integer set with a subreg
integer set.
2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* expr.c (expand_expr_addr_expr): Add a new_tmode local variable * expr.c (expand_expr_addr_expr): Add a new_tmode local variable
that is always either address_mode or pointer_mode. that is always either address_mode or pointer_mode.
......
...@@ -2645,6 +2645,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, ...@@ -2645,6 +2645,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
rtx other_pat = 0; rtx other_pat = 0;
rtx new_other_notes; rtx new_other_notes;
int i; int i;
scalar_int_mode dest_mode, temp_mode;
/* Immediately return if any of I0,I1,I2 are the same insn (I3 can /* Immediately return if any of I0,I1,I2 are the same insn (I3 can
never be). */ never be). */
...@@ -2847,33 +2848,40 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, ...@@ -2847,33 +2848,40 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
constant. */ constant. */
if (i1 == 0 if (i1 == 0
&& (temp_expr = single_set (i2)) != 0 && (temp_expr = single_set (i2)) != 0
&& is_a <scalar_int_mode> (GET_MODE (SET_DEST (temp_expr)), &temp_mode)
&& CONST_SCALAR_INT_P (SET_SRC (temp_expr)) && CONST_SCALAR_INT_P (SET_SRC (temp_expr))
&& GET_CODE (PATTERN (i3)) == SET && GET_CODE (PATTERN (i3)) == SET
&& CONST_SCALAR_INT_P (SET_SRC (PATTERN (i3))) && CONST_SCALAR_INT_P (SET_SRC (PATTERN (i3)))
&& reg_subword_p (SET_DEST (PATTERN (i3)), SET_DEST (temp_expr))) && reg_subword_p (SET_DEST (PATTERN (i3)), SET_DEST (temp_expr)))
{ {
rtx dest = SET_DEST (PATTERN (i3)); rtx dest = SET_DEST (PATTERN (i3));
rtx temp_dest = SET_DEST (temp_expr);
int offset = -1; int offset = -1;
int width = 0; int width = 0;
if (GET_CODE (dest) == ZERO_EXTRACT) if (GET_CODE (dest) == ZERO_EXTRACT)
{ {
if (CONST_INT_P (XEXP (dest, 1)) if (CONST_INT_P (XEXP (dest, 1))
&& CONST_INT_P (XEXP (dest, 2))) && CONST_INT_P (XEXP (dest, 2))
&& is_a <scalar_int_mode> (GET_MODE (XEXP (dest, 0)),
&dest_mode))
{ {
width = INTVAL (XEXP (dest, 1)); width = INTVAL (XEXP (dest, 1));
offset = INTVAL (XEXP (dest, 2)); offset = INTVAL (XEXP (dest, 2));
dest = XEXP (dest, 0); dest = XEXP (dest, 0);
if (BITS_BIG_ENDIAN) if (BITS_BIG_ENDIAN)
offset = GET_MODE_PRECISION (GET_MODE (dest)) - width - offset; offset = GET_MODE_PRECISION (dest_mode) - width - offset;
} }
} }
else else
{ {
if (GET_CODE (dest) == STRICT_LOW_PART) if (GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0); dest = XEXP (dest, 0);
width = GET_MODE_PRECISION (GET_MODE (dest)); if (is_a <scalar_int_mode> (GET_MODE (dest), &dest_mode))
offset = 0; {
width = GET_MODE_PRECISION (dest_mode);
offset = 0;
}
} }
if (offset >= 0) if (offset >= 0)
...@@ -2882,9 +2890,9 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, ...@@ -2882,9 +2890,9 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
if (subreg_lowpart_p (dest)) if (subreg_lowpart_p (dest))
; ;
/* Handle the case where inner is twice the size of outer. */ /* Handle the case where inner is twice the size of outer. */
else if (GET_MODE_PRECISION (GET_MODE (SET_DEST (temp_expr))) else if (GET_MODE_PRECISION (temp_mode)
== 2 * GET_MODE_PRECISION (GET_MODE (dest))) == 2 * GET_MODE_PRECISION (dest_mode))
offset += GET_MODE_PRECISION (GET_MODE (dest)); offset += GET_MODE_PRECISION (dest_mode);
/* Otherwise give up for now. */ /* Otherwise give up for now. */
else else
offset = -1; offset = -1;
...@@ -2895,23 +2903,22 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, ...@@ -2895,23 +2903,22 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
rtx inner = SET_SRC (PATTERN (i3)); rtx inner = SET_SRC (PATTERN (i3));
rtx outer = SET_SRC (temp_expr); rtx outer = SET_SRC (temp_expr);
wide_int o wide_int o = wi::insert (rtx_mode_t (outer, temp_mode),
= wi::insert (rtx_mode_t (outer, GET_MODE (SET_DEST (temp_expr))), rtx_mode_t (inner, dest_mode),
rtx_mode_t (inner, GET_MODE (dest)), offset, width);
offset, width);
combine_merges++; combine_merges++;
subst_insn = i3; subst_insn = i3;
subst_low_luid = DF_INSN_LUID (i2); subst_low_luid = DF_INSN_LUID (i2);
added_sets_2 = added_sets_1 = added_sets_0 = 0; added_sets_2 = added_sets_1 = added_sets_0 = 0;
i2dest = SET_DEST (temp_expr); i2dest = temp_dest;
i2dest_killed = dead_or_set_p (i2, i2dest); i2dest_killed = dead_or_set_p (i2, i2dest);
/* Replace the source in I2 with the new constant and make the /* Replace the source in I2 with the new constant and make the
resulting insn the new pattern for I3. Then skip to where we resulting insn the new pattern for I3. Then skip to where we
validate the pattern. Everything was set up above. */ validate the pattern. Everything was set up above. */
SUBST (SET_SRC (temp_expr), SUBST (SET_SRC (temp_expr),
immed_wide_int_const (o, GET_MODE (SET_DEST (temp_expr)))); immed_wide_int_const (o, temp_mode));
newpat = PATTERN (i2); newpat = PATTERN (i2);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment