This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[4/4] Make CONST_VECTOR_ELT handle implicitly-encoded elements
- From: Richard Sandiford <richard dot sandiford at linaro dot org>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 28 Dec 2017 20:54:04 +0000
- Subject: [4/4] Make CONST_VECTOR_ELT handle implicitly-encoded elements
- Authentication-results: sourceware.org; auth=none
- References: <874loainn7.fsf@linaro.org>
This patch makes CONST_VECTOR_ELT handle implicitly-encoded elements,
in a similar way to VECTOR_CST_ELT.
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.) */