This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[sel-sched] Fix substitution bugs, calling of reorder hooks, and bump alignment


Hello,

These are four patches that were sitting in our local tree for a while. I've decided to write about them in one email, though they were applied in different commits.

The first patch dumps the info about scheduled insns in the Haifa scheduler the same way as in the selective scheduling, making debug easier. The second patch bumps the default alignment of functions and loops in the ia64 backend for the same purpose, so we don't see performance losses due to the bad alignment.

The third patch fixes the substitution transformation by disabling the optimization in unsubstitution that works incorrectly.

The fourth patch is the fixes that were needed to get the compiler to bootstrap on powerpc. With this patch, we now call reorder* and variable_issue hooks properly; a few thinkos are also fixed.

Bootstrapped and regtested on ia64. The last patch is also bootstrapped and regtested on powerpc-linux with --enable-languages=c (the only powerpc I have access to is powerpc750, which is not terribly fast.)

Committed to sel-sched branch.

Andrey
2007-02-28  Maxim Kuvyrkov <mkuvyrkov@ispras.ru>

        * haifa-sched.c (schedule_block): Add debugging of insns and their
        costs.  Move debugging of the total scheduling time before updating
        head and tail. 
        * sched-ebb.c (schedule_ebb): Kill dead code setting head and tail.
        * sched-dump.c (dump_insn_1): Do not print insn with a verbose flag
        set to one.
2007-02-28  Maxim Kuvyrkov  <mkuvyrkov@ispras.ru>

        * config/ia64/ia64.c (ia64_override_options): Initialize 
        align_loops and align_functions to 32 and 64, respectively.
2007-02-28  Dmitry Melnik  <dm@ispras.ru>

        * sel-sched.c (substitute_rhs): Kill outdated and commented assert.
        (remove_if_has_source): Put under #if 0.
        (un_substitute): Put the call to remove_if_has_source under #if 0.
        Add comment. 
        (reg_alloc_tick): Rename to reg_rename_tick.
        (choose_best_reg): Don't modify it when original register is chosen.
        Don't set regs_ever_live.
        (moveup_set_rhs): Use av_set_lookup_other_equiv_rhs.
        (find_best_rhs_and_rtxhat_fits): Rename killing search&replace 
        glitch.
        (fill_insns): Update reg_rename_tick here instead of choose_best_reg.
        (sel_region_finish): Change dumping flags.  Put extra parentheses.
        * sel-sched-ir.c (av_set_lookup_other_equiv_rhs): New function.
        * sel-sched-ir.h: Declare it.
        * config/ia64/ia64.opt (mflag_sel_sched_substitution): Define to 1.

2007-02-28  Andrey Belevantsev  <abel@ispras.ru>

        * sel-sched.c (replace_in_vinsn_using_bitmask): Fix spacing.
        (compute_av_set): Instead of merging two rhs'es, remove one 
        first, then add second.
        (fill_ready_list): Do not pipeline USEs and CLOBBERs that were 
        already scheduled; bail out early when ready list doesn't contain 
        other insns.  Fix thinko with '!'.
        (find_best_rhs_and_reg_that_fits): Kill 's' variable.  Call 
        the reorder2 hook too, not only reorder.  Bail out early when 
        can_issue_more is 0.  Move the call to variable_issue from ...
        (fill_insns): ... here.  When can_issue_more is 0, set need_stall
        to 1 and bail out.  
        (sel_region_init): Initialize scheduling flags earlier.
        * sel-sched-ir.c (av_set_remove_rhs_with_insn): New function.  
        * sel-sched-ir.h: Declare it.  
        * sel-sched-dump.c (hard_regno_rename_ok): Mark the second 
        parameter as unused too.
        * config/rs6000/rs6000.c: Include sched-deps.h.
--- gcc/sched-ebb.c	(revision 25156)
+++ gcc/sched-ebb.c	(revision 25255)
@@ -584,8 +584,6 @@ schedule_ebb (rtx head, rtx tail)
   
   /* Sanity check: verify that all region insns were scheduled.  */
   gcc_assert (sched_n_insns == n_insns);
-  head = current_sched_info->head;
-  tail = current_sched_info->tail;
 
   if (EDGE_COUNT (last_bb->preds) == 0)
     /* LAST_BB is unreachable.  */
--- gcc/haifa-sched.c	(revision 25156)
+++ gcc/haifa-sched.c	(revision 25255)
@@ -2589,6 +2589,39 @@ schedule_block (basic_block *target_bb)
 	  }
     }
 
+  /* Debugging.  */
+  if (sched_verbose)
+    {
+      if (sched_verbose >= 6)
+	{
+	  rtx insn = NEXT_INSN (prev_head);
+	  rtx next_tail = NEXT_INSN (last_scheduled_insn);
+	  int last_clock = -1;
+	  int clock = 0;
+
+	  while (insn != next_tail)
+	    {
+	      char buf[2048];
+	      int cost;
+
+	      clock = INSN_TICK (insn);
+	      cost = clock - last_clock;
+
+	      print_insn (buf, insn, 0);
+	      fprintf (sched_dump, "    cost: %d\t(pat:%s;bb:%d;cycle:%d;)\n",
+		       cost, buf, BLOCK_NUM (insn), clock);
+
+	      last_clock = clock;
+
+	      insn = NEXT_INSN (insn);
+	    }
+
+	  gcc_assert (last_clock == clock_var);
+	}
+
+      fprintf (sched_dump, ";;   total time = %d\n", clock_var);
+    }
+
   if (!current_sched_info->queue_must_finish_empty
       || added_recovery_block_p)
     {
@@ -2604,21 +2637,16 @@ schedule_block (basic_block *target_bb)
   if (targetm.sched.md_finish)
     targetm.sched.md_finish (sched_dump, sched_verbose);
 
+  if (sched_verbose)
+    fprintf (sched_dump, ";;   new head = %d\n;;   new tail = %d\n\n",
+	     INSN_UID (head), INSN_UID (tail));
+
   /* Update head/tail boundaries.  */
   head = NEXT_INSN (prev_head);
   tail = last_scheduled_insn;
 
   head = restore_other_notes (head, NULL);
 
-  /* Debugging.  */
-  if (sched_verbose)
-    {
-      fprintf (sched_dump, ";;   total time = %d\n;;   new head = %d\n",
-	       clock_var, INSN_UID (head));
-      fprintf (sched_dump, ";;   new tail = %d\n\n",
-	       INSN_UID (tail));
-    }
-
   current_sched_info->head = head;
   current_sched_info->tail = tail;
 }
--- gcc/sel-sched-dump.c	(revision 25156)
+++ gcc/sel-sched-dump.c	(revision 25255)
@@ -240,7 +240,7 @@ dump_insn_1 (insn_t i, int flags)
 	{
 	  char buf[2048];
 
-	  print_insn (buf, i, 1);
+	  print_insn (buf, i, 0);
 	  print ("pat:%s;", buf);
 	}
       else if (flags & DUMP_INSN_UID)
--- gcc/config/ia64/ia64.c	(revision 25156)
+++ gcc/config/ia64/ia64.c	(revision 25255)
@@ -5199,6 +5199,11 @@ ia64_override_options (void)
 
   init_machine_status = ia64_init_machine_status;
 
+  if (align_functions <= 0)
+    align_functions = 64;
+  if (align_loops <= 0)
+    align_loops = 32;
+
   flag_sel_sched_renaming = mflag_sel_sched_renaming;
   flag_sel_sched_substitution = mflag_sel_sched_substitution;
 }
--- gcc/sel-sched.c	(revision 25156)
+++ gcc/sel-sched.c	(revision 25255)
@@ -284,10 +284,6 @@ substitute_rhs (rhs_t rhs, insn_t insn)
       rtx *where_replace = INSN_RHS (new_insn) ? 
 	&SET_SRC (PATTERN (new_insn)) : &PATTERN (new_insn);
 
-      /* ??? Somehow we've ended up substituting only in separable insns.  */
-      /*      gcc_assert (VINSN_HAS_RHS (*vi) && INSN_RHS (new_insn)
-              && VINSN_SEPARABLE (*vi));*/
-
       new_insn_valid = validate_replace_rtx_part (INSN_LHS (insn),
 						  expr_copy (INSN_RHS (insn)),
 						  where_replace, new_insn);
@@ -428,6 +424,9 @@ rtx_search (rtx what, rtx where)
   return (count_occurrences_equiv (what, where, 1) > 0);
 }
 
+/* FIXME: see comment in the un_substitute function regarding filtering
+   input av_set.  */
+#if 0
 /* Remove all RHSes which use X from av_set DATA.  Auxiliary function for 
    un_substitute.  */
 static void
@@ -461,10 +460,9 @@ remove_if_has_source (rtx x, rtx pat ATT
 	av_set_iter_remove (arg->iter);
     }
 }
+#endif
 
-/* Unsubstitution removes those elements of AV whose sources (and
-   destinations for !RHS_SCHEDULE_AS_RHS rhses) are set by INSN; and then, 
-   if INSN is a copy x:=y and if there is an rhs r in AV that uses y, 
+/* if INSN is a copy x:=y and if there is an rhs r in AV that uses y, 
    it adds all variants of r to AV derived by replacing one or more
    occurrences of y by x.  */
 static void
@@ -476,6 +474,13 @@ un_substitute (av_set_t *av_ptr, rtx ins
   rtx pat, src_reg, dst_reg;
 
   pat = PATTERN (insn);
+
+
+  /* FIXME: Enable *AV_PTR filtering, so un_substitute will remove those
+     elements of AV whose sources (and destinations for !RHS_SCHEDULE_AS_RHS 
+     rhses) are set by INSN.  This filtering used for optimization, and it's
+     presence doesn't affect the correctness.  */
+#if 0
   /* First remove all elements of SETP whose sources are set by INSN, but
      it's insn isn't conditionally mutexed by the predicates.  */
   FOR_EACH_RHS_1 (rhs, av_iter, av_ptr)
@@ -493,6 +498,7 @@ un_substitute (av_set_t *av_ptr, rtx ins
 	  || !sched_insns_conditions_mutex_p (insn, RHS_INSN (rhs)))
 	note_stores (pat, remove_if_has_source, (void *) &arg);
     }
+#endif
 
   /* Catch X := Y insns, where X and Y are regs.  Otherwise return.  */
   if (!insn_eligible_for_subst_p (insn))
@@ -968,9 +974,9 @@ mark_unavailable_hard_regs (def_t def, H
   IOR_COMPL_HARD_REG_SET (*unavailable_hard_regs, hard_regs_ok);
 }
 
-/* reg_alloc_tick[REG1] > reg_alloc_tick[REG2] if REG1 was chosen as the best 
-   register more recently than REG2.  */
-static int reg_alloc_tick[FIRST_PSEUDO_REGISTER];
+/* reg_rename_tick[REG1] > reg_rename_tick[REG2] if REG1 was chosen as the
+   best register more recently than REG2.  */
+static int reg_rename_tick[FIRST_PSEUDO_REGISTER];
 
 /* Choose the register among free, that is suitable for storing 
    the rhs value.
@@ -1003,7 +1009,6 @@ static int reg_alloc_tick[FIRST_PSEUDO_R
 static int
 choose_best_reg (HARD_REG_SET unavailable, def_list_t original_insns)
 {
-  int this_tick = 0;
   int best_new_reg;
   int cur_reg;
   def_list_iterator i;
@@ -1028,22 +1033,12 @@ choose_best_reg (HARD_REG_SET unavailabl
   /* If original register is available, return it.  */
   FOR_EACH_DEF (def, i, original_insns)
     {
-      rtx dest = SET_DEST (PATTERN (def->orig_insn));
-      int original_reg;
+      rtx orig_dest = SET_DEST (PATTERN (def->orig_insn));
 
-      if (REG_P (dest))
-  	original_reg = REGNO (dest);
-      else
-	{
-	  gcc_unreachable ();
-	  continue;
-	}
-      
-      if (!TEST_HARD_REG_BIT (unavailable, original_reg))
-	{
-	  reg_alloc_tick[original_reg]++;
-	  return original_reg;
-	}
+      gcc_assert (REG_P (orig_dest));
+
+      if (!TEST_HARD_REG_BIT (unavailable, REGNO (orig_dest)))
+	return REGNO (orig_dest);
     }
 
   best_new_reg = -1;
@@ -1053,18 +1048,10 @@ choose_best_reg (HARD_REG_SET unavailabl
   for (cur_reg = 0; cur_reg < FIRST_PSEUDO_REGISTER; cur_reg++)
     if (!TEST_HARD_REG_BIT (unavailable, cur_reg)) {
       if (best_new_reg < 0
-	  ||reg_alloc_tick[cur_reg] < reg_alloc_tick[best_new_reg])
+	  ||reg_rename_tick[cur_reg] < reg_rename_tick[best_new_reg])
 	best_new_reg = cur_reg;
     }
 
-  if (best_new_reg >= 0)
-    {
-      reg_alloc_tick[best_new_reg] = ++this_tick;
-    
-      /* FIXME: should we mark a best_new_reg here?  */
-      regs_ever_live[best_new_reg] = 1;
-    }
-
   return best_new_reg;
 }
 
@@ -1365,7 +1352,7 @@ moveup_set_rhs (av_set_t *avp, insn_t in
 
 	  /* If the resulting insn after substitution is already in av_set,
 	     remove it.  */
-	  if (av_set_lookup_rhs (*avp, rhs))
+	  if (av_set_lookup_other_equiv_rhs (*avp, rhs))
 	    {
 	      av_set_iter_remove (&i);
 	      print (" and removed, because av_set already had" \
@@ -2305,7 +2292,7 @@ sel_dfa_new_cycle (insn_t insn, fence_t 
    register for it (BEST_REG_FOUND).  BNDS and FENCE are current boundaries
    and scheduling fence respectively.  */ 
 static void
-find_best_rhs_and_rtxhat_fits (av_set_t *av_vliw_ptr, blist_t bnds, 
+find_best_rhs_and_reg_that_fits (av_set_t *av_vliw_ptr, blist_t bnds, 
 				 fence_t fence, rhs_t *best_rhs_vliw,
 				 int *best_reg_found)
 {
@@ -2691,7 +2678,7 @@ fill_insns (fence_t fence, int seqno, il
 
       /* Choose the best expression and, if needed, destination register
 	 for it.  */
-      find_best_rhs_and_rtxhat_fits (&av_vliw, bnds, fence,
+      find_best_rhs_and_reg_that_fits (&av_vliw, bnds, fence,
 				       &rhs_vliw, &best_reg);
 
       if (!rhs_vliw)
@@ -2799,8 +2786,16 @@ fill_insns (fence_t fence, int seqno, il
 		 do it once more, because that were done only in local av_vliw
 		 set (we can't do actual replacement there because at the
 		 moment we don't know yet which rhs is the best one.  */
-	      if (best_reg > -1 && best_reg != rhs_dest_regno (c_rhs))
-		replace_dest_with_reg_in_rhs (c_rhs, best_reg);
+	      if (best_reg > -1)
+		{
+		  static int reg_rename_this_tick = 0;
+
+		  if (best_reg != rhs_dest_regno (c_rhs))
+		    replace_dest_with_reg_in_rhs (c_rhs, best_reg);
+
+		  reg_rename_tick[best_reg] = ++reg_rename_this_tick;
+		  regs_ever_live[best_reg] = 1;
+		}
 
 	      insn = RHS_INSN (c_rhs);
 
@@ -3506,7 +3501,7 @@ sel_region_init (int rgn)
   first_emitted_uid = sel_max_uid;
 
   /* Reset register allocation ticks array.  */
-  memset (reg_alloc_tick, 0, sizeof reg_alloc_tick);
+  memset (reg_rename_tick, 0, sizeof reg_rename_tick);
 
   /* We don't need the semantics of moveup_set_path, because filtering of 
      dependencies inside a sched group is handled by tick_check_p and 
@@ -3772,15 +3767,14 @@ sel_region_finish (void)
                 }
 
               clock = INSN_FINAL_SCHED_CYCLE (insn);
-              cost = last_clock == -1 ? 1 : clock - last_clock;
+              cost = (last_clock == -1) ? 1 : clock - last_clock;
   
 	      gcc_assert (cost >= 0);
 
 	      line_start ();
 	      print ("cost: %d\t", cost);
-	      dump_insn_1 (insn, DUMP_INSN_UID | DUMP_INSN_BBN 
-			   | DUMP_INSN_SEQNO | DUMP_INSN_PATTERN
-			   | DUMP_INSN_CYCLE);
+	      dump_insn_1 (insn, (DUMP_INSN_UID | DUMP_INSN_BBN
+				  | DUMP_INSN_PATTERN | DUMP_INSN_CYCLE));
 	      line_finish ();
 
               if (issue_rate > 1
--- gcc/sel-sched-ir.c	(revision 25156)
+++ gcc/sel-sched-ir.c	(revision 25255)
@@ -1143,6 +1143,23 @@ av_set_lookup_rhs (av_set_t set, rhs_t s
   return NULL;
 }
 
+/* Search for an rhs in SET, such that it's equivalent to SOUGHT_RHS in the
+   sense of rhs_equal_p function, but not SOUGHT_RHS itself.
+   Function is used to check whether 
+   Returns NULL if no such rhs is in SET was found.  */
+rhs_t
+av_set_lookup_other_equiv_rhs (av_set_t set, rhs_t sought_rhs)
+{
+  rhs_t r;
+  av_set_iterator i;
+
+  FOR_EACH_RHS (r, i, set)
+    if (rhs_equal_p (r, sought_rhs) && r != sought_rhs)
+      return r;
+
+  return NULL;
+}
+
 bool
 av_set_is_in_p (av_set_t set, rhs_t rhs)
 {
--- gcc/sel-sched-ir.h	(revision 25156)
+++ gcc/sel-sched-ir.h	(revision 25255)
@@ -816,6 +816,7 @@ extern void rhs_clear (rhs_t);
 /* Av set functions.  */
 extern void av_set_iter_remove (av_set_iterator *);
 extern rhs_t av_set_lookup_rhs (av_set_t, rhs_t);
+extern rhs_t av_set_lookup_other_equiv_rhs (av_set_t, rhs_t);
 extern bool av_set_is_in_p (av_set_t, rhs_t);
 extern rhs_t av_set_add_vinsn (av_set_t *, vinsn_t, int, int);
 extern av_set_t av_set_copy (av_set_t, int);
--- gcc/config/ia64/ia64.opt	(revision 25156)
+++ gcc/config/ia64/ia64.opt	(revision 25255)
@@ -149,7 +149,7 @@ Common Report Var(mflag_sel_sched_renami
 Do register renaming in selective scheduling
 
 msel-sched-substitution
-Common Report Var(mflag_sel_sched_substitution) Init(0)
+Common Report Var(mflag_sel_sched_substitution) Init(1)
 Perform substitution in selective scheduling
 
 ; This comment is to ensure we retain the blank line above.
--- gcc/sel-sched.c	(revision 25255)
+++ gcc/sel-sched.c	(revision 25390)
@@ -360,7 +360,7 @@ replace_in_vinsn_using_bitmask (vinsn_t 
   arg.bitmask = bitmask;
 
   for_each_rtx (VINSN_SEPARABLE (where) ? 
-		  &VINSN_RHS (where) : &VINSN_PATTERN (where), 
+                &VINSN_RHS (where) : &VINSN_PATTERN (where), 
 		&replace_in_vinsn_using_bitmask_1, (void *) &arg);
 
   /* Make sure all occurences has been replaced.  */
@@ -1598,15 +1598,13 @@ compute_av_set (insn_t insn, ilist_t p, 
   /* Then, compute av1 above insn.  */
   if (!INSN_NOP_P (insn))
     {
-      rhs_t rhs;
-
       moveup_set_rhs (&av1, insn);
 
-      rhs = av_set_lookup_insn (av1, insn);
-      if (rhs)
-	RHS_SPEC (rhs) = 0;
-      else
-	av_set_add_insn (&av1, insn);
+      /* Add this insn to its av set.  If a similar insn is already in 
+         av set, we need to change its RHS properly.  By now, just 
+         remove it first.  */
+      av_set_remove_rhs_with_insn (&av1, insn);
+      av_set_add_insn (&av1, insn);
     }
 
   line_start ();
@@ -2172,6 +2170,15 @@ fill_ready_list (av_set_t av, bnd_t bnd,
       if (/* This will also initialize INSN_CODE for max_issue ().  */
 	  recog_memoized (insn) < 0)
         {
+
+          /* Do not pipeline these insns when they were already scheduled;
+             as we emit them unconditionally, it leads to an infinite loop.  */
+          if (VINSN_SCHED_TIMES (RHS_VINSN (rhs)) > 0)
+            {
+              gcc_assert (pipelining_p);
+              continue;
+            }
+
           VEC_block_remove (rhs_t, vec_av_set, 0, 
                             VEC_length (rhs_t, vec_av_set));
           return rhs;
@@ -2180,6 +2187,14 @@ fill_ready_list (av_set_t av, bnd_t bnd,
       VEC_safe_push (rhs_t, heap, vec_av_set, rhs);
     }
 
+  /* Bail out early when the ready list contained only USEs/CLOBBERs that are
+     already scheduled.  */
+  if (VEC_length (rhs_t, vec_av_set) == 0)
+    {
+      ready.n_ready = 0;
+      return NULL;
+    }
+
   /* Sort the vector.  */
   qsort (VEC_address (rhs_t, vec_av_set), VEC_length (rhs_t, vec_av_set),
          sizeof (rhs_t), sel_rank_for_schedule);
@@ -2233,7 +2248,7 @@ fill_ready_list (av_set_t av, bnd_t bnd,
   print ("\nreally_ready: %d stalled: %d \n", n, stalled);
   if (!n)
     {
-      if (enable_moveup_set_path_p)
+      if (!enable_moveup_set_path_p)
         /* It seems possible that when no insns are ready, this could be
            due to liveness restrictions.  However, we should always be able
            to schedule the next instruction.  So when the list is empty, then
@@ -2299,7 +2314,6 @@ find_best_rhs_and_reg_that_fits (av_set_
   rhs_t res = NULL;
   insn_t best = NULL_RTX;
   int best_reg;
-  state_t s = alloca (dfa_state_size);
   rhs_t r;
   _list_iterator i3;
 
@@ -2343,8 +2357,6 @@ find_best_rhs_and_reg_that_fits (av_set_
 	}
     }
 
-  memcpy (s, FENCE_STATE (fence), dfa_state_size);
-
   /* We have one boundary per fence.  */
   gcc_assert (BLIST_NEXT (bnds) == NULL);
 
@@ -2363,27 +2375,55 @@ find_best_rhs_and_reg_that_fits (av_set_
       int i, can_issue, privileged_n;
       int index;
 
-      if (targetm.sched.reorder
-          && !SCHED_GROUP_P (ready_element (&ready, 0))
-	  && ready.n_ready > 1)
-	{
-	  /* !!! Don't give reorder the most prioritized insn as it can break
-	     pipelining.  */
-          if (pipelining_p)
-            --ready.n_ready;
-
-	  can_issue_more
-	    = targetm.sched.reorder (sched_dump, sched_verbose,
-				     ready_lastpos (&ready),
-				     &ready.n_ready, FENCE_CYCLE (fence));
-          if (pipelining_p)
+      /* Call the reorder hook at the beginning of the cycle, and call
+         the reorder2 hook in the middle of the cycle.  */
+      if (FENCE_ISSUED_INSNS (fence) == 0)
+        {
+          if (targetm.sched.reorder
+              && !SCHED_GROUP_P (ready_element (&ready, 0))
+              && ready.n_ready > 1)
+            {
+              /* Don't give reorder the most prioritized insn as it can break
+                 pipelining.  */
+              if (pipelining_p)
+                --ready.n_ready;
+              
+              can_issue_more
+                = targetm.sched.reorder (sched_dump, sched_verbose,
+                                         ready_lastpos (&ready),
+                                         &ready.n_ready, FENCE_CYCLE (fence));
+              if (pipelining_p)
+                ++ready.n_ready;
+            }
+          else
+            /* Initialize can_issue_more for variable_issue.  */
+            can_issue_more = issue_rate;
+        }
+      else if (targetm.sched.reorder2
+               && (ready.n_ready == 0
+                   || !SCHED_GROUP_P (ready_element (&ready, 0))))
+        {
+          if (pipelining_p && ready.n_ready > 1)
+           --ready.n_ready;
+          can_issue_more =
+            targetm.sched.reorder2 (sched_dump, sched_verbose,
+                                    ready.n_ready
+                                    ? ready_lastpos (&ready) : NULL,
+                                    &ready.n_ready, FENCE_CYCLE (fence));
+          if (pipelining_p && ready.n_ready > 1)
             ++ready.n_ready;
-	}
+        }
+      
+      if (can_issue_more == 0)
+        {
+          *best_rhs_vliw = NULL;
+          *best_reg_found = -1;
+          return;
+        }
 
-      min_spec_insn = ready_element (&ready, 0);
 
+      min_spec_insn = ready_element (&ready, 0);
       min_spec_vinsn = INSN_VI (min_spec_insn);
-
       min_spec_rhs = av_set_lookup_insn (*av_vliw_ptr, min_spec_insn);
       gcc_assert (min_spec_rhs != NULL
 		  && RHS_VINSN (min_spec_rhs) == min_spec_vinsn);
@@ -2479,9 +2519,6 @@ find_best_rhs_and_reg_that_fits (av_set_
 	    }
         }
 
-      if (memcmp (s, FENCE_STATE (fence), dfa_state_size))
-        gcc_unreachable ();
-
       if (can_issue)
         {
           best = ready_element (&ready, index);
@@ -2503,6 +2540,19 @@ find_best_rhs_and_reg_that_fits (av_set_
     {
       gcc_assert (INSN_P (best));
       sel_dfa_new_cycle (best, fence);
+
+      if (targetm.sched.variable_issue)
+       {
+         memcpy (curr_state, FENCE_STATE (fence), dfa_state_size);
+         can_issue_more = targetm.sched.variable_issue (sched_dump,
+                                                        sched_verbose,
+                                                        best,
+                                                        can_issue_more);
+         memcpy (FENCE_STATE (fence), curr_state, dfa_state_size);
+       }
+      else if (GET_CODE (PATTERN (best)) != USE
+              && GET_CODE (PATTERN (best)) != CLOBBER)
+       can_issue_more--;
     }
 
   *best_rhs_vliw = res;
@@ -2687,6 +2737,11 @@ fill_insns (fence_t fence, int seqno, il
           print ("no best rhs found!");
           line_finish ();
 
+          /* Reorder* hooks told us nothing more to schedule; indicate that
+             a stall is needed.  */
+          if (can_issue_more == 0)
+            need_stall = 1;
+
 	  av_set_clear (&av_vliw);
           break;
         }
@@ -2912,18 +2967,6 @@ fill_insns (fence_t fence, int seqno, il
 		advance_one_cycle (fence);
             }
 
-          if (targetm.sched.variable_issue)
-            {
-              memcpy (curr_state, FENCE_STATE (fence), dfa_state_size);
-              can_issue_more = targetm.sched.variable_issue (sched_dump,
-                                                             sched_verbose,
-							     insn,
-                                                             can_issue_more);
-              memcpy (FENCE_STATE (fence), curr_state, dfa_state_size);
-            }
-          else
-            can_issue_more--;
-
 	  /* Set instruction scheduling info.  This will be used in bundling,
 	     pipelining, tick computations etc.  */
 
@@ -2979,6 +3022,14 @@ fill_insns (fence_t fence, int seqno, il
       /* Indicate that we've scheduled something on this fence.  */
       FENCE_SCHEDULED_SOMETHING (fence) = true;
 
+      /* When can_issue_more is 0, variable_issue tells us that we should
+        advance a cycle.  */
+      if (can_issue_more == 0)
+       {
+         need_stall = 1;
+         break;
+       }
+
       /* We currently support information about candidate blocks only for
 	 one 'target_bb' block.  Hence we can't schedule after jump insn,
 	 as this will bring two boundaries and, hence, necessity to handle
@@ -3452,6 +3503,17 @@ sel_region_init (int rgn)
   if (sched_rgn_local_preinit (rgn))
     return true;
 
+  /* We don't need the semantics of moveup_set_path, because filtering of 
+     dependencies inside a sched group is handled by tick_check_p and 
+     the target.  */
+  enable_moveup_set_path_p = 0;
+
+  /* We need to treat insns as RHSes only when renaming is enabled.  */
+  enable_schedule_as_rhs_p = (flag_sel_sched_renaming != 0);
+
+  bookkeeping_p = (flag_sel_sched_bookkeeping != 0);
+  pipelining_p = bookkeeping_p && (flag_sel_sched_pipelining != 0);
+
   bbs = sbitmap_alloc (last_basic_block);
   sbitmap_zero (bbs);
   for (i = 0; i < current_nr_blocks; i++)
@@ -3503,20 +3565,6 @@ sel_region_init (int rgn)
   /* Reset register allocation ticks array.  */
   memset (reg_rename_tick, 0, sizeof reg_rename_tick);
 
-  /* We don't need the semantics of moveup_set_path, because filtering of 
-     dependencies inside a sched group is handled by tick_check_p and 
-     the target.  */
-  enable_moveup_set_path_p = 0;
-
-  /* We need to treat insns as RHSes only when renaming is enabled.  */
-  enable_schedule_as_rhs_p = (flag_sel_sched_renaming != 0);
-
-  /* (En/Dis)able bookkeeping.  */
-  bookkeeping_p = (flag_sel_sched_bookkeeping != 0);
-
-  /* (En/Dis)able pipelining.  */
-  pipelining_p = bookkeeping_p && (flag_sel_sched_pipelining != 0);
-
   if (pipelining_p)
     pipelining_p = add_region_head ();
 
--- gcc/sel-sched-ir.c	(revision 25255)
+++ gcc/sel-sched-ir.c	(revision 25390)
@@ -1160,6 +1160,25 @@ av_set_lookup_other_equiv_rhs (av_set_t 
   return NULL;
 }
 
+
+/* Search for rhs corresponding to INSN in SET and remove it if found,
+   returning TRUE.  Return FALSE otherwise.  */
+bool
+av_set_remove_rhs_with_insn (av_set_t *set, insn_t insn)
+{
+  rhs_t r;
+  av_set_iterator i;
+
+  FOR_EACH_RHS_1 (r, i, set)
+    if (rhs_equals_insn_p (r, insn))
+      {
+       av_set_iter_remove (&i);
+       return true;
+      }
+
+  return false;
+}
+
 bool
 av_set_is_in_p (av_set_t set, rhs_t rhs)
 {
--- gcc/sel-sched-ir.h	(revision 25255)
+++ gcc/sel-sched-ir.h	(revision 25390)
@@ -817,6 +817,7 @@ extern void rhs_clear (rhs_t);
 extern void av_set_iter_remove (av_set_iterator *);
 extern rhs_t av_set_lookup_rhs (av_set_t, rhs_t);
 extern rhs_t av_set_lookup_other_equiv_rhs (av_set_t, rhs_t);
+extern bool av_set_remove_rhs_with_insn (av_set_t *, insn_t);
 extern bool av_set_is_in_p (av_set_t, rhs_t);
 extern rhs_t av_set_add_vinsn (av_set_t *, vinsn_t, int, int);
 extern av_set_t av_set_copy (av_set_t, int);
--- gcc/sel-sched-dump.c	(revision 25255)
+++ gcc/sel-sched-dump.c	(revision 25390)
@@ -861,7 +861,7 @@ bool insn_is_set_p (rtx insn)
 }
 
 int
-hard_regno_rename_ok (int i, int j ATTRIBUTE_UNUSED)
+hard_regno_rename_ok (int i ATTRIBUTE_UNUSED, int j ATTRIBUTE_UNUSED)
 {
   return HARD_REGNO_RENAME_OK (i, j);
 }
--- gcc/config/rs6000/rs6000.c	(revision 25255)
+++ gcc/config/rs6000/rs6000.c	(revision 25390)
@@ -53,6 +53,7 @@
 #include "reload.h"
 #include "cfglayout.h"
 #include "sched-int.h"
+#include "sched-deps.h"
 #include "tree-gimple.h"
 #include "intl.h"
 #include "params.h"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]