diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-11-01 09:20:15 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-11-01 09:20:15 +0000 |
commit | 59d06c050373919ed36a13b37103b6e069d8ebd3 (patch) | |
tree | 7dd263d0996c053d689121993600e51fa33249b4 /gcc/emit-rtl.c | |
parent | a9b76c8962410173ba0351b5b05b5f1f91742fc6 (diff) | |
download | gcc-59d06c050373919ed36a13b37103b6e069d8ebd3.zip gcc-59d06c050373919ed36a13b37103b6e069d8ebd3.tar.gz gcc-59d06c050373919ed36a13b37103b6e069d8ebd3.tar.bz2 |
Add gen_(const_)vec_duplicate helpers
This patch adds helper functions for generating constant and
non-constant vector duplicates. These routines help with SVE because
it is then easier to use:
(const:M (vec_duplicate:M X))
for a broadcast of X, even if the number of elements in M isn't known
at compile time. It also makes it easier for general rtx code to treat
constant and non-constant duplicates in the same way.
In the target code, the patch uses gen_vec_duplicate instead of
gen_rtx_VEC_DUPLICATE if handling constants correctly is potentially
useful. It might be that some or all of the call sites only handle
non-constants in practice, in which case the change is a harmless
no-op (and a saving of a few characters).
Otherwise, the target changes use gen_const_vec_duplicate instead
of gen_rtx_CONST_VECTOR if the constant is obviously a duplicate.
They also include some changes to use CONSTxx_RTX for easy global
constants.
2017-11-01 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* emit-rtl.h (gen_const_vec_duplicate): Declare.
(gen_vec_duplicate): Likewise.
* emit-rtl.c (gen_const_vec_duplicate_1): New function, split
out from...
(gen_const_vector): ...here.
(gen_const_vec_duplicate, gen_vec_duplicate): New functions.
(gen_rtx_CONST_VECTOR): Use gen_const_vec_duplicate for constants
whose elements are all equal.
* optabs.c (expand_vector_broadcast): Use gen_const_vec_duplicate.
* simplify-rtx.c (simplify_const_unary_operation): Likewise.
(simplify_relational_operation): Likewise.
* config/aarch64/aarch64.c (aarch64_simd_gen_const_vector_dup):
Likewise.
(aarch64_simd_dup_constant): Use gen_vec_duplicate.
(aarch64_expand_vector_init): Likewise.
* config/arm/arm.c (neon_vdup_constant): Likewise.
(neon_expand_vector_init): Likewise.
(arm_expand_vec_perm): Use gen_const_vec_duplicate.
(arm_block_set_unaligned_vect): Likewise.
(arm_block_set_aligned_vect): Likewise.
* config/arm/neon.md (neon_copysignf<mode>): Likewise.
* config/i386/i386.c (ix86_expand_vec_perm): Likewise.
(expand_vec_perm_even_odd_pack): Likewise.
(ix86_vector_duplicate_value): Use gen_vec_duplicate.
* config/i386/sse.md (one_cmpl<mode>2): Use CONSTM1_RTX.
* config/ia64/ia64.c (ia64_expand_vecint_compare): Use
gen_const_vec_duplicate.
* config/ia64/vect.md (addv2sf3, subv2sf3): Use CONST1_RTX.
* config/mips/mips.c (mips_gen_const_int_vector): Use
gen_const_vec_duplicate.
(mips_expand_vector_init): Use CONST0_RTX.
* config/powerpcspe/altivec.md (abs<mode>2, nabs<mode>2): Likewise.
(define_split): Use gen_const_vec_duplicate.
* config/rs6000/altivec.md (abs<mode>2, nabs<mode>2): Use CONST0_RTX.
(define_split): Use gen_const_vec_duplicate.
* config/s390/vx-builtins.md (vec_genmask<mode>): Likewise.
(vec_ctd_s64, vec_ctd_u64, vec_ctsl, vec_ctul): Likewise.
* config/spu/spu.c (spu_const): Likewise.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r254292
Diffstat (limited to 'gcc/emit-rtl.c')
-rw-r--r-- | gcc/emit-rtl.c | 84 |
1 files changed, 48 insertions, 36 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index d91988e..4df550f 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -5757,32 +5757,60 @@ init_emit (void) #endif } -/* Generate a vector constant for mode MODE and constant value CONSTANT. */ +/* Like gen_const_vec_duplicate, but ignore const_tiny_rtx. */ static rtx -gen_const_vector (machine_mode mode, int constant) +gen_const_vec_duplicate_1 (machine_mode mode, rtx el) { - rtx tem; - rtvec v; - int units, i; - machine_mode inner; + int nunits = GET_MODE_NUNITS (mode); + rtvec v = rtvec_alloc (nunits); + for (int i = 0; i < nunits; ++i) + RTVEC_ELT (v, i) = el; + return gen_rtx_raw_CONST_VECTOR (mode, v); +} - units = GET_MODE_NUNITS (mode); - inner = GET_MODE_INNER (mode); +/* Generate a vector constant of mode MODE in which every element has + value ELT. */ - gcc_assert (!DECIMAL_FLOAT_MODE_P (inner)); +rtx +gen_const_vec_duplicate (machine_mode mode, rtx elt) +{ + scalar_mode inner_mode = GET_MODE_INNER (mode); + if (elt == CONST0_RTX (inner_mode)) + return CONST0_RTX (mode); + else if (elt == CONST1_RTX (inner_mode)) + return CONST1_RTX (mode); + else if (elt == CONSTM1_RTX (inner_mode)) + return CONSTM1_RTX (mode); + + return gen_const_vec_duplicate_1 (mode, elt); +} + +/* Return a vector rtx of mode MODE in which every element has value X. + The result will be a constant if X is constant. */ + +rtx +gen_vec_duplicate (machine_mode mode, rtx x) +{ + if (CONSTANT_P (x)) + return gen_const_vec_duplicate (mode, x); + return gen_rtx_VEC_DUPLICATE (mode, x); +} - v = rtvec_alloc (units); +/* Generate a new vector constant for mode MODE and constant value + CONSTANT. */ - /* We need to call this function after we set the scalar const_tiny_rtx - entries. */ - gcc_assert (const_tiny_rtx[constant][(int) inner]); +static rtx +gen_const_vector (machine_mode mode, int constant) +{ + machine_mode inner = GET_MODE_INNER (mode); - for (i = 0; i < units; ++i) - RTVEC_ELT (v, i) = const_tiny_rtx[constant][(int) inner]; + gcc_assert (!DECIMAL_FLOAT_MODE_P (inner)); + + rtx el = const_tiny_rtx[constant][(int) inner]; + gcc_assert (el); - tem = gen_rtx_raw_CONST_VECTOR (mode, v); - return tem; + return gen_const_vec_duplicate_1 (mode, el); } /* Generate a vector like gen_rtx_raw_CONST_VEC, but use the zero vector when @@ -5790,28 +5818,12 @@ gen_const_vector (machine_mode mode, int constant) rtx gen_rtx_CONST_VECTOR (machine_mode mode, rtvec v) { - machine_mode inner = GET_MODE_INNER (mode); - int nunits = GET_MODE_NUNITS (mode); - rtx x; - int i; - - /* Check to see if all of the elements have the same value. */ - x = RTVEC_ELT (v, nunits - 1); - for (i = nunits - 2; i >= 0; i--) - if (RTVEC_ELT (v, i) != x) - break; + gcc_assert (GET_MODE_NUNITS (mode) == GET_NUM_ELEM (v)); /* If the values are all the same, check to see if we can use one of the standard constant vectors. */ - if (i == -1) - { - if (x == CONST0_RTX (inner)) - return CONST0_RTX (mode); - else if (x == CONST1_RTX (inner)) - return CONST1_RTX (mode); - else if (x == CONSTM1_RTX (inner)) - return CONSTM1_RTX (mode); - } + if (rtvec_all_equal_p (v)) + return gen_const_vec_duplicate (mode, RTVEC_ELT (v, 0)); return gen_rtx_raw_CONST_VECTOR (mode, v); } |