Fix scheduling undeterminism from sorting with DEBUG_INSNs
authorMaxim Kuvyrkov <maxim.kuvyrkov@linaro.org>
Sun, 1 Feb 2015 07:29:35 +0000 (07:29 +0000)
committerMaxim Kuvyrkov <mkuvyrkov@gcc.gnu.org>
Sun, 1 Feb 2015 07:29:35 +0000 (07:29 +0000)
* haifa-sched.c (INSN_RFS_DEBUG_ORIG_ORDER): New access macro.
(rank_for_schedule_debug): Split from ...
(rank_for_schedule): ... this.
(ready_sort): Sort DEBUG_INSNs separately from normal INSNs.
* sched-int.h (struct _haifa_insn_data): New field rfs_debug_orig_order.

From-SVN: r220316

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

index 0618d835f9a453b012378ab2e7c016d11a6baf32..504c741b3be2cee89ae45e329d05ec6256b5b9ab 100644 (file)
@@ -1,3 +1,11 @@
+2015-02-01  Maxim Kuvyrkov  <maxim.kuvyrkov@linaro.org>
+
+       * haifa-sched.c (INSN_RFS_DEBUG_ORIG_ORDER): New access macro.
+       (rank_for_schedule_debug): Split from ...
+       (rank_for_schedule): ... this.
+       (ready_sort): Sort DEBUG_INSNs separately from normal INSNs.
+       * sched-int.h (struct _haifa_insn_data): New field rfs_debug_orig_order.
+
 2015-01-31  Sandra Loosemore  <sandra@codesourcery.com>
 
        * doc/md.texi (Machine Constraints): Alphabetize table by target.
index 795ff79e8985c736a9346a912e2c2359375bf329..75d24217dbe187530e65fa2e874db9a081121a2c 100644 (file)
@@ -250,6 +250,10 @@ struct common_sched_info_def *common_sched_info;
 /* The minimal value of the INSN_TICK of an instruction.  */
 #define MIN_TICK (-max_insn_queue_index)
 
+/* Original order of insns in the ready list.
+   Used to keep order of normal insns while separating DEBUG_INSNs.  */
+#define INSN_RFS_DEBUG_ORIG_ORDER(INSN) (HID (INSN)->rfs_debug_orig_order)
+
 /* The deciding reason for INSN's place in the ready list.  */
 #define INSN_LAST_RFS_WIN(INSN) (HID (INSN)->last_rfs_win)
 
@@ -2597,6 +2601,27 @@ rfs_result (enum rfs_decision decision, int result, rtx tmp, rtx tmp2)
   return result;
 }
 
+/* Sorting predicate to move DEBUG_INSNs to the top of ready list, while
+   keeping normal insns in original order.  */
+
+static int
+rank_for_schedule_debug (const void *x, const void *y)
+{
+  rtx_insn *tmp = *(rtx_insn * const *) y;
+  rtx_insn *tmp2 = *(rtx_insn * const *) x;
+
+  /* Schedule debug insns as early as possible.  */
+  if (DEBUG_INSN_P (tmp) && !DEBUG_INSN_P (tmp2))
+    return rfs_result (RFS_DEBUG, -1, tmp, tmp2);
+  else if (!DEBUG_INSN_P (tmp) && DEBUG_INSN_P (tmp2))
+    return rfs_result (RFS_DEBUG, 1, tmp, tmp2);
+  else if (DEBUG_INSN_P (tmp) && DEBUG_INSN_P (tmp2))
+    return rfs_result (RFS_DEBUG, INSN_LUID (tmp) - INSN_LUID (tmp2),
+                      tmp, tmp2);
+  else
+    return INSN_RFS_DEBUG_ORIG_ORDER (tmp2) - INSN_RFS_DEBUG_ORIG_ORDER (tmp);
+}
+
 /* Returns a positive value if x is preferred; returns a negative value if
    y is preferred.  Should never return 0, since that will make the sort
    unstable.  */
@@ -2609,18 +2634,6 @@ rank_for_schedule (const void *x, const void *y)
   int tmp_class, tmp2_class;
   int val, priority_val, info_val, diff;
 
-  if (MAY_HAVE_DEBUG_INSNS)
-    {
-      /* Schedule debug insns as early as possible.  */
-      if (DEBUG_INSN_P (tmp) && !DEBUG_INSN_P (tmp2))
-       return rfs_result (RFS_DEBUG, -1, tmp, tmp2);
-      else if (!DEBUG_INSN_P (tmp) && DEBUG_INSN_P (tmp2))
-       return rfs_result (RFS_DEBUG, 1, tmp, tmp2);
-      else if (DEBUG_INSN_P (tmp) && DEBUG_INSN_P (tmp2))
-       return rfs_result (RFS_DEBUG, INSN_LUID (tmp) - INSN_LUID (tmp2),
-                          tmp, tmp2);
-    }
-
   if (live_range_shrinkage_p)
     {
       /* Don't use SCHED_PRESSURE_MODEL -- it results in much worse
@@ -3075,13 +3088,21 @@ ready_sort (struct ready_list *ready)
 {
   int i;
   rtx_insn **first = ready_lastpos (ready);
+  int n_ready_non_debug = ready->n_ready;
 
-  if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
+  for (i = 0; i < ready->n_ready; ++i)
     {
-      for (i = 0; i < ready->n_ready; i++)
-       if (!DEBUG_INSN_P (first[i]))
-         setup_insn_reg_pressure_info (first[i]);
+      if (DEBUG_INSN_P (first[i]))
+       --n_ready_non_debug;
+      else
+       {
+         INSN_RFS_DEBUG_ORIG_ORDER (first[i]) = i;
+
+         if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
+           setup_insn_reg_pressure_info (first[i]);
+       }
     }
+
   if (sched_pressure == SCHED_PRESSURE_MODEL
       && model_curr_point < model_num_insns)
     model_set_excess_costs (first, ready->n_ready);
@@ -3090,10 +3111,17 @@ ready_sort (struct ready_list *ready)
   if (sched_verbose >= 4)
     stats1 = rank_for_schedule_stats;
 
-  if (ready->n_ready == 2)
-    swap_sort (first, ready->n_ready);
-  else if (ready->n_ready > 2)
-    qsort (first, ready->n_ready, sizeof (rtx), rank_for_schedule);
+  if (n_ready_non_debug < ready->n_ready)
+    /* Separate DEBUG_INSNS from normal insns.  DEBUG_INSNs go to the end
+       of array.  */
+    qsort (first, ready->n_ready, sizeof (rtx), rank_for_schedule_debug);
+  else
+    {
+      if (n_ready_non_debug == 2)
+       swap_sort (first, n_ready_non_debug);
+      else if (n_ready_non_debug > 2)
+       qsort (first, n_ready_non_debug, sizeof (rtx), rank_for_schedule);
+    }
 
   if (sched_verbose >= 4)
     {
index 28e95ea97b6e7c5051e21ac915618327cbfe4f7e..1b9f8d1d74f08b939323162f5a25b5c0a2cd04c9 100644 (file)
@@ -917,6 +917,9 @@ struct _haifa_insn_data
   int reg_pressure_excess_cost_change;
   int model_index;
 
+  /* Original order of insns in the ready list.  */
+  int rfs_debug_orig_order;
+
   /* The deciding reason for INSN's place in the ready list.  */
   int last_rfs_win;