diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2018-01-03 21:42:20 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2018-01-03 21:42:20 +0000 |
commit | bb94ec7613a4fd30c278b236eb8783d985a1b6ee (patch) | |
tree | 4107ec912099af2ee77d6199890da00ee700d935 /gcc/combine.c | |
parent | 928686b1c6d0a8b791ec08b2588a5fb8118d191c (diff) | |
download | gcc-bb94ec7613a4fd30c278b236eb8783d985a1b6ee.zip gcc-bb94ec7613a4fd30c278b236eb8783d985a1b6ee.tar.gz gcc-bb94ec7613a4fd30c278b236eb8783d985a1b6ee.tar.bz2 |
poly_int: GET_MODE_PRECISION
This patch changes GET_MODE_PRECISION from an unsigned short
to a poly_uint16.
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* machmode.h (mode_precision): Change from unsigned short to
poly_uint16_pod.
(mode_to_precision): Return a poly_uint16 rather than an unsigned
short.
(GET_MODE_PRECISION): Return a constant if ONLY_FIXED_SIZE_MODES,
or if measurement_type is not polynomial.
(HWI_COMPUTABLE_MODE_P): Turn into a function. Optimize the case
in which the mode is already known to be a scalar_int_mode.
* genmodes.c (emit_mode_precision): Change the type of mode_precision
from unsigned short to poly_uint16_pod. Use ZERO_COEFFS for the
initializer.
* lto-streamer-in.c (lto_input_mode_table): Use bp_unpack_poly_value
for GET_MODE_PRECISION.
* lto-streamer-out.c (lto_write_mode_table): Use bp_pack_poly_value
for GET_MODE_PRECISION.
* combine.c (update_rsp_from_reg_equal): Treat GET_MODE_PRECISION
as polynomial.
(try_combine, find_split_point, combine_simplify_rtx): Likewise.
(expand_field_assignment, make_extraction): Likewise.
(make_compound_operation_int, record_dead_and_set_regs_1): Likewise.
(get_last_value): Likewise.
* convert.c (convert_to_integer_1): Likewise.
* cse.c (cse_insn): Likewise.
* expr.c (expand_expr_real_1): Likewise.
* lra-constraints.c (simplify_operand_subreg): Likewise.
* optabs-query.c (can_atomic_load_p): Likewise.
* optabs.c (expand_atomic_load): Likewise.
(expand_atomic_store): Likewise.
* ree.c (combine_reaching_defs): Likewise.
* rtl.h (partial_subreg_p, paradoxical_subreg_p): Likewise.
* rtlanal.c (nonzero_bits1, lsb_bitfield_op_p): Likewise.
* tree.h (type_has_mode_precision_p): Likewise.
* ubsan.c (instrument_si_overflow): Likewise.
gcc/ada/
* gcc-interface/misc.c (enumerate_modes): Treat GET_MODE_PRECISION
as polynomial.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r256198
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 77 |
1 files changed, 42 insertions, 35 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index 36713a1..fa6947a 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -1706,7 +1706,7 @@ update_rsp_from_reg_equal (reg_stat_type *rsp, rtx_insn *insn, const_rtx set, if (rsp->sign_bit_copies != 1) { num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x)); - if (reg_equal && num != GET_MODE_PRECISION (GET_MODE (x))) + if (reg_equal && maybe_ne (num, GET_MODE_PRECISION (GET_MODE (x)))) { unsigned int numeq = num_sign_bit_copies (reg_equal, GET_MODE (x)); if (num == 0 || numeq > num) @@ -3962,16 +3962,20 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, && ! (temp_expr = SET_DEST (XVECEXP (newpat, 0, 1)), (REG_P (temp_expr) && reg_stat[REGNO (temp_expr)].nonzero_bits != 0 - && GET_MODE_PRECISION (GET_MODE (temp_expr)) < BITS_PER_WORD - && GET_MODE_PRECISION (GET_MODE (temp_expr)) < HOST_BITS_PER_INT + && known_lt (GET_MODE_PRECISION (GET_MODE (temp_expr)), + BITS_PER_WORD) + && known_lt (GET_MODE_PRECISION (GET_MODE (temp_expr)), + HOST_BITS_PER_INT) && (reg_stat[REGNO (temp_expr)].nonzero_bits != GET_MODE_MASK (word_mode)))) && ! (GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == SUBREG && (temp_expr = SUBREG_REG (SET_DEST (XVECEXP (newpat, 0, 1))), (REG_P (temp_expr) && reg_stat[REGNO (temp_expr)].nonzero_bits != 0 - && GET_MODE_PRECISION (GET_MODE (temp_expr)) < BITS_PER_WORD - && GET_MODE_PRECISION (GET_MODE (temp_expr)) < HOST_BITS_PER_INT + && known_lt (GET_MODE_PRECISION (GET_MODE (temp_expr)), + BITS_PER_WORD) + && known_lt (GET_MODE_PRECISION (GET_MODE (temp_expr)), + HOST_BITS_PER_INT) && (reg_stat[REGNO (temp_expr)].nonzero_bits != GET_MODE_MASK (word_mode))))) && ! reg_overlap_mentioned_p (SET_DEST (XVECEXP (newpat, 0, 1)), @@ -5140,8 +5144,9 @@ find_split_point (rtx *loc, rtx_insn *insn, bool set_src) break; } - if (len && pos >= 0 - && pos + len <= GET_MODE_PRECISION (GET_MODE (inner)) + if (len + && known_subrange_p (pos, len, + 0, GET_MODE_PRECISION (GET_MODE (inner))) && is_a <scalar_int_mode> (GET_MODE (SET_SRC (x)), &mode)) { /* For unsigned, we have a choice of a shift followed by an @@ -6007,8 +6012,9 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int in_dest, && (UINTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1)) == (HOST_WIDE_INT_1U << (i + 1)) - 1)) || (GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND - && (GET_MODE_PRECISION (GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0))) - == (unsigned int) i + 1)))) + && known_eq ((GET_MODE_PRECISION + (GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)))), + (unsigned int) i + 1)))) return simplify_shift_const (NULL_RTX, ASHIFTRT, int_mode, simplify_shift_const (NULL_RTX, ASHIFT, int_mode, @@ -7346,7 +7352,7 @@ expand_field_assignment (const_rtx x) { rtx inner; rtx pos; /* Always counts from low bit. */ - int len; + int len, inner_len; rtx mask, cleared, masked; scalar_int_mode compute_mode; @@ -7356,8 +7362,10 @@ expand_field_assignment (const_rtx x) if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART && GET_CODE (XEXP (SET_DEST (x), 0)) == SUBREG) { + rtx x0 = XEXP (SET_DEST (x), 0); + if (!GET_MODE_PRECISION (GET_MODE (x0)).is_constant (&len)) + break; inner = SUBREG_REG (XEXP (SET_DEST (x), 0)); - len = GET_MODE_PRECISION (GET_MODE (XEXP (SET_DEST (x), 0))); pos = gen_int_mode (subreg_lsb (XEXP (SET_DEST (x), 0)), MAX_MODE_INT); } @@ -7365,33 +7373,30 @@ expand_field_assignment (const_rtx x) && CONST_INT_P (XEXP (SET_DEST (x), 1))) { inner = XEXP (SET_DEST (x), 0); + if (!GET_MODE_PRECISION (GET_MODE (inner)).is_constant (&inner_len)) + break; + len = INTVAL (XEXP (SET_DEST (x), 1)); pos = XEXP (SET_DEST (x), 2); /* A constant position should stay within the width of INNER. */ - if (CONST_INT_P (pos) - && INTVAL (pos) + len > GET_MODE_PRECISION (GET_MODE (inner))) + if (CONST_INT_P (pos) && INTVAL (pos) + len > inner_len) break; if (BITS_BIG_ENDIAN) { if (CONST_INT_P (pos)) - pos = GEN_INT (GET_MODE_PRECISION (GET_MODE (inner)) - len - - INTVAL (pos)); + pos = GEN_INT (inner_len - len - INTVAL (pos)); else if (GET_CODE (pos) == MINUS && CONST_INT_P (XEXP (pos, 1)) - && (INTVAL (XEXP (pos, 1)) - == GET_MODE_PRECISION (GET_MODE (inner)) - len)) + && INTVAL (XEXP (pos, 1)) == inner_len - len) /* If position is ADJUST - X, new position is X. */ pos = XEXP (pos, 0); else - { - HOST_WIDE_INT prec = GET_MODE_PRECISION (GET_MODE (inner)); - pos = simplify_gen_binary (MINUS, GET_MODE (pos), - gen_int_mode (prec - len, - GET_MODE (pos)), - pos); - } + pos = simplify_gen_binary (MINUS, GET_MODE (pos), + gen_int_mode (inner_len - len, + GET_MODE (pos)), + pos); } } @@ -7511,7 +7516,7 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, bits outside of is_mode, don't look through non-paradoxical SUBREGs. See PR82192. */ || (pos_rtx == NULL_RTX - && pos + len <= GET_MODE_PRECISION (is_mode)))) + && known_le (pos + len, GET_MODE_PRECISION (is_mode))))) { /* If going from (subreg:SI (mem:QI ...)) to (mem:QI ...), consider just the QI as the memory to extract from. @@ -7542,7 +7547,7 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, bits outside of is_mode, don't look through TRUNCATE. See PR82192. */ && pos_rtx == NULL_RTX - && pos + len <= GET_MODE_PRECISION (is_mode)) + && known_le (pos + len, GET_MODE_PRECISION (is_mode))) inner = XEXP (inner, 0); inner_mode = GET_MODE (inner); @@ -7589,11 +7594,12 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, if (MEM_P (inner)) { - HOST_WIDE_INT offset; + poly_int64 offset; /* POS counts from lsb, but make OFFSET count in memory order. */ if (BYTES_BIG_ENDIAN) - offset = (GET_MODE_PRECISION (is_mode) - len - pos) / BITS_PER_UNIT; + offset = bits_to_bytes_round_down (GET_MODE_PRECISION (is_mode) + - len - pos); else offset = pos / BITS_PER_UNIT; @@ -7685,7 +7691,7 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, other cases, we would only be going outside our object in cases when an original shift would have been undefined. */ if (MEM_P (inner) - && ((pos_rtx == 0 && pos + len > GET_MODE_PRECISION (is_mode)) + && ((pos_rtx == 0 && maybe_gt (pos + len, GET_MODE_PRECISION (is_mode))) || (pos_rtx != 0 && len != 1))) return 0; @@ -8164,8 +8170,10 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr, sub = XEXP (XEXP (x, 0), 0); machine_mode sub_mode = GET_MODE (sub); + int sub_width; if ((REG_P (sub) || MEM_P (sub)) - && GET_MODE_PRECISION (sub_mode) < mode_width) + && GET_MODE_PRECISION (sub_mode).is_constant (&sub_width) + && sub_width < mode_width) { unsigned HOST_WIDE_INT mode_mask = GET_MODE_MASK (sub_mode); unsigned HOST_WIDE_INT mask; @@ -8175,8 +8183,7 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr, if ((mask & mode_mask) == mode_mask) { new_rtx = make_compound_operation (sub, next_code); - new_rtx = make_extraction (mode, new_rtx, 0, 0, - GET_MODE_PRECISION (sub_mode), + new_rtx = make_extraction (mode, new_rtx, 0, 0, sub_width, 1, 0, in_code == COMPARE); } } @@ -13248,7 +13255,7 @@ record_dead_and_set_regs_1 (rtx dest, const_rtx setter, void *data) else if (GET_CODE (setter) == SET && GET_CODE (SET_DEST (setter)) == SUBREG && SUBREG_REG (SET_DEST (setter)) == dest - && GET_MODE_PRECISION (GET_MODE (dest)) <= BITS_PER_WORD + && known_le (GET_MODE_PRECISION (GET_MODE (dest)), BITS_PER_WORD) && subreg_lowpart_p (SET_DEST (setter))) record_value_for_reg (dest, record_dead_insn, gen_lowpart (GET_MODE (dest), @@ -13650,8 +13657,8 @@ get_last_value (const_rtx x) /* If fewer bits were set than what we are asked for now, we cannot use the value. */ - if (GET_MODE_PRECISION (rsp->last_set_mode) - < GET_MODE_PRECISION (GET_MODE (x))) + if (maybe_lt (GET_MODE_PRECISION (rsp->last_set_mode), + GET_MODE_PRECISION (GET_MODE (x)))) return 0; /* If the value has all its registers valid, return it. */ |