Message ID | mpty2wmgska.fsf@arm.com |
---|---|
State | New |
Headers | show |
Series | Improve vector alias checks for WAR and WAW dependencies | expand |
On Mon, Nov 11, 2019 at 7:46 PM Richard Sandiford <richard.sandiford@arm.com> wrote: > > The two users of tree-data-ref's runtime alias checks both canonicalise > the order of the dr_with_seg_lens in a pair before passing them to > prune_runtime_alias_test_list. It's more convenient for later patches > if prune_runtime_alias_test_list does that itself. OK. > > 2019-11-11 Richard Sandiford <richard.sandiford@arm.com> > > gcc/ > * tree-data-ref.c (prune_runtime_alias_test_list): Sort the > two accesses in each dr_with_seg_len_pair_t before trying to > combine separate dr_with_seg_len_pair_ts. > * tree-loop-distribution.c (compute_alias_check_pairs): Don't do > that here. > * tree-vect-data-refs.c (vect_prune_runtime_alias_test_list): Likewise. > > Index: gcc/tree-data-ref.c > =================================================================== > --- gcc/tree-data-ref.c 2019-07-18 09:22:13.893767915 +0100 > +++ gcc/tree-data-ref.c 2019-11-11 18:30:43.203244558 +0000 > @@ -1487,13 +1487,32 @@ comp_dr_with_seg_len_pair (const void *p > prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *alias_pairs, > poly_uint64) > { > + /* Canonicalize each pair so that the base components are ordered wrt > + data_ref_compare_tree. This allows the loop below to merge more > + cases. */ > + unsigned int i; > + dr_with_seg_len_pair_t *alias_pair; > + FOR_EACH_VEC_ELT (*alias_pairs, i, alias_pair) > + { > + data_reference_p dr_a = alias_pair->first.dr; > + data_reference_p dr_b = alias_pair->second.dr; > + int comp_res = data_ref_compare_tree (DR_BASE_ADDRESS (dr_a), > + DR_BASE_ADDRESS (dr_b)); > + if (comp_res == 0) > + comp_res = data_ref_compare_tree (DR_OFFSET (dr_a), DR_OFFSET (dr_b)); > + if (comp_res == 0) > + comp_res = data_ref_compare_tree (DR_INIT (dr_a), DR_INIT (dr_b)); > + if (comp_res > 0) > + std::swap (alias_pair->first, alias_pair->second); > + } > + > /* Sort the collected data ref pairs so that we can scan them once to > combine all possible aliasing checks. */ > alias_pairs->qsort (comp_dr_with_seg_len_pair); > > /* Scan the sorted dr pairs and check if we can combine alias checks > of two neighboring dr pairs. */ > - for (size_t i = 1; i < alias_pairs->length (); ++i) > + for (i = 1; i < alias_pairs->length (); ++i) > { > /* Deal with two ddrs (dr_a1, dr_b1) and (dr_a2, dr_b2). */ > dr_with_seg_len *dr_a1 = &(*alias_pairs)[i-1].first, > Index: gcc/tree-loop-distribution.c > =================================================================== > --- gcc/tree-loop-distribution.c 2019-07-10 19:41:20.539944929 +0100 > +++ gcc/tree-loop-distribution.c 2019-11-11 18:30:43.207244530 +0000 > @@ -2457,12 +2457,6 @@ compute_alias_check_pairs (class loop *l > struct data_reference *dr_a = DDR_A (ddr); > struct data_reference *dr_b = DDR_B (ddr); > tree seg_length_a, seg_length_b; > - int comp_res = data_ref_compare_tree (DR_BASE_ADDRESS (dr_a), > - DR_BASE_ADDRESS (dr_b)); > - > - if (comp_res == 0) > - comp_res = data_ref_compare_tree (DR_OFFSET (dr_a), DR_OFFSET (dr_b)); > - gcc_assert (comp_res != 0); > > if (latch_dominated_by_data_ref (loop, dr_a)) > seg_length_a = data_ref_segment_size (dr_a, niters_plus_one); > @@ -2485,10 +2479,6 @@ compute_alias_check_pairs (class loop *l > (dr_with_seg_len (dr_a, seg_length_a, access_size_a, align_a), > dr_with_seg_len (dr_b, seg_length_b, access_size_b, align_b)); > > - /* Canonicalize pairs by sorting the two DR members. */ > - if (comp_res > 0) > - std::swap (dr_with_seg_len_pair.first, dr_with_seg_len_pair.second); > - > comp_alias_pairs->safe_push (dr_with_seg_len_pair); > } > > Index: gcc/tree-vect-data-refs.c > =================================================================== > --- gcc/tree-vect-data-refs.c 2019-11-08 16:06:18.948980179 +0000 > +++ gcc/tree-vect-data-refs.c 2019-11-11 18:30:43.207244530 +0000 > @@ -3478,7 +3478,6 @@ vect_prune_runtime_alias_test_list (loop > /* First, we collect all data ref pairs for aliasing checks. */ > FOR_EACH_VEC_ELT (may_alias_ddrs, i, ddr) > { > - int comp_res; > poly_uint64 lower_bound; > tree segment_length_a, segment_length_b; > unsigned HOST_WIDE_INT access_size_a, access_size_b; > @@ -3594,14 +3593,11 @@ vect_prune_runtime_alias_test_list (loop > align_a = vect_vfa_align (dr_info_a); > align_b = vect_vfa_align (dr_info_b); > > - comp_res = data_ref_compare_tree (DR_BASE_ADDRESS (dr_info_a->dr), > - DR_BASE_ADDRESS (dr_info_b->dr)); > - if (comp_res == 0) > - comp_res = data_ref_compare_tree (DR_OFFSET (dr_info_a->dr), > - DR_OFFSET (dr_info_b->dr)); > - > /* See whether the alias is known at compilation time. */ > - if (comp_res == 0 > + if (operand_equal_p (DR_BASE_ADDRESS (dr_info_a->dr), > + DR_BASE_ADDRESS (dr_info_b->dr), 0) > + && operand_equal_p (DR_OFFSET (dr_info_a->dr), > + DR_OFFSET (dr_info_b->dr), 0) > && TREE_CODE (DR_STEP (dr_info_a->dr)) == INTEGER_CST > && TREE_CODE (DR_STEP (dr_info_b->dr)) == INTEGER_CST > && poly_int_tree_p (segment_length_a) > @@ -3640,10 +3636,6 @@ vect_prune_runtime_alias_test_list (loop > dr_with_seg_len (dr_info_b->dr, segment_length_b, > access_size_b, align_b)); > > - /* Canonicalize pairs by sorting the two DR members. */ > - if (comp_res > 0) > - std::swap (dr_with_seg_len_pair.first, dr_with_seg_len_pair.second); > - > comp_alias_ddrs.safe_push (dr_with_seg_len_pair); > } >
Index: gcc/tree-data-ref.c =================================================================== --- gcc/tree-data-ref.c 2019-07-18 09:22:13.893767915 +0100 +++ gcc/tree-data-ref.c 2019-11-11 18:30:43.203244558 +0000 @@ -1487,13 +1487,32 @@ comp_dr_with_seg_len_pair (const void *p prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *alias_pairs, poly_uint64) { + /* Canonicalize each pair so that the base components are ordered wrt + data_ref_compare_tree. This allows the loop below to merge more + cases. */ + unsigned int i; + dr_with_seg_len_pair_t *alias_pair; + FOR_EACH_VEC_ELT (*alias_pairs, i, alias_pair) + { + data_reference_p dr_a = alias_pair->first.dr; + data_reference_p dr_b = alias_pair->second.dr; + int comp_res = data_ref_compare_tree (DR_BASE_ADDRESS (dr_a), + DR_BASE_ADDRESS (dr_b)); + if (comp_res == 0) + comp_res = data_ref_compare_tree (DR_OFFSET (dr_a), DR_OFFSET (dr_b)); + if (comp_res == 0) + comp_res = data_ref_compare_tree (DR_INIT (dr_a), DR_INIT (dr_b)); + if (comp_res > 0) + std::swap (alias_pair->first, alias_pair->second); + } + /* Sort the collected data ref pairs so that we can scan them once to combine all possible aliasing checks. */ alias_pairs->qsort (comp_dr_with_seg_len_pair); /* Scan the sorted dr pairs and check if we can combine alias checks of two neighboring dr pairs. */ - for (size_t i = 1; i < alias_pairs->length (); ++i) + for (i = 1; i < alias_pairs->length (); ++i) { /* Deal with two ddrs (dr_a1, dr_b1) and (dr_a2, dr_b2). */ dr_with_seg_len *dr_a1 = &(*alias_pairs)[i-1].first, Index: gcc/tree-loop-distribution.c =================================================================== --- gcc/tree-loop-distribution.c 2019-07-10 19:41:20.539944929 +0100 +++ gcc/tree-loop-distribution.c 2019-11-11 18:30:43.207244530 +0000 @@ -2457,12 +2457,6 @@ compute_alias_check_pairs (class loop *l struct data_reference *dr_a = DDR_A (ddr); struct data_reference *dr_b = DDR_B (ddr); tree seg_length_a, seg_length_b; - int comp_res = data_ref_compare_tree (DR_BASE_ADDRESS (dr_a), - DR_BASE_ADDRESS (dr_b)); - - if (comp_res == 0) - comp_res = data_ref_compare_tree (DR_OFFSET (dr_a), DR_OFFSET (dr_b)); - gcc_assert (comp_res != 0); if (latch_dominated_by_data_ref (loop, dr_a)) seg_length_a = data_ref_segment_size (dr_a, niters_plus_one); @@ -2485,10 +2479,6 @@ compute_alias_check_pairs (class loop *l (dr_with_seg_len (dr_a, seg_length_a, access_size_a, align_a), dr_with_seg_len (dr_b, seg_length_b, access_size_b, align_b)); - /* Canonicalize pairs by sorting the two DR members. */ - if (comp_res > 0) - std::swap (dr_with_seg_len_pair.first, dr_with_seg_len_pair.second); - comp_alias_pairs->safe_push (dr_with_seg_len_pair); } Index: gcc/tree-vect-data-refs.c =================================================================== --- gcc/tree-vect-data-refs.c 2019-11-08 16:06:18.948980179 +0000 +++ gcc/tree-vect-data-refs.c 2019-11-11 18:30:43.207244530 +0000 @@ -3478,7 +3478,6 @@ vect_prune_runtime_alias_test_list (loop /* First, we collect all data ref pairs for aliasing checks. */ FOR_EACH_VEC_ELT (may_alias_ddrs, i, ddr) { - int comp_res; poly_uint64 lower_bound; tree segment_length_a, segment_length_b; unsigned HOST_WIDE_INT access_size_a, access_size_b; @@ -3594,14 +3593,11 @@ vect_prune_runtime_alias_test_list (loop align_a = vect_vfa_align (dr_info_a); align_b = vect_vfa_align (dr_info_b); - comp_res = data_ref_compare_tree (DR_BASE_ADDRESS (dr_info_a->dr), - DR_BASE_ADDRESS (dr_info_b->dr)); - if (comp_res == 0) - comp_res = data_ref_compare_tree (DR_OFFSET (dr_info_a->dr), - DR_OFFSET (dr_info_b->dr)); - /* See whether the alias is known at compilation time. */ - if (comp_res == 0 + if (operand_equal_p (DR_BASE_ADDRESS (dr_info_a->dr), + DR_BASE_ADDRESS (dr_info_b->dr), 0) + && operand_equal_p (DR_OFFSET (dr_info_a->dr), + DR_OFFSET (dr_info_b->dr), 0) && TREE_CODE (DR_STEP (dr_info_a->dr)) == INTEGER_CST && TREE_CODE (DR_STEP (dr_info_b->dr)) == INTEGER_CST && poly_int_tree_p (segment_length_a) @@ -3640,10 +3636,6 @@ vect_prune_runtime_alias_test_list (loop dr_with_seg_len (dr_info_b->dr, segment_length_b, access_size_b, align_b)); - /* Canonicalize pairs by sorting the two DR members. */ - if (comp_res > 0) - std::swap (dr_with_seg_len_pair.first, dr_with_seg_len_pair.second); - comp_alias_ddrs.safe_push (dr_with_seg_len_pair); }