aboutsummaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-10-26 16:12:09 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-10-26 16:12:09 +0000
commit9eaf97d6d7f1511638fb9209b7acf30e8f26a060 (patch)
tree16674acba1f8fe4ba22347b1846ccdecf4c4d541 /gcc/combine.c
parent7984457f8295811880c37e7861aa7c0454ce9845 (diff)
downloadgcc-9eaf97d6d7f1511638fb9209b7acf30e8f26a060.zip
gcc-9eaf97d6d7f1511638fb9209b7acf30e8f26a060.tar.gz
gcc-9eaf97d6d7f1511638fb9209b7acf30e8f26a060.tar.bz2
Make more use of df_read_modify_subreg_p
This patch uses df_read_modify_subreg_p to check whether writing to a subreg would preserve some of the existing contents. This has the effect of putting more emphasis on the REGMODE_NATURAL_SIZE-based definition of whether something can be partially modified, instead of using UNITS_PER_WORD unconditionally. This becomes important for SVE, where UNITS_PER_WORD has no significance for subregs of multi-register LD2/ST2, LD3/ST3 and LD4/ST4 tuples. 2017-10-26 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * caller-save.c (mark_referenced_regs): Use read_modify_subreg_p. * combine.c (find_single_use_1): Likewise. (expand_field_assignment): Likewise. (move_deaths): Likewise. * lra-constraints.c (simplify_operand_subreg): Likewise. (curr_insn_transform): Likewise. * lra.c (collect_non_operand_hard_regs): Likewise. (add_regs_to_insn_regno_info): Likewise. * rtlanal.c (reg_referenced_p): Likewise. (covers_regno_no_parallel_p): Likewise. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r254110
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c19
1 files changed, 5 insertions, 14 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index d71e50f..93adfc1 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -579,10 +579,7 @@ find_single_use_1 (rtx dest, rtx *loc)
&& !REG_P (SET_DEST (x))
&& ! (GET_CODE (SET_DEST (x)) == SUBREG
&& REG_P (SUBREG_REG (SET_DEST (x)))
- && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x))))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
- == ((GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))))
+ && !read_modify_subreg_p (SET_DEST (x))))
break;
return find_single_use_1 (dest, &SET_SRC (x));
@@ -7361,15 +7358,12 @@ expand_field_assignment (const_rtx x)
}
}
- /* A SUBREG between two modes that occupy the same numbers of words
- can be done by moving the SUBREG to the source. */
+ /* If the destination is a subreg that overwrites the whole of the inner
+ register, we can move the subreg to the source. */
else if (GET_CODE (SET_DEST (x)) == SUBREG
/* We need SUBREGs to compute nonzero_bits properly. */
&& nonzero_sign_valid
- && (((GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
- == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x))))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
+ && !read_modify_subreg_p (SET_DEST (x)))
{
x = gen_rtx_SET (SUBREG_REG (SET_DEST (x)),
gen_lowpart
@@ -13993,10 +13987,7 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_luid, rtx_insn *to_insn,
if (GET_CODE (dest) == ZERO_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART
|| (GET_CODE (dest) == SUBREG
- && (((GET_MODE_SIZE (GET_MODE (dest))
- + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
- == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
- + UNITS_PER_WORD - 1) / UNITS_PER_WORD))))
+ && !read_modify_subreg_p (dest)))
{
move_deaths (dest, maybe_kill_insn, from_luid, to_insn, pnotes);
return;