Make CONST_VECTOR_ELT handle implicitly-encoded elements
This patch makes CONST_VECTOR_ELT handle implicitly-encoded elements, in a similar way to VECTOR_CST_ELT. 2018-01-02 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. From-SVN: r256104
This commit is contained in:
committed by
Richard Sandiford
parent
3d8ca53dd9
commit
cd5ff7bc32
@@ -1,3 +1,14 @@
|
||||
2018-01-02 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
|
||||
* 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.
|
||||
|
||||
2018-01-02 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
|
||||
* expr.c: Include rtx-vector-builder.h.
|
||||
|
||||
@@ -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. */
|
||||
|
||||
|
||||
@@ -1969,7 +1969,7 @@ set_regno_raw (rtx x, unsigned int regno, unsigned int nregs)
|
||||
((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)
|
||||
|
||||
/* See rtl.texi for a description of these macros. */
|
||||
#define CONST_VECTOR_NPATTERNS(RTX) \
|
||||
@@ -1988,8 +1988,16 @@ set_regno_raw (rtx x, unsigned int regno, unsigned int nregs)
|
||||
|
||||
#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. */
|
||||
@@ -3001,6 +3009,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
|
||||
|
||||
+3
-3
@@ -5991,13 +5991,11 @@ simplify_immed_subreg (fixed_size_mode outermode, rtx op,
|
||||
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. */
|
||||
@@ -6008,7 +6006,9 @@ simplify_immed_subreg (fixed_size_mode outermode, rtx op,
|
||||
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.) */
|
||||
|
||||
Reference in New Issue
Block a user