aboutsummaryrefslogtreecommitdiff
path: root/gcc/emit-rtl.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-11-01 09:20:15 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-11-01 09:20:15 +0000
commit59d06c050373919ed36a13b37103b6e069d8ebd3 (patch)
tree7dd263d0996c053d689121993600e51fa33249b4 /gcc/emit-rtl.c
parenta9b76c8962410173ba0351b5b05b5f1f91742fc6 (diff)
downloadgcc-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.c84
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);
}