The following makes us use the SLP graph and its recorded vector types to perform alignment analysis even for loops. This avoids accessing STMT_VINFO_VECTYPE we want to get rid of.
v2 adjusts alignment peeling to ignore DRs that are dead because of conditional store pattern recognition. Bootstapped on x86_64-unknown-linux-gnu, testing in progress. * tree-vect-data-refs.cc (vect_analyze_data_refs_alignment): Walk over SLP instances and call vect_slp_analyze_instance_alignment. (vect_slp_analyze_dr_alignment): Split out from ... (vect_slp_analyze_node_alignment): ... here. Handle non-grouped access SLP nodes. (vect_slp_analyze_instance_alignment): Adjust for dropped return value from the above. (vect_relevant_for_alignment_p): Dead DRs are not relevant. (vect_enhance_data_refs_alignment): Ignore DRs not relevant for alignment when computing how many same-align refs exist. --- gcc/tree-vect-data-refs.cc | 95 ++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 45 deletions(-) diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc index a24ddfbc384..0601d592ca3 100644 --- a/gcc/tree-vect-data-refs.cc +++ b/gcc/tree-vect-data-refs.cc @@ -1754,6 +1754,12 @@ vect_relevant_for_alignment_p (dr_vec_info *dr_info) && !STMT_VINFO_GROUPED_ACCESS (stmt_info)) return false; + /* When the DR is dead, which can happen for conditional store + pattern recognized refs, it is no longer relevant (and we didn't + even analyze its alignment). */ + if (dr_info->misalignment == DR_MISALIGNMENT_UNINITIALIZED) + return false; + return true; } @@ -2391,15 +2397,17 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) for (unsigned j = i0; j < i; ++j) { dr_vec_info *dr_infoj = loop_vinfo->lookup_dr (datarefs[j]); - for (unsigned k = i0; k < i; ++k) - { - if (k == j) - continue; - dr_vec_info *dr_infok = loop_vinfo->lookup_dr (datarefs[k]); - if (vect_dr_aligned_if_related_peeled_dr_is (dr_infok, - dr_infoj)) - n_same_align_refs[j]++; - } + if (vect_relevant_for_alignment_p (dr_infoj)) + for (unsigned k = i0; k < i; ++k) + { + if (k == j) + continue; + dr_vec_info *dr_infok = loop_vinfo->lookup_dr (datarefs[k]); + if (vect_relevant_for_alignment_p (dr_infok) + && vect_dr_aligned_if_related_peeled_dr_is (dr_infok, + dr_infoj)) + n_same_align_refs[j]++; + } } i0 = i; } @@ -3083,51 +3091,32 @@ vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo) { DUMP_VECT_SCOPE ("vect_analyze_data_refs_alignment"); - vec<data_reference_p> datarefs = LOOP_VINFO_DATAREFS (loop_vinfo); - struct data_reference *dr; - unsigned int i; - vect_record_base_alignments (loop_vinfo); - FOR_EACH_VEC_ELT (datarefs, i, dr) - { - dr_vec_info *dr_info = loop_vinfo->lookup_dr (dr); - if (STMT_VINFO_VECTORIZABLE (dr_info->stmt)) - { - if (STMT_VINFO_GROUPED_ACCESS (dr_info->stmt) - && DR_GROUP_FIRST_ELEMENT (dr_info->stmt) != dr_info->stmt) - continue; - - vect_compute_data_ref_alignment (loop_vinfo, dr_info, - STMT_VINFO_VECTYPE (dr_info->stmt)); - } - } + for (slp_instance inst : LOOP_VINFO_SLP_INSTANCES (loop_vinfo)) + vect_slp_analyze_instance_alignment (loop_vinfo, inst); return opt_result::success (); } -/* Analyze alignment of DRs of stmts in NODE. */ +/* Analyze alignment of a DRs. */ -static bool -vect_slp_analyze_node_alignment (vec_info *vinfo, slp_tree node) +static void +vect_slp_analyze_dr_alignment (vec_info *vinfo, dr_vec_info *dr_info, + tree vectype) { - /* Alignment is maintained in the first element of the group. */ - stmt_vec_info first_stmt_info = SLP_TREE_SCALAR_STMTS (node)[0]; - first_stmt_info = DR_GROUP_FIRST_ELEMENT (first_stmt_info); - dr_vec_info *dr_info = STMT_VINFO_DR_INFO (first_stmt_info); - tree vectype = SLP_TREE_VECTYPE (node); poly_uint64 vector_alignment = exact_div (targetm.vectorize.preferred_vector_alignment (vectype), BITS_PER_UNIT); if (dr_info->misalignment == DR_MISALIGNMENT_UNINITIALIZED) - vect_compute_data_ref_alignment (vinfo, dr_info, SLP_TREE_VECTYPE (node)); + vect_compute_data_ref_alignment (vinfo, dr_info, vectype); /* Re-analyze alignment when we're facing a vectorization with a bigger alignment requirement. */ else if (known_lt (dr_info->target_alignment, vector_alignment)) { poly_uint64 old_target_alignment = dr_info->target_alignment; int old_misalignment = dr_info->misalignment; - vect_compute_data_ref_alignment (vinfo, dr_info, SLP_TREE_VECTYPE (node)); + vect_compute_data_ref_alignment (vinfo, dr_info, vectype); /* But keep knowledge about a smaller alignment. */ if (old_misalignment != DR_MISALIGNMENT_UNKNOWN && dr_info->misalignment == DR_MISALIGNMENT_UNKNOWN) @@ -3136,9 +3125,28 @@ vect_slp_analyze_node_alignment (vec_info *vinfo, slp_tree node) dr_info->misalignment = old_misalignment; } } - /* When we ever face unordered target alignments the first one wins in terms - of analyzing and the other will become unknown in dr_misalignment. */ - return true; +} + + +/* Analyze alignment of DRs of stmts in NODE. */ + +static void +vect_slp_analyze_node_alignment (vec_info *vinfo, slp_tree node) +{ + tree vectype = SLP_TREE_VECTYPE (node); + for (stmt_vec_info stmt_info : SLP_TREE_SCALAR_STMTS (node)) + { + if (STMT_VINFO_GROUPED_ACCESS (stmt_info)) + { + /* Alignment is maintained in the first element of the group. */ + stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info); + dr_vec_info *dr_info = STMT_VINFO_DR_INFO (stmt_info); + vect_slp_analyze_dr_alignment (vinfo, dr_info, vectype); + return; + } + dr_vec_info *dr_info = STMT_VINFO_DR_INFO (stmt_info); + vect_slp_analyze_dr_alignment (vinfo, dr_info, vectype); + } } /* Function vect_slp_analyze_instance_alignment @@ -3155,13 +3163,10 @@ vect_slp_analyze_instance_alignment (vec_info *vinfo, slp_tree node; unsigned i; FOR_EACH_VEC_ELT (SLP_INSTANCE_LOADS (instance), i, node) - if (! vect_slp_analyze_node_alignment (vinfo, node)) - return false; + vect_slp_analyze_node_alignment (vinfo, node); - if (SLP_INSTANCE_KIND (instance) == slp_inst_kind_store - && ! vect_slp_analyze_node_alignment - (vinfo, SLP_INSTANCE_TREE (instance))) - return false; + if (SLP_INSTANCE_KIND (instance) == slp_inst_kind_store) + vect_slp_analyze_node_alignment (vinfo, SLP_INSTANCE_TREE (instance)); return true; } -- 2.43.0