diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2018-01-03 07:17:18 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2018-01-03 07:17:18 +0000 |
commit | d34457c138d06e989c871e7b295c06a8b9873703 (patch) | |
tree | c6778566a2e3b2d38ff05041a41dc94a6d331a69 /gcc/match.pd | |
parent | fece509bf196d58d9b31e04d816bb4ecd3f73e89 (diff) | |
download | gcc-d34457c138d06e989c871e7b295c06a8b9873703.zip gcc-d34457c138d06e989c871e7b295c06a8b9873703.tar.gz gcc-d34457c138d06e989c871e7b295c06a8b9873703.tar.bz2 |
poly_int: folding BIT_FIELD_REFs on vectors
This patch makes the:
(BIT_FIELD_REF CONSTRUCTOR@0 @1 @2)
folder cope with polynomial numbers of elements.
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* match.pd: Cope with polynomial numbers of vector elements.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r256147
Diffstat (limited to 'gcc/match.pd')
-rw-r--r-- | gcc/match.pd | 47 |
1 files changed, 22 insertions, 25 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index 06af2a7..a2a1b8f 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -4530,46 +4530,43 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) idx = idx / width; n = n / width; /* Constructor elements can be subvectors. */ - unsigned HOST_WIDE_INT k = 1; + poly_uint64 k = 1; if (CONSTRUCTOR_NELTS (ctor) != 0) { tree cons_elem = TREE_TYPE (CONSTRUCTOR_ELT (ctor, 0)->value); if (TREE_CODE (cons_elem) == VECTOR_TYPE) k = TYPE_VECTOR_SUBPARTS (cons_elem); } + unsigned HOST_WIDE_INT elt, count, const_k; } (switch /* We keep an exact subset of the constructor elements. */ - (if ((idx % k) == 0 && (n % k) == 0) + (if (multiple_p (idx, k, &elt) && multiple_p (n, k, &count)) (if (CONSTRUCTOR_NELTS (ctor) == 0) { build_constructor (type, NULL); } - (with + (if (count == 1) + (if (elt < CONSTRUCTOR_NELTS (ctor)) + { CONSTRUCTOR_ELT (ctor, elt)->value; } + { build_zero_cst (type); }) { - idx /= k; - n /= k; - } - (if (n == 1) - (if (idx < CONSTRUCTOR_NELTS (ctor)) - { CONSTRUCTOR_ELT (ctor, idx)->value; } - { build_zero_cst (type); }) - { - vec<constructor_elt, va_gc> *vals; - vec_alloc (vals, n); - for (unsigned i = 0; - i < n && idx + i < CONSTRUCTOR_NELTS (ctor); ++i) - CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE, - CONSTRUCTOR_ELT (ctor, idx + i)->value); - build_constructor (type, vals); - })))) + vec<constructor_elt, va_gc> *vals; + vec_alloc (vals, count); + for (unsigned i = 0; + i < count && elt + i < CONSTRUCTOR_NELTS (ctor); ++i) + CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE, + CONSTRUCTOR_ELT (ctor, elt + i)->value); + build_constructor (type, vals); + }))) /* The bitfield references a single constructor element. */ - (if (idx + n <= (idx / k + 1) * k) + (if (k.is_constant (&const_k) + && idx + n <= (idx / const_k + 1) * const_k) (switch - (if (CONSTRUCTOR_NELTS (ctor) <= idx / k) + (if (CONSTRUCTOR_NELTS (ctor) <= idx / const_k) { build_zero_cst (type); }) - (if (n == k) - { CONSTRUCTOR_ELT (ctor, idx / k)->value; }) - (BIT_FIELD_REF { CONSTRUCTOR_ELT (ctor, idx / k)->value; } - @1 { bitsize_int ((idx % k) * width); }))))))))) + (if (n == const_k) + { CONSTRUCTOR_ELT (ctor, idx / const_k)->value; }) + (BIT_FIELD_REF { CONSTRUCTOR_ELT (ctor, idx / const_k)->value; } + @1 { bitsize_int ((idx % const_k) * width); }))))))))) /* Simplify a bit extraction from a bit insertion for the cases with the inserted element fully covering the extraction or the insertion |