]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR rtl-optimization/42389 (ICE in advance_state_on_fence with sel-schd...
authorAndrey Belevantsev <abel@ispras.ru>
Tue, 24 Aug 2010 09:02:30 +0000 (13:02 +0400)
committerAndrey Belevantsev <abel@gcc.gnu.org>
Tue, 24 Aug 2010 09:02:30 +0000 (13:02 +0400)
Backport from mainline:
        PR rtl-optimization/42389
         * sel-sched.c (advance_one_cycle): Set FENCE_ISSUE_MORE
         to can_issue_more.
         (advance_state_on_fence): Likewise.
         (sel_target_adjust_priority): Print debug output only when
         sched_verbose >= 4, not 2.
         (get_expr_cost): Do not issue all unique insns on the next cycle.
         (fill_insns): Initialize can_issue_more from the value saved
         with the fence.
         * sel-sched-ir.c (flist_add): New parameter issue_more.
         Init FENCE_ISSUE_MORE with it.
         (merge_fences): Likewise.
         (init_fences): Update call to flist_add.
         (add_to_fences, add_clean_fence_to_fences)
         (add_dirty_fence_to_fences): Likewise.
         (move_fence_to_fences): Update call to merge_fences.
         (invoke_reorder_hooks): Do not reset can_issue_more on insns from
         sched groups.
         * sel-sched-ir.h (struct _fence): New field issue_more.
         (FENCE_ISSUE_MORE): New accessor macro.

From-SVN: r163508

gcc/ChangeLog
gcc/sel-sched-ir.c
gcc/sel-sched-ir.h
gcc/sel-sched.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr42389.c [new file with mode: 0644]

index b7be6f0394ea74cc53fdb25e6b525e22f475cd20..b22ce56160a669ba5c81077b2e021c52359a5d5a 100644 (file)
@@ -1,3 +1,30 @@
+2010-08-24  Andrey Belevantsev  <abel@ispras.ru>
+
+       Backport from mainline:
+       2010-01-14  Andrey Belevantsev  <abel@ispras.ru>
+           Alexander Monakov  <amonakov@ispras.ru>
+
+       PR rtl-optimization/42389
+       * sel-sched.c (advance_one_cycle): Set FENCE_ISSUE_MORE
+       to can_issue_more.
+       (advance_state_on_fence): Likewise.
+       (sel_target_adjust_priority): Print debug output only when
+       sched_verbose >= 4, not 2.
+       (get_expr_cost): Do not issue all unique insns on the next cycle.
+       (fill_insns): Initialize can_issue_more from the value saved
+       with the fence.
+       * sel-sched-ir.c (flist_add): New parameter issue_more.
+       Init FENCE_ISSUE_MORE with it.
+       (merge_fences): Likewise.
+       (init_fences): Update call to flist_add.
+       (add_to_fences, add_clean_fence_to_fences)
+       (add_dirty_fence_to_fences): Likewise.
+       (move_fence_to_fences): Update call to merge_fences.
+       (invoke_reorder_hooks): Do not reset can_issue_more on insns from
+       sched groups.
+       * sel-sched-ir.h (struct _fence): New field issue_more.
+       (FENCE_ISSUE_MORE): New accessor macro.
+
 2010-08-24  Andrey Belevantsev  <abel@ispras.ru>
 
        Backport from mainline:
index b8043071823289a169b414cd0c168c5e0f77c817..aa479f9cc840b6cf0eea1b548944efebcd6cae41 100644 (file)
@@ -258,10 +258,10 @@ init_fence_for_scheduling (fence_t f)
 
 /* Add new fence consisting of INSN and STATE to the list pointed to by LP.  */
 static void
-flist_add (flist_t *lp, insn_t insn, state_t state, deps_t dc, void *tc, 
-           insn_t last_scheduled_insn, VEC(rtx,gc) *executing_insns, 
-           int *ready_ticks, int ready_ticks_size, insn_t sched_next, 
-           int cycle, int cycle_issued_insns, 
+flist_add (flist_t *lp, insn_t insn, state_t state, deps_t dc, void *tc,
+           insn_t last_scheduled_insn, VEC(rtx,gc) *executing_insns,
+           int *ready_ticks, int ready_ticks_size, insn_t sched_next,
+           int cycle, int cycle_issued_insns, int issue_more,
            bool starts_cycle_p, bool after_stall_p)
 {
   fence_t f;
@@ -286,6 +286,7 @@ flist_add (flist_t *lp, insn_t insn, state_t state, deps_t dc, void *tc,
   FENCE_TC (f) = tc;
 
   FENCE_LAST_SCHEDULED_INSN (f) = last_scheduled_insn;
+  FENCE_ISSUE_MORE (f) = issue_more;
   FENCE_EXECUTING_INSNS (f) = executing_insns;
   FENCE_READY_TICKS (f) = ready_ticks;
   FENCE_READY_TICKS_SIZE (f) = ready_ticks_size;
@@ -616,8 +617,9 @@ init_fences (insn_t old_fence)
                  XCNEWVEC (int, ready_ticks_size), /* ready_ticks */
                  ready_ticks_size,
                  NULL_RTX /* sched_next */,
-                1 /* cycle */, 0 /* cycle_issued_insns */, 
-                1 /* starts_cycle_p */, 0 /* after_stall_p */);  
+                1 /* cycle */, 0 /* cycle_issued_insns */,
+                issue_rate, /* issue_more */
+                1 /* starts_cycle_p */, 0 /* after_stall_p */);
     }
 }
 
@@ -627,15 +629,15 @@ init_fences (insn_t old_fence)
    2) deps context and cycle is propagated from more probable edge;
    3) all other fields are set to corresponding constant values.  
 
-   INSN, STATE, DC, TC, LAST_SCHEDULED_INSN, EXECUTING_INSNS, 
-   READY_TICKS, READY_TICKS_SIZE, SCHED_NEXT, CYCLE and AFTER_STALL_P
-   are the corresponding fields of the second fence.  */
+   INSN, STATE, DC, TC, LAST_SCHEDULED_INSN, EXECUTING_INSNS,
+   READY_TICKS, READY_TICKS_SIZE, SCHED_NEXT, CYCLE, ISSUE_MORE
+   and AFTER_STALL_P are the corresponding fields of the second fence.  */
 static void
 merge_fences (fence_t f, insn_t insn,
              state_t state, deps_t dc, void *tc, 
               rtx last_scheduled_insn, VEC(rtx, gc) *executing_insns,
               int *ready_ticks, int ready_ticks_size,
-             rtx sched_next, int cycle, bool after_stall_p)
+             rtx sched_next, int cycle, int issue_more, bool after_stall_p)
 {
   insn_t last_scheduled_insn_old = FENCE_LAST_SCHEDULED_INSN (f);
 
@@ -665,6 +667,7 @@ merge_fences (fence_t f, insn_t insn,
         FENCE_CYCLE (f) = cycle;
 
       FENCE_LAST_SCHEDULED_INSN (f) = NULL;
+      FENCE_ISSUE_MORE (f) = issue_rate;
       VEC_free (rtx, gc, executing_insns);
       free (ready_ticks);
       if (FENCE_EXECUTING_INSNS (f))
@@ -696,6 +699,7 @@ merge_fences (fence_t f, insn_t insn,
           delete_target_context (tc);
   
           FENCE_LAST_SCHEDULED_INSN (f) = NULL;
+         FENCE_ISSUE_MORE (f) = issue_rate;
         }
       else
         if (candidate->src == BLOCK_FOR_INSN (last_scheduled_insn))
@@ -712,6 +716,7 @@ merge_fences (fence_t f, insn_t insn,
             FENCE_TC (f) = tc;
 
             FENCE_LAST_SCHEDULED_INSN (f) = last_scheduled_insn;
+           FENCE_ISSUE_MORE (f) = issue_more;
           }
         else
           {
@@ -795,10 +800,11 @@ merge_fences (fence_t f, insn_t insn,
    other parameters.  */
 static void
 add_to_fences (flist_tail_t new_fences, insn_t insn,
-               state_t state, deps_t dc, void *tc, rtx last_scheduled_insn, 
-               VEC(rtx, gc) *executing_insns, int *ready_ticks, 
-               int ready_ticks_size, rtx sched_next, int cycle, 
-               int cycle_issued_insns, bool starts_cycle_p, bool after_stall_p)
+               state_t state, deps_t dc, void *tc, rtx last_scheduled_insn,
+               VEC(rtx, gc) *executing_insns, int *ready_ticks,
+               int ready_ticks_size, rtx sched_next, int cycle,
+               int cycle_issued_insns, int issue_rate,
+              bool starts_cycle_p, bool after_stall_p)
 {
   fence_t f = flist_lookup (FLIST_TAIL_HEAD (new_fences), insn);
 
@@ -807,16 +813,16 @@ add_to_fences (flist_tail_t new_fences, insn_t insn,
       flist_add (FLIST_TAIL_TAILP (new_fences), insn, state, dc, tc,
                 last_scheduled_insn, executing_insns, ready_ticks, 
                  ready_ticks_size, sched_next, cycle, cycle_issued_insns,
-                starts_cycle_p, after_stall_p);
+                issue_rate, starts_cycle_p, after_stall_p);
 
       FLIST_TAIL_TAILP (new_fences)
        = &FLIST_NEXT (*FLIST_TAIL_TAILP (new_fences));
     }
   else
     {
-      merge_fences (f, insn, state, dc, tc, last_scheduled_insn, 
-                    executing_insns, ready_ticks, ready_ticks_size, 
-                    sched_next, cycle, after_stall_p);
+      merge_fences (f, insn, state, dc, tc, last_scheduled_insn,
+                    executing_insns, ready_ticks, ready_ticks_size,
+                    sched_next, cycle, issue_rate, after_stall_p);
     }
 }
 
@@ -835,7 +841,7 @@ move_fence_to_fences (flist_t old_fences, flist_tail_t new_fences)
       merge_fences (f, old->insn, old->state, old->dc, old->tc,
                     old->last_scheduled_insn, old->executing_insns,
                     old->ready_ticks, old->ready_ticks_size,
-                    old->sched_next, old->cycle, 
+                    old->sched_next, old->cycle, old->issue_more,
                     old->after_stall_p);
     }
   else
@@ -861,7 +867,7 @@ add_clean_fence_to_fences (flist_tail_t new_fences, insn_t succ, fence_t fence)
                  NULL_RTX, NULL, 
                  XCNEWVEC (int, ready_ticks_size), ready_ticks_size,
                  NULL_RTX, FENCE_CYCLE (fence) + 1,
-                 0, 1, FENCE_AFTER_STALL_P (fence));
+                 0, issue_rate, 1, FENCE_AFTER_STALL_P (fence));
 }
 
 /* Add a new fence to NEW_FENCES list and initialize all of its data 
@@ -885,6 +891,7 @@ add_dirty_fence_to_fences (flist_tail_t new_fences, insn_t succ, fence_t fence)
                  FENCE_SCHED_NEXT (fence),
                  FENCE_CYCLE (fence),
                  FENCE_ISSUED_INSNS (fence),
+                FENCE_ISSUE_MORE (fence),
                  FENCE_STARTS_CYCLE_P (fence),
                  FENCE_AFTER_STALL_P (fence));
 }
index 335ed0ac3006e324da4ad5c481735ee8cfb0829d..4e7da57d8d59ddd680bf5778c5a3217c4b9bd66e 100644 (file)
@@ -296,6 +296,9 @@ struct _fence
   /* Insn, which has been scheduled last on this fence.  */
   rtx last_scheduled_insn;
 
+  /* The last value of can_issue_more variable on this fence.  */
+  int issue_more;
+
   /* If non-NULL force the next scheduled insn to be SCHED_NEXT.  */
   rtx sched_next;
 
@@ -325,6 +328,7 @@ typedef struct _fence *fence_t;
 #define FENCE_DC(F) ((F)->dc)
 #define FENCE_TC(F) ((F)->tc)
 #define FENCE_LAST_SCHEDULED_INSN(F) ((F)->last_scheduled_insn)
+#define FENCE_ISSUE_MORE(F) ((F)->issue_more)
 #define FENCE_EXECUTING_INSNS(F) ((F)->executing_insns)
 #define FENCE_READY_TICKS(F) ((F)->ready_ticks)
 #define FENCE_READY_TICKS_SIZE(F) ((F)->ready_ticks_size)
index f053a2d230c0a017b0c7fda228adee354d8283c8..9ca2ec43522409d0aad036f63e3b61fa0cdba649 100644 (file)
@@ -587,6 +587,7 @@ advance_one_cycle (fence_t fence)
   FENCE_ISSUED_INSNS (fence) = 0;
   FENCE_STARTS_CYCLE_P (fence) = 1;
   can_issue_more = issue_rate;
+  FENCE_ISSUE_MORE (fence) = can_issue_more;
 
   for (i = 0; VEC_iterate (rtx, FENCE_EXECUTING_INSNS (fence), i, insn); )
     {
@@ -3235,9 +3236,9 @@ sel_target_adjust_priority (expr_t expr)
 
   gcc_assert (EXPR_PRIORITY_ADJ (expr) >= 0);
 
-  if (sched_verbose >= 2)
-    sel_print ("sel_target_adjust_priority: insn %d,  %d +%d = %d.\n", 
-              INSN_UID (EXPR_INSN_RTX (expr)), EXPR_PRIORITY (expr), 
+  if (sched_verbose >= 4)
+    sel_print ("sel_target_adjust_priority: insn %d,  %d+%d = %d.\n",
+              INSN_UID (EXPR_INSN_RTX (expr)), EXPR_PRIORITY (expr),
               EXPR_PRIORITY_ADJ (expr), new_priority);
 
   return new_priority;
@@ -4033,8 +4034,8 @@ invoke_reorder_hooks (fence_t fence)
 
       ran_hook = true;
     }
-  else 
-    issue_more = issue_rate;
+  else
+    issue_more = FENCE_ISSUE_MORE (fence);
 
   /* Ensure that ready list and vec_av_set are in line with each other,
      i.e. vec_av_set[i] == ready_element (&ready, i).  */
@@ -4224,9 +4225,7 @@ get_expr_cost (expr_t expr, fence_t fence)
 
   if (recog_memoized (insn) < 0)
     {
-      if (!FENCE_STARTS_CYCLE_P (fence) 
-          /* FIXME: Is this condition necessary?  */
-          && VINSN_UNIQUE_P (EXPR_VINSN (expr))
+      if (!FENCE_STARTS_CYCLE_P (fence)
          && INSN_ASM_P (insn))
        /* This is asm insn which is tryed to be issued on the
           cycle not first.  Issue it on the next cycle.  */
@@ -5065,6 +5064,7 @@ advance_state_on_fence (fence_t fence, insn_t insn)
   if (sched_verbose >= 2)
     debug_state (FENCE_STATE (fence));
   FENCE_STARTS_CYCLE_P (fence) = 0;
+  FENCE_ISSUE_MORE (fence) = can_issue_more;
   return asm_p;
 }
 
@@ -5246,6 +5246,7 @@ fill_insns (fence_t fence, int seqno, ilist_t **scheduled_insns_tailpp)
   blist_add (&bnds, insn, NULL, FENCE_DC (fence));
   bnds_tailp = &BLIST_NEXT (bnds);
   set_target_context (FENCE_TC (fence));
+  can_issue_more = FENCE_ISSUE_MORE (fence);
   target_bb = INSN_BB (insn);
 
   /* Do while we can add any operation to the current group.  */
index 0800e582673f26f4d4bf2eab5ba9128c0fba71bf..d50db3bb69edecefed99bd8a3dd6cc50896fb7fd 100644 (file)
@@ -1,3 +1,11 @@
+2010-08-24  Andrey Belevantsev <abel@ispras.ru>
+
+       Backport from mainline:
+       2010-01-14  Alexander Monakov  <amonakov@ispras.ru>
+
+       PR rtl-optimization/42389
+       * gcc.dg/pr42389.c: New.
+
 2010-08-24  Andrey Belevantsev <abel@ispras.ru>
 
        Backport from mainline:
diff --git a/gcc/testsuite/gcc.dg/pr42389.c b/gcc/testsuite/gcc.dg/pr42389.c
new file mode 100644 (file)
index 0000000..2c1d981
--- /dev/null
@@ -0,0 +1,87 @@
+/* { dg-do compile { target powerpc*-*-* ia64-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -fselective-scheduling -fsel-sched-pipelining" } */
+
+struct s_linked_f_pointer
+{
+  struct s_linked_f_pointer *next;
+  float *fptr;
+};
+struct s_trace
+{
+  int index;
+};
+struct s_rr_cost
+{
+  float base_cost;
+  float acc_cost;
+};
+extern int num_nets;
+extern struct s_trace **trace_head;
+extern struct s_rr_cost *rr_cost;
+struct s_rr_route
+{
+  float cost;
+};
+static int heap_tail;
+extern struct s_linked_f_pointer *rr_modified_head;
+extern struct s_rr_route *rr_route;
+
+void
+empty_heap (void)
+{
+  heap_tail = 1;
+}
+
+void
+reset_path_costs (void)
+{
+  struct s_linked_f_pointer *mod_ptr;
+  if (rr_modified_head != ((void *) 0))
+    {
+      mod_ptr = rr_modified_head;
+      while (mod_ptr->next != ((void *) 0))
+       {
+         *(mod_ptr->fptr) = 1.e30;
+         mod_ptr = mod_ptr->next;
+       }
+      rr_modified_head = ((void *) 0);
+    }
+}
+
+static void
+route_net (int inet)
+{
+  int i;
+  for (i = 1; i < inet; i++)
+    reset_path_costs ();
+  empty_heap ();
+  reset_path_costs ();
+}
+
+void
+pathfinder_update_one_cost (int inet, float pres_fac, float acc_fac)
+{
+  struct s_trace *tptr;
+  int inode = 0;
+
+  tptr = trace_head[inet];
+  inode = tptr->index;
+  rr_route[inode].cost = rr_cost[inode].base_cost + rr_cost[inode].acc_cost;
+}
+
+int
+try_route (int n, float x, float y)
+{
+  int inet, itry;
+  float pres_fac;
+  for (itry = 1; itry <= n; itry++)
+    {
+      for (inet = 0; inet < num_nets; inet++)
+       {
+         route_net (inet);
+         pathfinder_update_one_cost (inet, pres_fac, x);
+       }
+      pres_fac *= y;
+    }
+}
+