[1/8] Move canonicalisation of dr_with_seg_len_pair_ts
diff mbox series

Message ID mpty2wmgska.fsf@arm.com
State New
Headers show
Series
  • Improve vector alias checks for WAR and WAW dependencies
Related show

Commit Message

Richard Sandiford Nov. 11, 2019, 6:45 p.m. UTC
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.


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.

Comments

Richard Biener Nov. 15, 2019, 11 a.m. UTC | #1
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);
>      }
>

Patch
diff mbox series

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);
     }