summaryrefslogtreecommitdiff
path: root/gcc/rtlanal.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/rtlanal.c
parent7984457f8295811880c37e7861aa7c0454ce9845 (diff)
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/rtlanal.c')
-rw-r--r--gcc/rtlanal.c17
1 files changed, 5 insertions, 12 deletions
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 560bfd43c1c..beb24ba573c 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -1124,10 +1124,7 @@ reg_referenced_p (const_rtx x, const_rtx body)
&& !REG_P (SET_DEST (body))
&& ! (GET_CODE (SET_DEST (body)) == SUBREG
&& REG_P (SUBREG_REG (SET_DEST (body)))
- && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (body))))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
- == ((GET_MODE_SIZE (GET_MODE (SET_DEST (body)))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
+ && !read_modify_subreg_p (SET_DEST (body)))
&& reg_overlap_mentioned_p (x, SET_DEST (body)))
return 1;
return 0;
@@ -2017,20 +2014,16 @@ dead_or_set_p (const rtx_insn *insn, const_rtx x)
return 1;
}
-/* Return TRUE iff DEST is a register or subreg of a register and
- doesn't change the number of words of the inner register, and any
- part of the register is TEST_REGNO. */
+/* Return TRUE iff DEST is a register or subreg of a register, is a
+ complete rather than read-modify-write destination, and contains
+ register TEST_REGNO. */
static bool
covers_regno_no_parallel_p (const_rtx dest, unsigned int test_regno)
{
unsigned int regno, endregno;
- if (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)))
+ if (GET_CODE (dest) == SUBREG && !read_modify_subreg_p (dest))
dest = SUBREG_REG (dest);
if (!REG_P (dest))