aboutsummaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-08-30 15:25:38 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-08-30 15:25:38 +0000
commitbd4288c02b487cc8a9afcfa9c21bfe594a78e26d (patch)
tree9d9683180c8d4eb77c41fbb539c214855b182e6f /gcc/combine.c
parent432ebb1dea041cce8322e78cb394d41970387bae (diff)
downloadgcc-bd4288c02b487cc8a9afcfa9c21bfe594a78e26d.zip
gcc-bd4288c02b487cc8a9afcfa9c21bfe594a78e26d.tar.gz
gcc-bd4288c02b487cc8a9afcfa9c21bfe594a78e26d.tar.bz2
Add a partial_subreg_p predicate
This patch adds a partial_subreg_p predicate to go alongside paradoxical_subreg_p. Like the paradoxical_subreg_p patch, this one replaces some tests that were based on GET_MODE_SIZE rather than GET_MODE_PRECISION. In each case the change should be a no-op or an improvement. The regcprop.c patch prevents some replacements of the 82-bit RFmode with the 80-bit XFmode on ia64. I don't understand the target details here particularly well, but from the way the modes are described in ia64-modes.def, it isn't valid to assume that an XFmode can carry an RFmode payload. A comparison of the testsuite assembly output for one target per CPU showed no other differences. Some of the places changed here are tracking the widest access mode found for a register. The series tries to standardise on: if (partial_subreg_p (widest_seen, new_mode)) widest_seen = new_mode; rather than: if (paradoxical_subreg_p (new_mode, widest_seen)) widest_seen = new_mode; Either would have been OK. 2017-08-30 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * rtl.h (partial_subreg_p): New function. * caller-save.c (save_call_clobbered_regs): Use it. * calls.c (expand_call): Likewise. * combine.c (combinable_i3pat): Likewise. (simplify_set): Likewise. (make_extraction): Likewise. (make_compound_operation_int): Likewise. (gen_lowpart_or_truncate): Likewise. (force_to_mode): Likewise. (make_field_assignment): Likewise. (reg_truncated_to_mode): Likewise. (record_truncated_value): Likewise. (move_deaths): Likewise. * cse.c (record_jump_cond): Likewise. (cse_insn): Likewise. * cselib.c (cselib_lookup_1): Likewise. * expmed.c (extract_bit_field_using_extv): Likewise. * function.c (assign_parm_setup_reg): Likewise. * ifcvt.c (noce_convert_multiple_sets): Likewise. * ira-build.c (create_insn_allocnos): Likewise. * lra-coalesce.c (merge_pseudos): Likewise. * lra-constraints.c (match_reload): Likewise. (simplify_operand_subreg): Likewise. (curr_insn_transform): Likewise. * lra-lives.c (process_bb_lives): Likewise. * lra.c (new_insn_reg): Likewise. (lra_substitute_pseudo): Likewise. * regcprop.c (mode_change_ok): Likewise. (maybe_mode_change): Likewise. (copyprop_hardreg_forward_1): Likewise. * reload.c (push_reload): Likewise. (find_reloads): Likewise. (find_reloads_subreg_address): Likewise. * reload1.c (alter_reg): Likewise. (eliminate_regs_1): Likewise. * simplify-rtx.c (simplify_unary_operation_1): Likewise. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r251536
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c48
1 files changed, 21 insertions, 27 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index bc31280..8605538 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -2224,9 +2224,7 @@ combinable_i3pat (rtx_insn *i3, rtx *loc, rtx i2dest, rtx i1dest, rtx i0dest,
STACK_POINTER_REGNUM, since these are always considered to be
live. Similarly for ARG_POINTER_REGNUM if it is fixed. */
subdest = dest;
- if (GET_CODE (subdest) == SUBREG
- && (GET_MODE_SIZE (GET_MODE (subdest))
- >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (subdest)))))
+ if (GET_CODE (subdest) == SUBREG && !partial_subreg_p (subdest))
subdest = SUBREG_REG (subdest);
if (pi3dest_killed
&& REG_P (subdest)
@@ -6882,10 +6880,8 @@ simplify_set (rtx x)
/* If we have (set (cc0) (subreg ...)), we try to remove the subreg
in SRC. */
if (dest == cc0_rtx
- && GET_CODE (src) == SUBREG
- && subreg_lowpart_p (src)
- && (GET_MODE_PRECISION (GET_MODE (src))
- < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (src)))))
+ && partial_subreg_p (src)
+ && subreg_lowpart_p (src))
{
rtx inner = SUBREG_REG (src);
machine_mode inner_mode = GET_MODE (inner);
@@ -7634,7 +7630,7 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
/* Never narrow an object, since that might not be safe. */
if (mode != VOIDmode
- && GET_MODE_SIZE (extraction_mode) < GET_MODE_SIZE (mode))
+ && partial_subreg_p (extraction_mode, mode))
extraction_mode = mode;
if (!MEM_P (inner))
@@ -7681,7 +7677,7 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
if (wanted_inner_mode != VOIDmode
&& inner_mode != wanted_inner_mode
&& ! pos_rtx
- && GET_MODE_SIZE (wanted_inner_mode) < GET_MODE_SIZE (is_mode)
+ && partial_subreg_p (wanted_inner_mode, is_mode)
&& MEM_P (inner)
&& ! mode_dependent_address_p (XEXP (inner, 0), MEM_ADDR_SPACE (inner))
&& ! MEM_VOLATILE_P (inner))
@@ -8201,7 +8197,7 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr,
to (subreg:QI (lshiftrt:SI (reg:SI) (const_int 7)) 0). */
|| (GET_CODE (inner) == AND
&& CONST_INT_P (XEXP (inner, 1))
- && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (inner))
+ && partial_subreg_p (x)
&& exact_log2 (UINTVAL (XEXP (inner, 1)))
>= GET_MODE_BITSIZE (mode) - 1)))
subreg_code = SET;
@@ -8214,7 +8210,7 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr,
tem = simplified;
if (GET_CODE (tem) != GET_CODE (inner)
- && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (inner))
+ && partial_subreg_p (x)
&& subreg_lowpart_p (x))
{
rtx newer
@@ -8225,8 +8221,9 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr,
if (GET_CODE (newer) != SUBREG)
newer = make_compound_operation (newer, in_code);
- /* force_to_mode can expand compounds. If it just re-expanded the
- compound, use gen_lowpart to convert to the desired mode. */
+ /* force_to_mode can expand compounds. If it just re-expanded
+ the compound, use gen_lowpart to convert to the desired
+ mode. */
if (rtx_equal_p (newer, x)
/* Likewise if it re-expanded the compound only partially.
This happens for SUBREG of ZERO_EXTRACT if they extract
@@ -8468,7 +8465,7 @@ static rtx
gen_lowpart_or_truncate (machine_mode mode, rtx x)
{
if (!CONST_INT_P (x)
- && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x))
+ && partial_subreg_p (mode, GET_MODE (x))
&& !TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (x))
&& !(REG_P (x) && reg_truncated_to_mode (mode, x)))
{
@@ -8523,7 +8520,7 @@ force_to_mode (rtx x, machine_mode mode, unsigned HOST_WIDE_INT mask,
/* It is not valid to do a right-shift in a narrower mode
than the one it came in with. */
if ((code == LSHIFTRT || code == ASHIFTRT)
- && GET_MODE_PRECISION (mode) < GET_MODE_PRECISION (GET_MODE (x)))
+ && partial_subreg_p (mode, GET_MODE (x)))
op_mode = GET_MODE (x);
/* Truncate MASK to fit OP_MODE. */
@@ -8560,8 +8557,7 @@ force_to_mode (rtx x, machine_mode mode, unsigned HOST_WIDE_INT mask,
if the constant masks to zero all the bits the mode doesn't have. */
if (GET_CODE (x) == SUBREG
&& subreg_lowpart_p (x)
- && ((GET_MODE_SIZE (GET_MODE (x))
- < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+ && (partial_subreg_p (x)
|| (0 == (mask
& GET_MODE_MASK (GET_MODE (x))
& ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))))))
@@ -9555,8 +9551,7 @@ make_field_assignment (rtx x)
if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == SUBREG
&& subreg_lowpart_p (XEXP (src, 0))
- && (GET_MODE_SIZE (GET_MODE (XEXP (src, 0)))
- < GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (src, 0)))))
+ && partial_subreg_p (XEXP (src, 0))
&& GET_CODE (SUBREG_REG (XEXP (src, 0))) == ROTATE
&& CONST_INT_P (XEXP (SUBREG_REG (XEXP (src, 0)), 0))
&& INTVAL (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) == -2
@@ -13325,7 +13320,7 @@ reg_truncated_to_mode (machine_mode mode, const_rtx x)
if (truncated == 0
|| rsp->truncation_label < label_tick_ebb_start)
return false;
- if (GET_MODE_SIZE (truncated) <= GET_MODE_SIZE (mode))
+ if (!partial_subreg_p (mode, truncated))
return true;
if (TRULY_NOOP_TRUNCATION_MODES_P (mode, truncated))
return true;
@@ -13348,9 +13343,10 @@ record_truncated_value (rtx x)
machine_mode original_mode = GET_MODE (SUBREG_REG (x));
truncated_mode = GET_MODE (x);
- if (GET_MODE_SIZE (original_mode) <= GET_MODE_SIZE (truncated_mode))
+ if (!partial_subreg_p (truncated_mode, original_mode))
return true;
+ truncated_mode = GET_MODE (x);
if (TRULY_NOOP_TRUNCATION_MODES_P (truncated_mode, original_mode))
return true;
@@ -13366,8 +13362,7 @@ record_truncated_value (rtx x)
rsp = &reg_stat[REGNO (x)];
if (rsp->truncated_to_mode == 0
|| rsp->truncation_label < label_tick_ebb_start
- || (GET_MODE_SIZE (truncated_mode)
- < GET_MODE_SIZE (rsp->truncated_to_mode)))
+ || partial_subreg_p (truncated_mode, rsp->truncated_to_mode))
{
rsp->truncated_to_mode = truncated_mode;
rsp->truncation_label = label_tick;
@@ -13891,8 +13886,7 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_luid, rtx_insn *to_insn,
the remaining registers in place of NOTE. */
if (note != 0 && regno < FIRST_PSEUDO_REGISTER
- && (GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))
- > GET_MODE_SIZE (GET_MODE (x))))
+ && partial_subreg_p (GET_MODE (x), GET_MODE (XEXP (note, 0))))
{
unsigned int deadregno = REGNO (XEXP (note, 0));
unsigned int deadend = END_REGNO (XEXP (note, 0));
@@ -13911,8 +13905,8 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_luid, rtx_insn *to_insn,
their own REG_DEAD notes lying around. */
else if ((note == 0
|| (note != 0
- && (GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))
- < GET_MODE_SIZE (GET_MODE (x)))))
+ && partial_subreg_p (GET_MODE (XEXP (note, 0)),
+ GET_MODE (x))))
&& regno < FIRST_PSEUDO_REGISTER
&& REG_NREGS (x) > 1)
{