On Tue, 13 Oct 2020, Richard Sandiford wrote: > Richard Biener <rguent...@suse.de> writes: > > This makes the only consumer of STMT_VINFO_SAME_ALIGN_REFS, the > > loop peeling for alignment code, use locally computed data and > > then removes STMT_VINFO_SAME_ALIGN_REFS and its computation. > > The main benefit is reducing the dependence computation load > > by not asking for read-read dependences and getting rid of > > DR related info from stmt_vec_info. > > Nice. Some very minor comments below? > > > @@ -1130,6 +1129,45 @@ vect_compute_data_ref_alignment (vec_info *vinfo, > > dr_vec_info *dr_info) > > return; > > } > > > > +/* Return whether DR_INFO, which is related to DR_PEEL_INFO in > > + that it only differs in DR_INIT, is aligned if DR_PEEL_INFO > > + is made aligned via peeling. */ > > + > > +static bool > > +vect_dr_aligned_if_related_peeled_dr_is (dr_vec_info *dr_info, > > + dr_vec_info *dr_peel_info) > > +{ > > + if (known_ge (DR_TARGET_ALIGNMENT (dr_peel_info), > > + DR_TARGET_ALIGNMENT (dr_info))) > > Wondered here if multiple_p might be clearer/more precise than known_ge, > but of course non-power-of-2 alignments aren't much use?
Works for me. > > + { > > + poly_offset_int diff > > + = (wi::to_poly_offset (DR_INIT (dr_peel_info->dr)) > > + - wi::to_poly_offset (DR_INIT (dr_info->dr))); > > + if (known_eq (diff, 0) > > + || multiple_p (diff, DR_TARGET_ALIGNMENT (dr_info))) > > + return true; > > + } > > + return false; > > +} > > + > > +/* Return whether DR_INFO is aligned if DR_PEEL_INFO is made > > + aligned via peeling. */ > > + > > +static bool > > +vect_dr_aligned_if_peeled_dr_is (dr_vec_info *dr_info, > > + dr_vec_info *dr_peel_info) > > +{ > > + if (!operand_equal_p (DR_BASE_ADDRESS (dr_info->dr), > > + DR_BASE_ADDRESS (dr_peel_info->dr), 0) > > + || !operand_equal_p (DR_OFFSET (dr_info->dr), > > + DR_OFFSET (dr_peel_info->dr), 0) > > + || !operand_equal_p (DR_STEP (dr_info->dr), > > + DR_STEP (dr_peel_info->dr), 0)) > > + return false; > > + > > + return vect_dr_aligned_if_related_peeled_dr_is (dr_info, dr_peel_info); > > +} > > + > > /* Function vect_update_misalignment_for_peel. > > Sets DR_INFO's misalignment > > - to 0 if it has the same alignment as DR_PEEL_INFO, > > @@ -1146,18 +1184,10 @@ static void > > vect_update_misalignment_for_peel (dr_vec_info *dr_info, > > dr_vec_info *dr_peel_info, int npeel) > > { > > - unsigned int i; > > - vec<dr_p> same_aligned_drs; > > - struct data_reference *current_dr; > > - stmt_vec_info peel_stmt_info = dr_peel_info->stmt; > > - > > /* It can be assumed that if dr_info has the same alignment as dr_peel, > > it is aligned in the vector loop. */ > > - same_aligned_drs = STMT_VINFO_SAME_ALIGN_REFS (peel_stmt_info); > > - FOR_EACH_VEC_ELT (same_aligned_drs, i, current_dr) > > + if (vect_dr_aligned_if_peeled_dr_is (dr_info, dr_peel_info)) > > { > > - if (current_dr != dr_info->dr) > > - continue; > > gcc_assert (!known_alignment_for_access_p (dr_info) > > || !known_alignment_for_access_p (dr_peel_info) > > || (DR_MISALIGNMENT (dr_info) > > @@ -1572,6 +1602,43 @@ vect_peeling_supportable (loop_vec_info loop_vinfo, > > dr_vec_info *dr0_info, > > return true; > > } > > > > +/* Compare two data-references DRA and DRB to group them into chunks > > + with related alignment. */ > > + > > +static int > > +dr_align_group_sort_cmp (const void *dra_, const void *drb_) > > +{ > > + data_reference_p dra = *(data_reference_p *)const_cast<void *>(dra_); > > + data_reference_p drb = *(data_reference_p *)const_cast<void *>(drb_); > > + int cmp; > > + > > + /* Stabilize sort. */ > > + if (dra == drb) > > + return 0; > > + > > + /* Ordering of DRs according to base. */ > > + cmp = data_ref_compare_tree (DR_BASE_ADDRESS (dra), > > + DR_BASE_ADDRESS (drb)); > > + if (cmp != 0) > > + return cmp; > > + > > + /* And according to DR_OFFSET. */ > > + cmp = data_ref_compare_tree (DR_OFFSET (dra), DR_OFFSET (drb)); > > + if (cmp != 0) > > + return cmp; > > + > > + /* And after step. */ > > + cmp = data_ref_compare_tree (DR_STEP (dra), DR_STEP (drb)); > > + if (cmp != 0) > > + return cmp; > > + > > + /* Then sort after DR_INIT. In case of identical DRs sort after stmt > > UID. */ > > + cmp = data_ref_compare_tree (DR_INIT (dra), DR_INIT (drb)); > > + if (cmp == 0) > > + return gimple_uid (DR_STMT (dra)) < gimple_uid (DR_STMT (drb)) ? -1 : > > 1; > > + return cmp; > > +} > > + > > /* Function vect_enhance_data_refs_alignment > > > > This pass will use loop versioning and loop peeling in order to enhance > > @@ -1666,7 +1733,6 @@ vect_peeling_supportable (loop_vec_info loop_vinfo, > > dr_vec_info *dr0_info, > > opt_result > > vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) > > { > > - vec<data_reference_p> datarefs = LOOP_VINFO_DATAREFS (loop_vinfo); > > class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); > > enum dr_alignment_support supportable_dr_alignment; > > dr_vec_info *first_store = NULL; > > @@ -1680,7 +1746,7 @@ vect_enhance_data_refs_alignment (loop_vec_info > > loop_vinfo) > > bool one_misalignment_unknown = false; > > bool one_dr_unsupportable = false; > > dr_vec_info *unsupportable_dr_info = NULL; > > - unsigned int mis, same_align_drs_max = 0; > > + unsigned int mis, dr0_same_align_drs = 0, first_store_same_align_drs = 0; > > hash_table<peel_info_hasher> peeling_htab (1); > > > > DUMP_VECT_SCOPE ("vect_enhance_data_refs_alignment"); > > @@ -1689,6 +1755,54 @@ vect_enhance_data_refs_alignment (loop_vec_info > > loop_vinfo) > > LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo).truncate (0); > > LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) = 0; > > > > + if (LOOP_VINFO_DATAREFS (loop_vinfo).is_empty ()) > > + return opt_result::success (); > > + > > + /* Sort the vector of datarefs so DRs that have the same or dependent > > + alignment are next to each other. */ > > + auto_vec<data_reference_p> datarefs > > + = LOOP_VINFO_DATAREFS (loop_vinfo).copy (); > > + datarefs.qsort (dr_align_group_sort_cmp); > > + > > + /* Compute what was formerly STMT_VINFO_SAME_ALIGN_REFS.length (). */ > > Is this comment worth it? Hopefully in a couple of years noone will > know/need to know what on earth STMT_VINFO_SAME_ALIGN_REFS is/was. Heh, changed it to /* Compute the number of DRs that become aligned when we peel a dataref so it becomes aligned. */ > > + auto_vec<unsigned> n_same_align_refs (datarefs.length ()); > > + n_same_align_refs.quick_grow_cleared (datarefs.length ()); > > + unsigned i0; > > + for (i0 = 0; i0 < datarefs.length (); ++i0) > > + if (DR_BASE_ADDRESS (datarefs[i0])) > > + break; > > + for (i = i0 + 1; i <= datarefs.length (); ++i) > > + { > > + if (i == datarefs.length () > > + || !DR_BASE_ADDRESS (datarefs[i]) > > Can this happen? I thought the qsort would put all null bases first. True, I'll remove it. Richard.