mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-24 12:41:09 +08:00
Make more use of paradoxical_subreg_p
This patch makes more use of the existing paradoxical_subreg_p predicate and also adds a version that operates on outer and inner modes. Some of the affected tests were based on GET_MODE_SIZE rather than GET_MODE_PRECISION and so the patch could change the result for modes that have the same size but different precisions. I think in each case the change should be a no-op or more correct, since a mode with precision N bits can't be expected to hold all of a mode with precision M>N bits. The patch changes the branch taken in simplify_subreg for modes with equal precision, but the new form matches the commentary more closely. Both branches should be equally good in that situation. 2017-08-22 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * rtl.h (paradoxical_subreg_p): Define inline, and add a version that takes the outer and inner modes. * doc/rtl.texi: Use paradoxical_subreg_p instead of a GET_MODE_SIZE comparison as the canonical test for a paradoxical subreg. * combine.c (simplify_set): Use paradoxical_subreg_p. (make_extraction): Likewise. (force_to_mode): Likewise. (rtx_equal_for_field_assignment_p): Likewise. (gen_lowpart_for_combine): Likewise. (simplify_comparison): Likewise. * cse.c (equiv_constant): Likewise. * expmed.c (store_bit_field_1): Likewise. * final.c (alter_subreg): Likewise. * fwprop.c (propagate_rtx): Likewise. (forward_propagate_subreg): Likewise. * ira-conflicts.c (ira_build_conflicts): Likewise. * lower-subreg.c (simplify_gen_subreg_concatn): Likewise. * lra-constraints.c (curr_insn_transform): Likewise. (split_reg): Likewise. * lra-eliminations.c (move_plus_up): Likewise. (lra_eliminate_regs_1): Likewise. * recog.c (general_operand): Likewise. * ree.c (combine_reaching_defs): Likewise. * reload.c (push_reload): Likewise. (find_reloads): Likewise. * reload1.c (elimination_effects): Likewise. (compute_reload_subreg_offset): Likewise. (choose_reload_regs): Likewise. * rtlanal.c (subreg_lsb_1): Likewise. * simplify-rtx.c (simplify_unary_operation_1): Likewise. (simplify_subreg): Likewise. * var-tracking.c (track_loc_p): Likewise. * emit-rtl.c (byte_lowpart_offset): Likewise. (paradoxical_subreg_p): Delete out-of-line definition. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r251282
This commit is contained in:
parent
5b37159fca
commit
03a9562184
@ -1,3 +1,42 @@
|
||||
2017-08-22 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
Alan Hayward <alan.hayward@arm.com>
|
||||
David Sherwood <david.sherwood@arm.com>
|
||||
|
||||
* rtl.h (paradoxical_subreg_p): Define inline, and add a version
|
||||
that takes the outer and inner modes.
|
||||
* doc/rtl.texi: Use paradoxical_subreg_p instead of a GET_MODE_SIZE
|
||||
comparison as the canonical test for a paradoxical subreg.
|
||||
* combine.c (simplify_set): Use paradoxical_subreg_p.
|
||||
(make_extraction): Likewise.
|
||||
(force_to_mode): Likewise.
|
||||
(rtx_equal_for_field_assignment_p): Likewise.
|
||||
(gen_lowpart_for_combine): Likewise.
|
||||
(simplify_comparison): Likewise.
|
||||
* cse.c (equiv_constant): Likewise.
|
||||
* expmed.c (store_bit_field_1): Likewise.
|
||||
* final.c (alter_subreg): Likewise.
|
||||
* fwprop.c (propagate_rtx): Likewise.
|
||||
(forward_propagate_subreg): Likewise.
|
||||
* ira-conflicts.c (ira_build_conflicts): Likewise.
|
||||
* lower-subreg.c (simplify_gen_subreg_concatn): Likewise.
|
||||
* lra-constraints.c (curr_insn_transform): Likewise.
|
||||
(split_reg): Likewise.
|
||||
* lra-eliminations.c (move_plus_up): Likewise.
|
||||
(lra_eliminate_regs_1): Likewise.
|
||||
* recog.c (general_operand): Likewise.
|
||||
* ree.c (combine_reaching_defs): Likewise.
|
||||
* reload.c (push_reload): Likewise.
|
||||
(find_reloads): Likewise.
|
||||
* reload1.c (elimination_effects): Likewise.
|
||||
(compute_reload_subreg_offset): Likewise.
|
||||
(choose_reload_regs): Likewise.
|
||||
* rtlanal.c (subreg_lsb_1): Likewise.
|
||||
* simplify-rtx.c (simplify_unary_operation_1): Likewise.
|
||||
(simplify_subreg): Likewise.
|
||||
* var-tracking.c (track_loc_p): Likewise.
|
||||
* emit-rtl.c (byte_lowpart_offset): Likewise.
|
||||
(paradoxical_subreg_p): Delete out-of-line definition.
|
||||
|
||||
2017-08-22 Jeff Law <law@redhat.com>
|
||||
|
||||
PR tree-optimization/81741
|
||||
|
@ -6809,9 +6809,7 @@ simplify_set (rtx x)
|
||||
/ UNITS_PER_WORD)
|
||||
== ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))
|
||||
+ (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
|
||||
&& (WORD_REGISTER_OPERATIONS
|
||||
|| (GET_MODE_SIZE (GET_MODE (src))
|
||||
<= GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))))
|
||||
&& (WORD_REGISTER_OPERATIONS || !paradoxical_subreg_p (src))
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
&& ! (REG_P (dest) && REGNO (dest) < FIRST_PSEUDO_REGISTER
|
||||
&& REG_CANNOT_CHANGE_MODE_P (REGNO (dest),
|
||||
@ -7456,7 +7454,7 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
|
||||
: BITS_PER_UNIT)) == 0
|
||||
/* We can't do this if we are widening INNER_MODE (it
|
||||
may not be aligned, for one thing). */
|
||||
&& GET_MODE_PRECISION (inner_mode) >= GET_MODE_PRECISION (tmode)
|
||||
&& !paradoxical_subreg_p (tmode, inner_mode)
|
||||
&& (inner_mode == tmode
|
||||
|| (! mode_dependent_address_p (XEXP (inner, 0),
|
||||
MEM_ADDR_SPACE (inner))
|
||||
@ -7669,7 +7667,7 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
|
||||
/* If bytes are big endian and we had a paradoxical SUBREG, we must
|
||||
adjust OFFSET to compensate. */
|
||||
if (BYTES_BIG_ENDIAN
|
||||
&& GET_MODE_SIZE (inner_mode) < GET_MODE_SIZE (is_mode))
|
||||
&& paradoxical_subreg_p (is_mode, inner_mode))
|
||||
offset -= GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (inner_mode);
|
||||
|
||||
/* We can now move to the desired byte. */
|
||||
@ -8529,7 +8527,7 @@ force_to_mode (rtx x, machine_mode mode, unsigned HOST_WIDE_INT mask,
|
||||
|
||||
/* If X is narrower than MODE and we want all the bits in X's mode, just
|
||||
get X in the proper mode. */
|
||||
if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode)
|
||||
if (paradoxical_subreg_p (mode, GET_MODE (x))
|
||||
&& (GET_MODE_MASK (GET_MODE (x)) & ~mask) == 0)
|
||||
return gen_lowpart (mode, x);
|
||||
|
||||
@ -9408,7 +9406,7 @@ rtx_equal_for_field_assignment_p (rtx x, rtx y, bool widen_x)
|
||||
{
|
||||
if (widen_x && GET_MODE (x) != GET_MODE (y))
|
||||
{
|
||||
if (GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (y)))
|
||||
if (paradoxical_subreg_p (GET_MODE (x), GET_MODE (y)))
|
||||
return 0;
|
||||
if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
|
||||
return 0;
|
||||
@ -11488,7 +11486,7 @@ gen_lowpart_for_combine (machine_mode omode, rtx x)
|
||||
/* If we want to refer to something bigger than the original memref,
|
||||
generate a paradoxical subreg instead. That will force a reload
|
||||
of the original memref X. */
|
||||
if (isize < osize)
|
||||
if (paradoxical_subreg_p (omode, imode))
|
||||
return gen_rtx_SUBREG (omode, x, 0);
|
||||
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
@ -12145,8 +12143,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
|
||||
|
||||
/* If the inner mode is narrower and we are extracting the low part,
|
||||
we can treat the SUBREG as if it were a ZERO_EXTEND. */
|
||||
if (subreg_lowpart_p (op0)
|
||||
&& GET_MODE_PRECISION (GET_MODE (SUBREG_REG (op0))) < mode_width)
|
||||
if (paradoxical_subreg_p (op0))
|
||||
;
|
||||
else if (subreg_lowpart_p (op0)
|
||||
&& GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
|
||||
|
@ -3802,7 +3802,7 @@ equiv_constant (rtx x)
|
||||
the subreg. Note that the upper bits of paradoxical subregs
|
||||
are undefined, so they cannot be said to equal anything. */
|
||||
if (REG_P (SUBREG_REG (x))
|
||||
&& GET_MODE_SIZE (mode) <= GET_MODE_SIZE (imode)
|
||||
&& !paradoxical_subreg_p (x)
|
||||
&& (new_rtx = equiv_constant (SUBREG_REG (x))) != 0)
|
||||
return simplify_subreg (mode, new_rtx, imode, SUBREG_BYTE (x));
|
||||
|
||||
|
@ -1872,7 +1872,7 @@ expression is called @dfn{paradoxical}. The canonical test for this
|
||||
class of @code{subreg} is:
|
||||
|
||||
@smallexample
|
||||
GET_MODE_SIZE (@var{m1}) > GET_MODE_SIZE (@var{m2})
|
||||
paradoxical_subreg_p (@var{m1}, @var{m2})
|
||||
@end smallexample
|
||||
|
||||
Paradoxical @code{subreg}s can be used as both lvalues and rvalues.
|
||||
|
@ -1008,10 +1008,10 @@ int
|
||||
byte_lowpart_offset (machine_mode outer_mode,
|
||||
machine_mode inner_mode)
|
||||
{
|
||||
if (GET_MODE_SIZE (outer_mode) < GET_MODE_SIZE (inner_mode))
|
||||
return subreg_lowpart_offset (outer_mode, inner_mode);
|
||||
else
|
||||
if (paradoxical_subreg_p (outer_mode, inner_mode))
|
||||
return -subreg_lowpart_offset (inner_mode, outer_mode);
|
||||
else
|
||||
return subreg_lowpart_offset (outer_mode, inner_mode);
|
||||
}
|
||||
|
||||
/* Generate a REG rtx for a new pseudo register of mode MODE.
|
||||
@ -1552,16 +1552,6 @@ subreg_lowpart_p (const_rtx x)
|
||||
return (subreg_lowpart_offset (GET_MODE (x), GET_MODE (SUBREG_REG (x)))
|
||||
== SUBREG_BYTE (x));
|
||||
}
|
||||
|
||||
/* Return true if X is a paradoxical subreg, false otherwise. */
|
||||
bool
|
||||
paradoxical_subreg_p (const_rtx x)
|
||||
{
|
||||
if (GET_CODE (x) != SUBREG)
|
||||
return false;
|
||||
return (GET_MODE_PRECISION (GET_MODE (x))
|
||||
> GET_MODE_PRECISION (GET_MODE (SUBREG_REG (x))));
|
||||
}
|
||||
|
||||
/* Return subword OFFSET of operand OP.
|
||||
The word number, OFFSET, is interpreted as the word number starting
|
||||
|
@ -736,7 +736,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
|
||||
int byte_offset = 0;
|
||||
|
||||
/* Paradoxical subregs need special handling on big-endian machines. */
|
||||
if (SUBREG_BYTE (op0) == 0 && inner_mode_size < outer_mode_size)
|
||||
if (paradoxical_subreg_p (op0))
|
||||
{
|
||||
int difference = inner_mode_size - outer_mode_size;
|
||||
|
||||
|
@ -3204,8 +3204,7 @@ alter_subreg (rtx *xp, bool final_p)
|
||||
|
||||
/* For paradoxical subregs on big-endian machines, SUBREG_BYTE
|
||||
contains 0 instead of the proper offset. See simplify_subreg. */
|
||||
if (offset == 0
|
||||
&& GET_MODE_SIZE (GET_MODE (y)) < GET_MODE_SIZE (GET_MODE (x)))
|
||||
if (paradoxical_subreg_p (x))
|
||||
{
|
||||
int difference = GET_MODE_SIZE (GET_MODE (y))
|
||||
- GET_MODE_SIZE (GET_MODE (x));
|
||||
|
@ -680,8 +680,7 @@ propagate_rtx (rtx x, machine_mode mode, rtx old_rtx, rtx new_rtx,
|
||||
|| CONSTANT_P (new_rtx)
|
||||
|| (GET_CODE (new_rtx) == SUBREG
|
||||
&& REG_P (SUBREG_REG (new_rtx))
|
||||
&& (GET_MODE_SIZE (mode)
|
||||
<= GET_MODE_SIZE (GET_MODE (SUBREG_REG (new_rtx))))))
|
||||
&& !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (new_rtx)))))
|
||||
flags |= PR_CAN_APPEAR;
|
||||
if (!varying_mem_p (new_rtx))
|
||||
flags |= PR_HANDLE_MEM;
|
||||
@ -1103,9 +1102,7 @@ forward_propagate_subreg (df_ref use, rtx_insn *def_insn, rtx def_set)
|
||||
|| !REG_P (SET_DEST (def_set)))
|
||||
return false;
|
||||
|
||||
/* If this is a paradoxical SUBREG... */
|
||||
if (GET_MODE_SIZE (use_mode)
|
||||
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (use_reg))))
|
||||
if (paradoxical_subreg_p (use_reg))
|
||||
{
|
||||
/* If this is a paradoxical SUBREG, we have no idea what value the
|
||||
extra bits would have. However, if the operand is equivalent to
|
||||
|
@ -775,7 +775,7 @@ ira_build_conflicts (void)
|
||||
cannot be accessed in the widest mode. */
|
||||
machine_mode outer_mode = ALLOCNO_WMODE (a);
|
||||
machine_mode inner_mode = ALLOCNO_MODE (a);
|
||||
if (GET_MODE_SIZE (outer_mode) > GET_MODE_SIZE (inner_mode))
|
||||
if (paradoxical_subreg_p (outer_mode, inner_mode))
|
||||
{
|
||||
enum reg_class aclass = ALLOCNO_CLASS (a);
|
||||
for (int j = ira_class_hard_regs_num[aclass] - 1; j >= 0; --j)
|
||||
|
@ -661,10 +661,8 @@ simplify_gen_subreg_concatn (machine_mode outermode, rtx op,
|
||||
if (op2 == NULL_RTX)
|
||||
{
|
||||
/* We don't handle paradoxical subregs here. */
|
||||
gcc_assert (GET_MODE_SIZE (outermode)
|
||||
<= GET_MODE_SIZE (GET_MODE (op)));
|
||||
gcc_assert (GET_MODE_SIZE (GET_MODE (op))
|
||||
<= GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))));
|
||||
gcc_assert (!paradoxical_subreg_p (outermode, GET_MODE (op)));
|
||||
gcc_assert (!paradoxical_subreg_p (op));
|
||||
op2 = simplify_subreg_concatn (outermode, SUBREG_REG (op),
|
||||
byte + SUBREG_BYTE (op));
|
||||
gcc_assert (op2 != NULL_RTX);
|
||||
@ -685,10 +683,7 @@ simplify_gen_subreg_concatn (machine_mode outermode, rtx op,
|
||||
resolve_simple_move will ask for the high part of the paradoxical
|
||||
subreg, which does not have a value. Just return a zero. */
|
||||
if (ret == NULL_RTX
|
||||
&& GET_CODE (op) == SUBREG
|
||||
&& SUBREG_BYTE (op) == 0
|
||||
&& (GET_MODE_SIZE (innermode)
|
||||
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))))
|
||||
&& paradoxical_subreg_p (op))
|
||||
return CONST0_RTX (outermode);
|
||||
|
||||
gcc_assert (ret != NULL_RTX);
|
||||
|
@ -4225,8 +4225,7 @@ curr_insn_transform (bool check_only_p)
|
||||
/* Strict_low_part requires reload the register not
|
||||
the sub-register. */
|
||||
&& (curr_static_id->operand[i].strict_low
|
||||
|| (GET_MODE_SIZE (mode)
|
||||
<= GET_MODE_SIZE (GET_MODE (reg))
|
||||
|| (!paradoxical_subreg_p (mode, GET_MODE (reg))
|
||||
&& (hard_regno
|
||||
= get_try_hard_regno (REGNO (reg))) >= 0
|
||||
&& (simplify_subreg_regno
|
||||
@ -5465,7 +5464,7 @@ split_reg (bool before_p, int original_regno, rtx_insn *insn,
|
||||
mode was larger than a register, just use the reg_rtx. Otherwise,
|
||||
limit the size to that of the biggest access in the function. */
|
||||
if (mode == VOIDmode
|
||||
|| GET_MODE_SIZE (mode) > GET_MODE_SIZE (reg_rtx_mode))
|
||||
|| paradoxical_subreg_p (mode, reg_rtx_mode))
|
||||
{
|
||||
original_reg = regno_reg_rtx[hard_regno];
|
||||
mode = reg_rtx_mode;
|
||||
|
@ -286,8 +286,8 @@ move_plus_up (rtx x)
|
||||
subreg_reg = SUBREG_REG (x);
|
||||
x_mode = GET_MODE (x);
|
||||
subreg_reg_mode = GET_MODE (subreg_reg);
|
||||
if (GET_CODE (x) == SUBREG && GET_CODE (subreg_reg) == PLUS
|
||||
&& GET_MODE_SIZE (x_mode) <= GET_MODE_SIZE (subreg_reg_mode)
|
||||
if (!paradoxical_subreg_p (x)
|
||||
&& GET_CODE (subreg_reg) == PLUS
|
||||
&& CONSTANT_P (XEXP (subreg_reg, 1))
|
||||
&& GET_MODE_CLASS (x_mode) == MODE_INT
|
||||
&& GET_MODE_CLASS (subreg_reg_mode) == MODE_INT)
|
||||
@ -605,10 +605,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
|
||||
|
||||
if (new_rtx != SUBREG_REG (x))
|
||||
{
|
||||
int x_size = GET_MODE_SIZE (GET_MODE (x));
|
||||
int new_size = GET_MODE_SIZE (GET_MODE (new_rtx));
|
||||
|
||||
if (MEM_P (new_rtx) && x_size <= new_size)
|
||||
if (MEM_P (new_rtx) && !paradoxical_subreg_p (x))
|
||||
{
|
||||
SUBREG_REG (x) = new_rtx;
|
||||
alter_subreg (&x, false);
|
||||
|
@ -1002,7 +1002,7 @@ general_operand (rtx op, machine_mode mode)
|
||||
However, we must allow them after reload so that they can
|
||||
get cleaned up by cleanup_subreg_operands. */
|
||||
if (!reload_completed && MEM_P (sub)
|
||||
&& GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (sub)))
|
||||
&& paradoxical_subreg_p (op))
|
||||
return 0;
|
||||
#endif
|
||||
/* Avoid memories with nonzero SUBREG_BYTE, as offsetting the memory
|
||||
@ -1037,7 +1037,7 @@ general_operand (rtx op, machine_mode mode)
|
||||
size of floating point mode can be less than the integer
|
||||
mode. */
|
||||
&& ! lra_in_progress
|
||||
&& GET_MODE_SIZE (GET_MODE (op)) > GET_MODE_SIZE (GET_MODE (sub)))
|
||||
&& paradoxical_subreg_p (op))
|
||||
return 0;
|
||||
|
||||
op = sub;
|
||||
|
@ -869,7 +869,8 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
|
||||
return false;
|
||||
|
||||
for (df_link *use = uses; use; use = use->next)
|
||||
if (GET_MODE_PRECISION (GET_MODE (*DF_REF_LOC (use->ref))) > prec)
|
||||
if (paradoxical_subreg_p (GET_MODE (*DF_REF_LOC (use->ref)),
|
||||
GET_MODE (SET_DEST (*dest_sub_rtx))))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
20
gcc/reload.c
20
gcc/reload.c
@ -1062,13 +1062,12 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
|
||||
|| (((REG_P (SUBREG_REG (in))
|
||||
&& REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
|
||||
|| MEM_P (SUBREG_REG (in)))
|
||||
&& ((GET_MODE_PRECISION (inmode)
|
||||
> GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
|
||||
&& (paradoxical_subreg_p (inmode, GET_MODE (SUBREG_REG (in)))
|
||||
|| (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
|
||||
&& (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
|
||||
<= UNITS_PER_WORD)
|
||||
&& (GET_MODE_PRECISION (inmode)
|
||||
> GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
|
||||
&& paradoxical_subreg_p (inmode,
|
||||
GET_MODE (SUBREG_REG (in)))
|
||||
&& INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
|
||||
&& LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != UNKNOWN)
|
||||
|| (WORD_REGISTER_OPERATIONS
|
||||
@ -1170,8 +1169,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
|
||||
|| (((REG_P (SUBREG_REG (out))
|
||||
&& REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
|
||||
|| MEM_P (SUBREG_REG (out)))
|
||||
&& ((GET_MODE_PRECISION (outmode)
|
||||
> GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out))))
|
||||
&& (paradoxical_subreg_p (outmode, GET_MODE (SUBREG_REG (out)))
|
||||
|| (WORD_REGISTER_OPERATIONS
|
||||
&& (GET_MODE_PRECISION (outmode)
|
||||
< GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out))))
|
||||
@ -1299,7 +1297,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
|
||||
if (this_insn_is_asm)
|
||||
{
|
||||
machine_mode mode;
|
||||
if (GET_MODE_SIZE (inmode) > GET_MODE_SIZE (outmode))
|
||||
if (paradoxical_subreg_p (inmode, outmode))
|
||||
mode = inmode;
|
||||
else
|
||||
mode = outmode;
|
||||
@ -3137,15 +3135,15 @@ find_reloads (rtx_insn *insn, int replace, int ind_levels, int live_known,
|
||||
&& (WORD_REGISTER_OPERATIONS
|
||||
|| ((GET_MODE_BITSIZE (GET_MODE (operand))
|
||||
< BIGGEST_ALIGNMENT)
|
||||
&& (GET_MODE_SIZE (operand_mode[i])
|
||||
> GET_MODE_SIZE (GET_MODE (operand))))
|
||||
&& paradoxical_subreg_p (operand_mode[i],
|
||||
GET_MODE (operand)))
|
||||
|| BYTES_BIG_ENDIAN
|
||||
|| ((GET_MODE_SIZE (operand_mode[i])
|
||||
<= UNITS_PER_WORD)
|
||||
&& (GET_MODE_SIZE (GET_MODE (operand))
|
||||
<= UNITS_PER_WORD)
|
||||
&& (GET_MODE_SIZE (operand_mode[i])
|
||||
> GET_MODE_SIZE (GET_MODE (operand)))
|
||||
&& paradoxical_subreg_p (operand_mode[i],
|
||||
GET_MODE (operand))
|
||||
&& INTEGRAL_MODE_P (GET_MODE (operand))
|
||||
&& LOAD_EXTEND_OP (GET_MODE (operand))
|
||||
!= UNKNOWN)))
|
||||
|
@ -3042,8 +3042,7 @@ elimination_effects (rtx x, machine_mode mem_mode)
|
||||
|
||||
case SUBREG:
|
||||
if (REG_P (SUBREG_REG (x))
|
||||
&& (GET_MODE_SIZE (GET_MODE (x))
|
||||
<= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
|
||||
&& !paradoxical_subreg_p (x)
|
||||
&& reg_equivs
|
||||
&& reg_equiv_memory_loc (REGNO (SUBREG_REG (x))) != 0)
|
||||
return;
|
||||
@ -6373,8 +6372,7 @@ compute_reload_subreg_offset (machine_mode outermode,
|
||||
/* If SUBREG is paradoxical then return the normal lowpart offset
|
||||
for OUTERMODE and INNERMODE. Our caller has already checked
|
||||
that OUTERMODE fits in INNERMODE. */
|
||||
if (outer_offset == 0
|
||||
&& GET_MODE_SIZE (outermode) > GET_MODE_SIZE (middlemode))
|
||||
if (paradoxical_subreg_p (outermode, middlemode))
|
||||
return subreg_lowpart_offset (outermode, innermode);
|
||||
|
||||
/* SUBREG is normal, but may not be lowpart; return OUTER_OFFSET
|
||||
@ -6664,8 +6662,7 @@ choose_reload_regs (struct insn_chain *chain)
|
||||
&& rld[r].out)
|
||||
/* Don't really use the inherited spill reg
|
||||
if we need it wider than we've got it. */
|
||||
|| (GET_MODE_SIZE (rld[r].mode)
|
||||
> GET_MODE_SIZE (mode))
|
||||
|| paradoxical_subreg_p (rld[r].mode, mode)
|
||||
|| bad_for_class
|
||||
|
||||
/* If find_reloads chose reload_out as reload
|
||||
|
20
gcc/rtl.h
20
gcc/rtl.h
@ -2784,10 +2784,28 @@ extern rtx operand_subword (rtx, unsigned int, int, machine_mode);
|
||||
|
||||
/* In emit-rtl.c */
|
||||
extern rtx operand_subword_force (rtx, unsigned int, machine_mode);
|
||||
extern bool paradoxical_subreg_p (const_rtx);
|
||||
extern int subreg_lowpart_p (const_rtx);
|
||||
extern unsigned int subreg_size_lowpart_offset (unsigned int, unsigned int);
|
||||
|
||||
/* Return true if a subreg with the given outer and inner modes is
|
||||
paradoxical. */
|
||||
|
||||
inline bool
|
||||
paradoxical_subreg_p (machine_mode outermode, machine_mode innermode)
|
||||
{
|
||||
return GET_MODE_PRECISION (outermode) > GET_MODE_PRECISION (innermode);
|
||||
}
|
||||
|
||||
/* Return true if X is a paradoxical subreg, false otherwise. */
|
||||
|
||||
inline bool
|
||||
paradoxical_subreg_p (const_rtx x)
|
||||
{
|
||||
if (GET_CODE (x) != SUBREG)
|
||||
return false;
|
||||
return paradoxical_subreg_p (GET_MODE (x), GET_MODE (SUBREG_REG (x)));
|
||||
}
|
||||
|
||||
/* Return the SUBREG_BYTE for an OUTERMODE lowpart of an INNERMODE value. */
|
||||
|
||||
inline unsigned int
|
||||
|
@ -3530,7 +3530,7 @@ subreg_lsb_1 (machine_mode outer_mode,
|
||||
unsigned int word;
|
||||
|
||||
/* A paradoxical subreg begins at bit position 0. */
|
||||
if (GET_MODE_PRECISION (outer_mode) > GET_MODE_PRECISION (inner_mode))
|
||||
if (paradoxical_subreg_p (outer_mode, inner_mode))
|
||||
return 0;
|
||||
|
||||
if (WORDS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
|
||||
|
@ -1465,7 +1465,7 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
|
||||
if (GET_CODE (op) == SUBREG
|
||||
&& SUBREG_PROMOTED_VAR_P (op)
|
||||
&& SUBREG_PROMOTED_SIGNED_P (op)
|
||||
&& GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
|
||||
&& !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
|
||||
{
|
||||
temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
|
||||
if (temp)
|
||||
@ -1547,7 +1547,7 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
|
||||
if (GET_CODE (op) == SUBREG
|
||||
&& SUBREG_PROMOTED_VAR_P (op)
|
||||
&& SUBREG_PROMOTED_UNSIGNED_P (op)
|
||||
&& GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
|
||||
&& !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
|
||||
{
|
||||
temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
|
||||
if (temp)
|
||||
@ -6080,7 +6080,7 @@ simplify_subreg (machine_mode outermode, rtx op,
|
||||
}
|
||||
|
||||
/* See whether resulting subreg will be paradoxical. */
|
||||
if (GET_MODE_SIZE (innermostmode) > GET_MODE_SIZE (outermode))
|
||||
if (!paradoxical_subreg_p (outermode, innermostmode))
|
||||
{
|
||||
/* In nonparadoxical subregs we can't handle negative offsets. */
|
||||
if (final_offset < 0)
|
||||
|
@ -5295,7 +5295,7 @@ track_loc_p (rtx loc, tree expr, HOST_WIDE_INT offset, bool store_reg_p,
|
||||
machine_mode pseudo_mode;
|
||||
|
||||
pseudo_mode = PSEUDO_REGNO_MODE (ORIGINAL_REGNO (loc));
|
||||
if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (pseudo_mode))
|
||||
if (paradoxical_subreg_p (mode, pseudo_mode))
|
||||
{
|
||||
offset += byte_lowpart_offset (pseudo_mode, mode);
|
||||
mode = pseudo_mode;
|
||||
@ -5309,7 +5309,7 @@ track_loc_p (rtx loc, tree expr, HOST_WIDE_INT offset, bool store_reg_p,
|
||||
because the real and imaginary parts are represented as separate
|
||||
pseudo registers, even if the whole complex value fits into one
|
||||
hard register. */
|
||||
if ((GET_MODE_SIZE (mode) > GET_MODE_SIZE (DECL_MODE (expr))
|
||||
if ((paradoxical_subreg_p (mode, DECL_MODE (expr))
|
||||
|| (store_reg_p
|
||||
&& !COMPLEX_MODE_P (DECL_MODE (expr))
|
||||
&& hard_regno_nregs[REGNO (loc)][DECL_MODE (expr)] == 1))
|
||||
|
Loading…
x
Reference in New Issue
Block a user