native_decode_rtx handles integer modes by building up a wide_int and then converting it to an rtx. This patch splits out the wide_int part, so that callers who don't want an rtx can avoid creating garbage rtl.
Bootstrapped & regression-tested on aarch64-linux-gnu. OK to install? Richard gcc/ * rtl.h (native_decode_int): Declare. * simplify-rtx.cc (native_decode_int): New function, split out from... (native_decode_rtx): ...here. --- gcc/rtl.h | 2 ++ gcc/simplify-rtx.cc | 38 +++++++++++++++++++++++++------------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/gcc/rtl.h b/gcc/rtl.h index 3b676c46880..cc25aed1f49 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -2443,6 +2443,8 @@ extern void get_full_rtx_cost (rtx, machine_mode, enum rtx_code, int, struct full_rtx_costs *); extern bool native_encode_rtx (machine_mode, rtx, vec<target_unit> &, unsigned int, unsigned int); +extern wide_int native_decode_int (const vec<target_unit> &, unsigned int, + unsigned int, unsigned int); extern rtx native_decode_rtx (machine_mode, const vec<target_unit> &, unsigned int); extern rtx native_decode_vector_rtx (machine_mode, const vec<target_unit> &, diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index 88d31a71c05..0e0a908aa38 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -7702,6 +7702,28 @@ native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes, return builder.build (); } +/* Extract a PRECISION-bit integer from bytes [FIRST_BYTE, FIRST_BYTE + SIZE) + of target memory image BYTES. */ + +wide_int +native_decode_int (const vec<target_unit> &bytes, unsigned int first_byte, + unsigned int size, unsigned int precision) +{ + /* Pull the bytes msb first, so that we can use simple + shift-and-insert wide_int operations. */ + wide_int result (wi::zero (precision)); + for (unsigned int i = 0; i < size; ++i) + { + unsigned int lsb = (size - i - 1) * BITS_PER_UNIT; + /* Always constant because the inputs are. */ + unsigned int subbyte + = subreg_size_offset_from_lsb (1, size, lsb).to_constant (); + result <<= BITS_PER_UNIT; + result |= bytes[first_byte + subbyte]; + } + return result; +} + /* Read an rtx of mode MODE from the target memory image given by BYTES, starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT bits and the bytes are in target memory order. The image has enough @@ -7727,19 +7749,9 @@ native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes, if (is_a <scalar_int_mode> (mode, &imode) && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT) { - /* Pull the bytes msb first, so that we can use simple - shift-and-insert wide_int operations. */ - unsigned int size = GET_MODE_SIZE (imode); - wide_int result (wi::zero (GET_MODE_PRECISION (imode))); - for (unsigned int i = 0; i < size; ++i) - { - unsigned int lsb = (size - i - 1) * BITS_PER_UNIT; - /* Always constant because the inputs are. */ - unsigned int subbyte - = subreg_size_offset_from_lsb (1, size, lsb).to_constant (); - result <<= BITS_PER_UNIT; - result |= bytes[first_byte + subbyte]; - } + auto result = native_decode_int (bytes, first_byte, + GET_MODE_SIZE (imode), + GET_MODE_PRECISION (imode)); return immed_wide_int_const (result, imode); } -- 2.43.0