diff options
author | Victor Do Nascimento <victor.donascimento@arm.com> | 2024-12-11 12:00:58 +0000 |
---|---|---|
committer | Tamar Christina <tamar.christina@arm.com> | 2024-12-11 12:01:06 +0000 |
commit | b6242bd122757ec6c75c73a4921f24a9a382b090 (patch) | |
tree | 651a5bbe42e8259b0b1cf32589c33417f422a0ed /gcc/expr.cc | |
parent | d069eb91d5696a8642bd5fc44a6d47fd7f74d18b (diff) | |
download | gcc-b6242bd122757ec6c75c73a4921f24a9a382b090.zip gcc-b6242bd122757ec6c75c73a4921f24a9a382b090.tar.gz gcc-b6242bd122757ec6c75c73a4921f24a9a382b090.tar.bz2 |
middle-end: Add initial support for poly_int64 BIT_FIELD_REF in expand pass [PR96342]
While `poly_int64' has been the default representation of bitfield size
and offset for some time, there was a lack of support for the use of
non-constant `poly_int64' values for those values throughout the
compiler, limiting the applicability of the BIT_FIELD_REF rtl expression
for variable length vectors, such as those used by SVE.
This patch starts work on extending the functionality of relevant
functions in the expand pass such as to enable their use by the compiler
for such vectors.
gcc/ChangeLog:
PR target/96342
* expr.cc (store_constructor): Enable poly_{u}int64 type usage.
(get_inner_reference): Ditto.
Co-authored-by: Tamar Christina <tamar.christina@arm.com>
Diffstat (limited to 'gcc/expr.cc')
-rw-r--r-- | gcc/expr.cc | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/gcc/expr.cc b/gcc/expr.cc index 88fa56c..babf00f 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -7901,15 +7901,14 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size, { unsigned HOST_WIDE_INT idx; constructor_elt *ce; - int i; bool need_to_clear; insn_code icode = CODE_FOR_nothing; tree elt; tree elttype = TREE_TYPE (type); int elt_size = vector_element_bits (type); machine_mode eltmode = TYPE_MODE (elttype); - HOST_WIDE_INT bitsize; - HOST_WIDE_INT bitpos; + poly_int64 bitsize; + poly_int64 bitpos; rtvec vector = NULL; poly_uint64 n_elts; unsigned HOST_WIDE_INT const_n_elts; @@ -8006,7 +8005,7 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size, ? TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value) : elttype); if (VECTOR_TYPE_P (val_type)) - bitsize = tree_to_uhwi (TYPE_SIZE (val_type)); + bitsize = tree_to_poly_uint64 (TYPE_SIZE (val_type)); else bitsize = elt_size; @@ -8019,12 +8018,12 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size, need_to_clear = true; else { - unsigned HOST_WIDE_INT count = 0, zero_count = 0; + poly_uint64 count = 0, zero_count = 0; tree value; FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value) { - int n_elts_here = bitsize / elt_size; + poly_int64 n_elts_here = exact_div (bitsize, elt_size); count += n_elts_here; if (mostly_zeros_p (value)) zero_count += n_elts_here; @@ -8033,7 +8032,7 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size, /* Clear the entire vector first if there are any missing elements, or if the incidence of zero elements is >= 75%. */ need_to_clear = (maybe_lt (count, n_elts) - || 4 * zero_count >= 3 * count); + || maybe_gt (4 * zero_count, 3 * count)); } if (need_to_clear && maybe_gt (size, 0) && !vector) @@ -8060,9 +8059,13 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size, /* Store each element of the constructor into the corresponding element of TARGET, determined by counting the elements. */ - for (idx = 0, i = 0; - vec_safe_iterate (CONSTRUCTOR_ELTS (exp), idx, &ce); - idx++, i += bitsize / elt_size) + HOST_WIDE_INT chunk_size = 0; + bool chunk_multiple_p = constant_multiple_p (bitsize, elt_size, + &chunk_size); + gcc_assert (chunk_multiple_p || vec_vec_init_p); + + for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (exp), idx, &ce); + idx++) { HOST_WIDE_INT eltpos; tree value = ce->value; @@ -8073,7 +8076,7 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size, if (ce->index) eltpos = tree_to_uhwi (ce->index); else - eltpos = i; + eltpos = idx * chunk_size; if (vector) { @@ -8461,10 +8464,8 @@ get_inner_reference (tree exp, poly_int64 *pbitsize, if (size_tree != 0) { - if (! tree_fits_uhwi_p (size_tree)) + if (!poly_int_tree_p (size_tree, pbitsize)) mode = BLKmode, *pbitsize = -1; - else - *pbitsize = tree_to_uhwi (size_tree); } *preversep = reverse_storage_order_for_component_p (exp); |