aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-08-30 11:18:29 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-08-30 11:18:29 +0000
commit2123a9a50fb35109af6c2ba3bcfd71a1d5432954 (patch)
tree97a0311ec16d63c69c73d255611afe6da1970e0e /gcc
parentd93d3864ca8a8b50de81e084136574021463d228 (diff)
downloadgcc-2123a9a50fb35109af6c2ba3bcfd71a1d5432954.zip
gcc-2123a9a50fb35109af6c2ba3bcfd71a1d5432954.tar.gz
gcc-2123a9a50fb35109af6c2ba3bcfd71a1d5432954.tar.bz2
[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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/combine.c35
2 files changed, 29 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 51f6f37..3fb54e6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -2,6 +2,14 @@
Alan Hayward <alan.hayward@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
that is always either address_mode or pointer_mode.
diff --git a/gcc/combine.c b/gcc/combine.c
index 85a2f50..022a5b5 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -2645,6 +2645,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
rtx other_pat = 0;
rtx new_other_notes;
int i;
+ scalar_int_mode dest_mode, temp_mode;
/* Immediately return if any of I0,I1,I2 are the same insn (I3 can
never be). */
@@ -2847,33 +2848,40 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
constant. */
if (i1 == 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))
&& GET_CODE (PATTERN (i3)) == SET
&& CONST_SCALAR_INT_P (SET_SRC (PATTERN (i3)))
&& reg_subword_p (SET_DEST (PATTERN (i3)), SET_DEST (temp_expr)))
{
rtx dest = SET_DEST (PATTERN (i3));
+ rtx temp_dest = SET_DEST (temp_expr);
int offset = -1;
int width = 0;
-
+
if (GET_CODE (dest) == ZERO_EXTRACT)
{
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));
offset = INTVAL (XEXP (dest, 2));
dest = XEXP (dest, 0);
if (BITS_BIG_ENDIAN)
- offset = GET_MODE_PRECISION (GET_MODE (dest)) - width - offset;
+ offset = GET_MODE_PRECISION (dest_mode) - width - offset;
}
}
else
{
if (GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
- width = GET_MODE_PRECISION (GET_MODE (dest));
- offset = 0;
+ if (is_a <scalar_int_mode> (GET_MODE (dest), &dest_mode))
+ {
+ width = GET_MODE_PRECISION (dest_mode);
+ offset = 0;
+ }
}
if (offset >= 0)
@@ -2882,9 +2890,9 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
if (subreg_lowpart_p (dest))
;
/* Handle the case where inner is twice the size of outer. */
- else if (GET_MODE_PRECISION (GET_MODE (SET_DEST (temp_expr)))
- == 2 * GET_MODE_PRECISION (GET_MODE (dest)))
- offset += GET_MODE_PRECISION (GET_MODE (dest));
+ else if (GET_MODE_PRECISION (temp_mode)
+ == 2 * GET_MODE_PRECISION (dest_mode))
+ offset += GET_MODE_PRECISION (dest_mode);
/* Otherwise give up for now. */
else
offset = -1;
@@ -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 outer = SET_SRC (temp_expr);
- wide_int o
- = wi::insert (rtx_mode_t (outer, GET_MODE (SET_DEST (temp_expr))),
- rtx_mode_t (inner, GET_MODE (dest)),
- offset, width);
+ wide_int o = wi::insert (rtx_mode_t (outer, temp_mode),
+ rtx_mode_t (inner, dest_mode),
+ offset, width);
combine_merges++;
subst_insn = i3;
subst_low_luid = DF_INSN_LUID (i2);
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);
/* Replace the source in I2 with the new constant and make the
resulting insn the new pattern for I3. Then skip to where we
validate the pattern. Everything was set up above. */
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);