Message ID | 87k1x6h8ur.fsf@linaro.org |
---|---|
State | New |
Headers | show |
Series | Use new vector constant encoding for CONST_VECTOR | expand |
On Thu, Dec 28, 2017 at 9:54 PM, Richard Sandiford <richard.sandiford@linaro.org> wrote: > This patch makes CONST_VECTOR_ELT handle implicitly-encoded elements, > in a similar way to VECTOR_CST_ELT. Ok. Richard. > > 2017-12-28 Richard Sandiford <richard.sandiford@linaro.org> > > gcc/ > * rtl.h (CONST_VECTOR_ELT): Redefine to const_vector_elt. > (const_vector_encoded_nelts): New function. > (CONST_VECTOR_NUNITS): Redefine to use GET_MODE_NUNITS. > (const_vector_int_elt, const_vector_elt): Declare. > * emit-rtl.c (const_vector_int_elt_1): New function. > (const_vector_elt): Likewise. > * simplify-rtx.c (simplify_immed_subreg): Avoid taking the address > of CONST_VECTOR_ELT. > > Index: gcc/rtl.h > =================================================================== > --- gcc/rtl.h 2017-12-22 13:12:00.662528577 +0000 > +++ gcc/rtl.h 2017-12-22 13:12:00.834520649 +0000 > @@ -1969,7 +1969,7 @@ #define CONST_FIXED_VALUE_LOW(r) \ > ((HOST_WIDE_INT) (CONST_FIXED_VALUE (r)->data.low)) > > /* For a CONST_VECTOR, return element #n. */ > -#define CONST_VECTOR_ELT(RTX, N) XCVECEXP (RTX, 0, N, CONST_VECTOR) > +#define CONST_VECTOR_ELT(RTX, N) const_vector_elt (RTX, N) > > #define CONST_VECTOR_NPATTERNS(RTX) \ > (RTL_FLAG_CHECK1 ("CONST_VECTOR_NPATTERNS", (RTX), CONST_VECTOR) \ > @@ -1987,8 +1987,16 @@ #define CONST_VECTOR_STEPPED_P(RTX) \ > > #define CONST_VECTOR_ENCODED_ELT(RTX, N) XCVECEXP (RTX, 0, N, CONST_VECTOR) > > +/* Return the number of elements encoded directly in a CONST_VECTOR. */ > + > +inline unsigned int > +const_vector_encoded_nelts (const_rtx x) > +{ > + return CONST_VECTOR_NPATTERNS (x) * CONST_VECTOR_NELTS_PER_PATTERN (x); > +} > + > /* For a CONST_VECTOR, return the number of elements in a vector. */ > -#define CONST_VECTOR_NUNITS(RTX) XCVECLEN (RTX, 0, CONST_VECTOR) > +#define CONST_VECTOR_NUNITS(RTX) GET_MODE_NUNITS (GET_MODE (RTX)) > > /* For a SUBREG rtx, SUBREG_REG extracts the value we want a subreg of. > SUBREG_BYTE extracts the byte-number. */ > @@ -3000,6 +3008,8 @@ unwrap_const_vec_duplicate (T x) > } > > /* In emit-rtl.c. */ > +extern wide_int const_vector_int_elt (const_rtx, unsigned int); > +extern rtx const_vector_elt (const_rtx, unsigned int); > extern bool const_vec_series_p_1 (const_rtx, rtx *, rtx *); > > /* Return true if X is an integer constant vector that contains a linear > Index: gcc/emit-rtl.c > =================================================================== > --- gcc/emit-rtl.c 2017-12-22 13:11:58.364634475 +0000 > +++ gcc/emit-rtl.c 2017-12-22 13:12:00.833520695 +0000 > @@ -5862,6 +5862,62 @@ init_emit (void) > #endif > } > > +/* Return the value of element I of CONST_VECTOR X as a wide_int. */ > + > +wide_int > +const_vector_int_elt (const_rtx x, unsigned int i) > +{ > + /* First handle elements that are directly encoded. */ > + machine_mode elt_mode = GET_MODE_INNER (GET_MODE (x)); > + if (i < (unsigned int) XVECLEN (x, 0)) > + return rtx_mode_t (CONST_VECTOR_ENCODED_ELT (x, i), elt_mode); > + > + /* Identify the pattern that contains element I and work out the index of > + the last encoded element for that pattern. */ > + unsigned int encoded_nelts = const_vector_encoded_nelts (x); > + unsigned int npatterns = CONST_VECTOR_NPATTERNS (x); > + unsigned int count = i / npatterns; > + unsigned int pattern = i % npatterns; > + unsigned int final_i = encoded_nelts - npatterns + pattern; > + > + /* If there are no steps, the final encoded value is the right one. */ > + if (!CONST_VECTOR_STEPPED_P (x)) > + return rtx_mode_t (CONST_VECTOR_ENCODED_ELT (x, final_i), elt_mode); > + > + /* Otherwise work out the value from the last two encoded elements. */ > + rtx v1 = CONST_VECTOR_ENCODED_ELT (x, final_i - npatterns); > + rtx v2 = CONST_VECTOR_ENCODED_ELT (x, final_i); > + wide_int diff = wi::sub (rtx_mode_t (v2, elt_mode), > + rtx_mode_t (v1, elt_mode)); > + return wi::add (rtx_mode_t (v2, elt_mode), (count - 2) * diff); > +} > + > +/* Return the value of element I of CONST_VECTOR X. */ > + > +rtx > +const_vector_elt (const_rtx x, unsigned int i) > +{ > + /* First handle elements that are directly encoded. */ > + if (i < (unsigned int) XVECLEN (x, 0)) > + return CONST_VECTOR_ENCODED_ELT (x, i); > + > + /* If there are no steps, the final encoded value is the right one. */ > + if (!CONST_VECTOR_STEPPED_P (x)) > + { > + /* Identify the pattern that contains element I and work out the index of > + the last encoded element for that pattern. */ > + unsigned int encoded_nelts = const_vector_encoded_nelts (x); > + unsigned int npatterns = CONST_VECTOR_NPATTERNS (x); > + unsigned int pattern = i % npatterns; > + unsigned int final_i = encoded_nelts - npatterns + pattern; > + return CONST_VECTOR_ENCODED_ELT (x, final_i); > + } > + > + /* Otherwise work out the value from the last two encoded elements. */ > + return immed_wide_int_const (const_vector_int_elt (x, i), > + GET_MODE_INNER (GET_MODE (x))); > +} > + > /* Return true if X is a valid element for a CONST_VECTOR of the given > mode. */ > > Index: gcc/simplify-rtx.c > =================================================================== > --- gcc/simplify-rtx.c 2017-12-22 13:12:00.662528577 +0000 > +++ gcc/simplify-rtx.c 2017-12-22 13:12:00.834520649 +0000 > @@ -5990,13 +5990,11 @@ simplify_immed_subreg (fixed_size_mode o > if (GET_CODE (op) == CONST_VECTOR) > { > num_elem = CONST_VECTOR_NUNITS (op); > - elems = &CONST_VECTOR_ELT (op, 0); > elem_bitsize = GET_MODE_UNIT_BITSIZE (innermode); > } > else > { > num_elem = 1; > - elems = &op; > elem_bitsize = max_bitsize; > } > /* If this asserts, it is too complicated; reducing value_bit may help. */ > @@ -6007,7 +6005,9 @@ simplify_immed_subreg (fixed_size_mode o > for (elem = 0; elem < num_elem; elem++) > { > unsigned char * vp; > - rtx el = elems[elem]; > + rtx el = (GET_CODE (op) == CONST_VECTOR > + ? CONST_VECTOR_ELT (op, elem) > + : op); > > /* Vectors are kept in target memory order. (This is probably > a mistake.) */
Index: gcc/rtl.h =================================================================== --- gcc/rtl.h 2017-12-22 13:12:00.662528577 +0000 +++ gcc/rtl.h 2017-12-22 13:12:00.834520649 +0000 @@ -1969,7 +1969,7 @@ #define CONST_FIXED_VALUE_LOW(r) \ ((HOST_WIDE_INT) (CONST_FIXED_VALUE (r)->data.low)) /* For a CONST_VECTOR, return element #n. */ -#define CONST_VECTOR_ELT(RTX, N) XCVECEXP (RTX, 0, N, CONST_VECTOR) +#define CONST_VECTOR_ELT(RTX, N) const_vector_elt (RTX, N) #define CONST_VECTOR_NPATTERNS(RTX) \ (RTL_FLAG_CHECK1 ("CONST_VECTOR_NPATTERNS", (RTX), CONST_VECTOR) \ @@ -1987,8 +1987,16 @@ #define CONST_VECTOR_STEPPED_P(RTX) \ #define CONST_VECTOR_ENCODED_ELT(RTX, N) XCVECEXP (RTX, 0, N, CONST_VECTOR) +/* Return the number of elements encoded directly in a CONST_VECTOR. */ + +inline unsigned int +const_vector_encoded_nelts (const_rtx x) +{ + return CONST_VECTOR_NPATTERNS (x) * CONST_VECTOR_NELTS_PER_PATTERN (x); +} + /* For a CONST_VECTOR, return the number of elements in a vector. */ -#define CONST_VECTOR_NUNITS(RTX) XCVECLEN (RTX, 0, CONST_VECTOR) +#define CONST_VECTOR_NUNITS(RTX) GET_MODE_NUNITS (GET_MODE (RTX)) /* For a SUBREG rtx, SUBREG_REG extracts the value we want a subreg of. SUBREG_BYTE extracts the byte-number. */ @@ -3000,6 +3008,8 @@ unwrap_const_vec_duplicate (T x) } /* In emit-rtl.c. */ +extern wide_int const_vector_int_elt (const_rtx, unsigned int); +extern rtx const_vector_elt (const_rtx, unsigned int); extern bool const_vec_series_p_1 (const_rtx, rtx *, rtx *); /* Return true if X is an integer constant vector that contains a linear Index: gcc/emit-rtl.c =================================================================== --- gcc/emit-rtl.c 2017-12-22 13:11:58.364634475 +0000 +++ gcc/emit-rtl.c 2017-12-22 13:12:00.833520695 +0000 @@ -5862,6 +5862,62 @@ init_emit (void) #endif } +/* Return the value of element I of CONST_VECTOR X as a wide_int. */ + +wide_int +const_vector_int_elt (const_rtx x, unsigned int i) +{ + /* First handle elements that are directly encoded. */ + machine_mode elt_mode = GET_MODE_INNER (GET_MODE (x)); + if (i < (unsigned int) XVECLEN (x, 0)) + return rtx_mode_t (CONST_VECTOR_ENCODED_ELT (x, i), elt_mode); + + /* Identify the pattern that contains element I and work out the index of + the last encoded element for that pattern. */ + unsigned int encoded_nelts = const_vector_encoded_nelts (x); + unsigned int npatterns = CONST_VECTOR_NPATTERNS (x); + unsigned int count = i / npatterns; + unsigned int pattern = i % npatterns; + unsigned int final_i = encoded_nelts - npatterns + pattern; + + /* If there are no steps, the final encoded value is the right one. */ + if (!CONST_VECTOR_STEPPED_P (x)) + return rtx_mode_t (CONST_VECTOR_ENCODED_ELT (x, final_i), elt_mode); + + /* Otherwise work out the value from the last two encoded elements. */ + rtx v1 = CONST_VECTOR_ENCODED_ELT (x, final_i - npatterns); + rtx v2 = CONST_VECTOR_ENCODED_ELT (x, final_i); + wide_int diff = wi::sub (rtx_mode_t (v2, elt_mode), + rtx_mode_t (v1, elt_mode)); + return wi::add (rtx_mode_t (v2, elt_mode), (count - 2) * diff); +} + +/* Return the value of element I of CONST_VECTOR X. */ + +rtx +const_vector_elt (const_rtx x, unsigned int i) +{ + /* First handle elements that are directly encoded. */ + if (i < (unsigned int) XVECLEN (x, 0)) + return CONST_VECTOR_ENCODED_ELT (x, i); + + /* If there are no steps, the final encoded value is the right one. */ + if (!CONST_VECTOR_STEPPED_P (x)) + { + /* Identify the pattern that contains element I and work out the index of + the last encoded element for that pattern. */ + unsigned int encoded_nelts = const_vector_encoded_nelts (x); + unsigned int npatterns = CONST_VECTOR_NPATTERNS (x); + unsigned int pattern = i % npatterns; + unsigned int final_i = encoded_nelts - npatterns + pattern; + return CONST_VECTOR_ENCODED_ELT (x, final_i); + } + + /* Otherwise work out the value from the last two encoded elements. */ + return immed_wide_int_const (const_vector_int_elt (x, i), + GET_MODE_INNER (GET_MODE (x))); +} + /* Return true if X is a valid element for a CONST_VECTOR of the given mode. */ Index: gcc/simplify-rtx.c =================================================================== --- gcc/simplify-rtx.c 2017-12-22 13:12:00.662528577 +0000 +++ gcc/simplify-rtx.c 2017-12-22 13:12:00.834520649 +0000 @@ -5990,13 +5990,11 @@ simplify_immed_subreg (fixed_size_mode o if (GET_CODE (op) == CONST_VECTOR) { num_elem = CONST_VECTOR_NUNITS (op); - elems = &CONST_VECTOR_ELT (op, 0); elem_bitsize = GET_MODE_UNIT_BITSIZE (innermode); } else { num_elem = 1; - elems = &op; elem_bitsize = max_bitsize; } /* If this asserts, it is too complicated; reducing value_bit may help. */ @@ -6007,7 +6005,9 @@ simplify_immed_subreg (fixed_size_mode o for (elem = 0; elem < num_elem; elem++) { unsigned char * vp; - rtx el = elems[elem]; + rtx el = (GET_CODE (op) == CONST_VECTOR + ? CONST_VECTOR_ELT (op, elem) + : op); /* Vectors are kept in target memory order. (This is probably a mistake.) */