Revert r253399:
authorWilco Dijkstra <wdijkstr@arm.com>
Wed, 4 Oct 2017 16:40:44 +0000 (16:40 +0000)
committerWilco Dijkstra <wilco@gcc.gnu.org>
Wed, 4 Oct 2017 16:40:44 +0000 (16:40 +0000)
PR rtl-optimization/82396
* haifa-sched.c (autopref_multipass_init): Simplify
initialization.
(autopref_rank_data): Simplify sort order.
* sched-int.h (autopref_multipass_data_): Remove
multi_mem_insn_p, min_offset and max_offset.

From-SVN: r253419

gcc/ChangeLog
gcc/haifa-sched.c
gcc/sched-int.h

index 7ad2fe0ba9b3ffe4743daea2da7b02502402197e..5167a14788fc503303e589de56b03adf66965352 100644 (file)
@@ -1,3 +1,14 @@
+2017-10-04  Wilco Dijkstra  <wdijkstr@arm.com>
+
+       Revert r253399:
+
+       PR rtl-optimization/82396
+       * haifa-sched.c (autopref_multipass_init): Simplify
+       initialization.
+       (autopref_rank_data): Simplify sort order.
+       * sched-int.h (autopref_multipass_data_): Remove
+       multi_mem_insn_p, min_offset and max_offset.
+
 2017-10-04  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
 
        * doc/sourcebuild.texi: Document vect_peeling_profitable.
index 77ba8c5292a0801bbbcb35ed61ab3040015f6677..549e8961411ecd0a04ac3b24ba78b5d53e63258a 100644 (file)
@@ -5568,7 +5568,9 @@ autopref_multipass_init (const rtx_insn *insn, int write)
 
   gcc_assert (data->status == AUTOPREF_MULTIPASS_DATA_UNINITIALIZED);
   data->base = NULL_RTX;
-  data->offset = 0;
+  data->min_offset = 0;
+  data->max_offset = 0;
+  data->multi_mem_insn_p = false;
   /* Set insn entry initialized, but not relevant for auto-prefetcher.  */
   data->status = AUTOPREF_MULTIPASS_DATA_IRRELEVANT;
 
@@ -5583,9 +5585,10 @@ autopref_multipass_init (const rtx_insn *insn, int write)
     {
       int n_elems = XVECLEN (pat, 0);
 
-      int i, offset;
-      rtx base, prev_base = NULL_RTX;
-      int min_offset = INT_MAX;
+      int i = 0;
+      rtx prev_base = NULL_RTX;
+      int min_offset = 0;
+      int max_offset = 0;
 
       for (i = 0; i < n_elems; i++)
        {
@@ -5593,23 +5596,38 @@ autopref_multipass_init (const rtx_insn *insn, int write)
          if (GET_CODE (set) != SET)
            return;
 
+         rtx base = NULL_RTX;
+         int offset = 0;
          if (!analyze_set_insn_for_autopref (set, write, &base, &offset))
            return;
 
+         if (i == 0)
+           {
+             prev_base = base;
+             min_offset = offset;
+             max_offset = offset;
+           }
          /* Ensure that all memory operations in the PARALLEL use the same
             base register.  */
-         if (i > 0 && REGNO (base) != REGNO (prev_base))
+         else if (REGNO (base) != REGNO (prev_base))
            return;
-         prev_base = base;
-         min_offset = MIN (min_offset, offset);
+         else
+           {
+             min_offset = MIN (min_offset, offset);
+             max_offset = MAX (max_offset, offset);
+           }
        }
 
-      /* If we reached here then we have a valid PARALLEL of multiple memory ops
-        with prev_base as the base and min_offset containing the offset.  */
+      /* If we reached here then we have a valid PARALLEL of multiple memory
+        ops with prev_base as the base and min_offset and max_offset
+        containing the offsets range.  */
       gcc_assert (prev_base);
       data->base = prev_base;
-      data->offset = min_offset;
+      data->min_offset = min_offset;
+      data->max_offset = max_offset;
+      data->multi_mem_insn_p = true;
       data->status = AUTOPREF_MULTIPASS_DATA_NORMAL;
+
       return;
     }
 
@@ -5619,7 +5637,7 @@ autopref_multipass_init (const rtx_insn *insn, int write)
     return;
 
   if (!analyze_set_insn_for_autopref (set, write, &data->base,
-                                      &data->offset))
+                                      &data->min_offset))
     return;
 
   /* This insn is relevant for the auto-prefetcher.
@@ -5628,6 +5646,63 @@ autopref_multipass_init (const rtx_insn *insn, int write)
   data->status = AUTOPREF_MULTIPASS_DATA_NORMAL;
 }
 
+
+/* Helper for autopref_rank_for_schedule.  Given the data of two
+   insns relevant to the auto-prefetcher modelling code DATA1 and DATA2
+   return their comparison result.  Return 0 if there is no sensible
+   ranking order for the two insns.  */
+
+static int
+autopref_rank_data (autopref_multipass_data_t data1,
+                    autopref_multipass_data_t data2)
+{
+  /* Simple case when both insns are simple single memory ops.  */
+  if (!data1->multi_mem_insn_p && !data2->multi_mem_insn_p)
+    return data1->min_offset - data2->min_offset;
+
+  /* Two load/store multiple insns.  Return 0 if the offset ranges
+     overlap and the difference between the minimum offsets otherwise.  */
+  else if (data1->multi_mem_insn_p && data2->multi_mem_insn_p)
+    {
+      int min1 = data1->min_offset;
+      int max1 = data1->max_offset;
+      int min2 = data2->min_offset;
+      int max2 = data2->max_offset;
+
+      if (max1 < min2 || min1 > max2)
+       return min1 - min2;
+      else
+       return 0;
+    }
+
+  /* The other two cases is a pair of a load/store multiple and
+     a simple memory op.  Return 0 if the single op's offset is within the
+     range of the multi-op insn and the difference between the single offset
+     and the minimum offset of the multi-set insn otherwise.  */
+  else if (data1->multi_mem_insn_p && !data2->multi_mem_insn_p)
+    {
+      int max1 = data1->max_offset;
+      int min1 = data1->min_offset;
+
+      if (data2->min_offset >= min1
+         && data2->min_offset <= max1)
+       return 0;
+      else
+       return min1 - data2->min_offset;
+    }
+  else
+    {
+      int max2 = data2->max_offset;
+      int min2 = data2->min_offset;
+
+      if (data1->min_offset >= min2
+         && data1->min_offset <= max2)
+       return 0;
+      else
+       return data1->min_offset - min2;
+    }
+}
+
 /* Helper function for rank_for_schedule sorting.  */
 static int
 autopref_rank_for_schedule (const rtx_insn *insn1, const rtx_insn *insn2)
@@ -5650,7 +5725,7 @@ autopref_rank_for_schedule (const rtx_insn *insn1, const rtx_insn *insn2)
       int irrel2 = data2->status == AUTOPREF_MULTIPASS_DATA_IRRELEVANT;
 
       if (!irrel1 && !irrel2)
-       r = data1->offset - data2->offset;
+       r = autopref_rank_data (data1, data2);
       else
        r = irrel2 - irrel1;
     }
@@ -5678,7 +5753,7 @@ autopref_multipass_dfa_lookahead_guard_1 (const rtx_insn *insn1,
     return 0;
 
   if (rtx_equal_p (data1->base, data2->base)
-      && data1->offset > data2->offset)
+      && autopref_rank_data (data1, data2) > 0)
     {
       if (sched_verbose >= 2)
        {
index 98174f7ce308f75ddc9056bb0dab23812db63291..2af8f9fc32c0085c18511bbc83ad52c6ec31f671 100644 (file)
@@ -819,8 +819,15 @@ struct autopref_multipass_data_
   /* Base part of memory address.  */
   rtx base;
 
-  /* Memory offset from the base.  */
-  int offset;
+  /* Memory offsets from the base.  For single simple sets
+     only min_offset is valid.  For multi-set insns min_offset
+     and max_offset record the minimum and maximum offsets from the same
+     base among the sets inside the PARALLEL.  */
+  int min_offset;
+  int max_offset;
+
+  /* True if this is a load/store-multiple instruction.  */
+  bool multi_mem_insn_p;
 
   /* Entry status.  */
   enum autopref_multipass_data_status status;