Richard Biener via Gcc-patches <[email protected]> writes:
> This changes us to maintain and compute (mis-)alignment info for
> the first element of a group only rather than for each DR when
> doing interleaving and for the earliest, first, or first in the SLP
> node (or any pair or all three of those) when SLP vectorizing.
>
> For this to work out the easiest way I have changed the accessors
> DR_MISALIGNMENT and DR_TARGET_ALIGNMENT to do the indirection to
> the first element rather than adjusting all callers.
> dr_misalignment is moved out-of-line and I'm not too fond of the
> poly-int dances there (any hints?), but basically we are now
> adjusting the first elements misalignment based on the DR_INIT
> difference.
>
> Bootstrap & regtest running on x86_64-unknown-linux-gnu.
>
> Richard.
>
> 2021-09-13 Richard Biener <[email protected]>
>
> * tree-vectorizer.h (dr_misalignment): Move out of line.
> (dr_target_alignment): New.
> (DR_TARGET_ALIGNMENT): Wrap dr_target_alignment.
> (set_dr_target_alignment): New.
> (SET_DR_TARGET_ALIGNMENT): Wrap set_dr_target_alignment.
> * tree-vect-data-refs.c (dr_misalignment): Compute and
> return the group members misalignment.
> (vect_compute_data_ref_alignment): Use SET_DR_TARGET_ALIGNMENT.
> (vect_analyze_data_refs_alignment): Compute alignment only
> for the first element of a DR group.
> (vect_slp_analyze_node_alignment): Likewise.
> ---
> gcc/tree-vect-data-refs.c | 65 ++++++++++++++++++++++++---------------
> gcc/tree-vectorizer.h | 24 ++++++++++-----
> 2 files changed, 57 insertions(+), 32 deletions(-)
>
> diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
> index 66e76132d14..b53d6a0b3f1 100644
> --- a/gcc/tree-vect-data-refs.c
> +++ b/gcc/tree-vect-data-refs.c
> @@ -887,6 +887,36 @@ vect_slp_analyze_instance_dependence (vec_info *vinfo,
> slp_instance instance)
> return res;
> }
>
> +/* Return the misalignment of DR_INFO. */
> +
> +int
> +dr_misalignment (dr_vec_info *dr_info)
> +{
> + if (STMT_VINFO_GROUPED_ACCESS (dr_info->stmt))
> + {
> + dr_vec_info *first_dr
> + = STMT_VINFO_DR_INFO (DR_GROUP_FIRST_ELEMENT (dr_info->stmt));
> + int misalign = first_dr->misalignment;
> + gcc_assert (misalign != DR_MISALIGNMENT_UNINITIALIZED);
> + if (misalign == DR_MISALIGNMENT_UNKNOWN)
> + return misalign;
> + poly_offset_int diff = (wi::to_poly_offset (DR_INIT (dr_info->dr))
> + - wi::to_poly_offset (DR_INIT (first_dr->dr)));
> + poly_int64 mispoly = misalign + diff.to_constant ().to_shwi ();
> + bool res = known_misalignment (mispoly,
> + first_dr->target_alignment.to_constant (),
> + &misalign);
> + gcc_assert (res);
> + return misalign;
Yeah, not too keen on the to_constants here. The one on diff looks
redundant -- you could just use diff.force_shwi () instead, and
keep everything poly_int.
For the known_misalignment I think we should use:
if (!can_div_trunc_p (mispoly, first_dr->target_alignment,
"ient, &misalign))
misalign = DR_MISALIGNMENT_UNKNOWN;
return misalign;
There are then no to_constant assumptions.
Thanks,
Richard