diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-10-26 16:12:09 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-10-26 16:12:09 +0000 |
commit | 9eaf97d6d7f1511638fb9209b7acf30e8f26a060 (patch) | |
tree | 16674acba1f8fe4ba22347b1846ccdecf4c4d541 /gcc/rtlanal.c | |
parent | 7984457f8295811880c37e7861aa7c0454ce9845 (diff) | |
download | gcc-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/rtlanal.c')
-rw-r--r-- | gcc/rtlanal.c | 17 |
1 files changed, 5 insertions, 12 deletions
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 560bfd4..beb24ba 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)) |