haifa-sched.c (move_insn): Restore moving all schedule group.
authorVladimir Makarov <vmakarov@redhat.com>
Fri, 17 Jan 2003 00:00:18 +0000 (00:00 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Fri, 17 Jan 2003 00:00:18 +0000 (00:00 +0000)
2003-01-16  Vladimir Makarov  <vmakarov@redhat.com>

* haifa-sched.c (move_insn): Restore moving all schedule group.
(set_priorities): Restore taking SCHED_GROUP_P into account.

* sched-deps.c (add_dependence): Restore processing the last group
insn.
(remove_dependence, group_leader): Restore the functions.
(set_sched_group_p): Restore adding dependencies from previous insn
in the group.
(compute_forward_dependences): Restore usage of group_leader.

* sched-ebb.c (init_ready_list): Restore taking SCHED_GROUP_P into
account.

* sched-rgn.c (init_ready_list): Restore taking SCHED_GROUP_P into
account.
(can_schedule_ready_p): Ditto.
(add_branch_dependences): Restore skipping over the group insns.

From-SVN: r61412

gcc/ChangeLog
gcc/haifa-sched.c
gcc/sched-deps.c
gcc/sched-ebb.c
gcc/sched-rgn.c

index 2cbeff1fcf731b980143c3218397f05f84aa58cf..262eb0be3f6d20553ec1a845da6feea049b4a13b 100644 (file)
@@ -1,3 +1,23 @@
+2003-01-16  Vladimir Makarov  <vmakarov@redhat.com>
+
+       * haifa-sched.c (move_insn): Restore moving all schedule group.
+       (set_priorities): Restore taking SCHED_GROUP_P into account.
+
+       * sched-deps.c (add_dependence): Restore processing the last group
+       insn.
+       (remove_dependence, group_leader): Restore the functions.
+       (set_sched_group_p): Restore adding dependencies from previous insn
+       in the group.
+       (compute_forward_dependences): Restore usage of group_leader.
+
+       * sched-ebb.c (init_ready_list): Restore taking SCHED_GROUP_P into
+       account.
+
+       * sched-rgn.c (init_ready_list): Restore taking SCHED_GROUP_P into
+       account.
+       (can_schedule_ready_p): Ditto.
+       (add_branch_dependences): Restore skipping over the group insns.
+       
 2003-01-16  Stephane Carrez  <stcarrez@nerim.fr>
 
        * config/m68hc11/m68hc11.c (m68hc11_check_z_replacement): Fix handling
index 046abc344239c73e30d7ee5dd408031767c38efb..c6b2aab49357a5700608ef690d3f1943dfb0ef70 100644 (file)
@@ -1769,6 +1769,25 @@ move_insn (insn, last)
 {
   rtx retval = NULL;
 
+  /* If INSN has SCHED_GROUP_P set, then issue it and any other
+     insns with SCHED_GROUP_P set first.  */
+  while (SCHED_GROUP_P (insn))
+    {
+      rtx prev = PREV_INSN (insn);
+      
+      /* Move a SCHED_GROUP_P insn.  */
+      move_insn1 (insn, last);
+      /* If this is the first call to reemit_notes, then record
+        its return value.  */
+      if (retval == NULL_RTX)
+       retval = reemit_notes (insn, insn);
+      else
+       reemit_notes (insn, insn);
+      /* Consume SCHED_GROUP_P flag.  */
+      SCHED_GROUP_P (insn) = 0;
+      insn = prev;
+    }
+
   /* Now move the first non SCHED_GROUP_P insn.  */
   move_insn1 (insn, last);
 
@@ -1779,8 +1798,6 @@ move_insn (insn, last)
   else
     reemit_notes (insn, insn);
 
-  SCHED_GROUP_P (insn) = 0;
-
   return retval;
 }
 
@@ -2376,7 +2393,8 @@ set_priorities (head, tail)
       if (GET_CODE (insn) == NOTE)
        continue;
 
-      n_insn++;
+      if (! SCHED_GROUP_P (insn))
+       n_insn++;
       (void) priority (insn);
     }
 
index a735125495c35bc0fd1f54327f1eea8af1f9a09b..d6fa2c821a61a85409031ae700205eaeb418db70 100644 (file)
@@ -83,12 +83,14 @@ static sbitmap *forward_dependency_cache;
 static int deps_may_trap_p PARAMS ((rtx));
 static void add_dependence_list PARAMS ((rtx, rtx, enum reg_note));
 static void add_dependence_list_and_free PARAMS ((rtx, rtx *, enum reg_note));
+static void remove_dependence PARAMS ((rtx, rtx));
 static void set_sched_group_p PARAMS ((rtx));
 
 static void flush_pending_lists PARAMS ((struct deps *, rtx, int, int));
 static void sched_analyze_1 PARAMS ((struct deps *, rtx, rtx));
 static void sched_analyze_2 PARAMS ((struct deps *, rtx, rtx));
 static void sched_analyze_insn PARAMS ((struct deps *, rtx, rtx, rtx));
+static rtx group_leader PARAMS ((rtx));
 
 static rtx get_condition PARAMS ((rtx));
 static int conditions_mutex_p PARAMS ((rtx, rtx));
@@ -235,13 +237,16 @@ add_dependence (insn, elem, dep_type)
       rtx nnext;
       while ((nnext = next_nonnote_insn (next)) != NULL
             && INSN_P (nnext)
-            && next != insn
             && SCHED_GROUP_P (nnext))
        next = nnext;
 
-      if (insn != next)
-       add_dependence (insn, next, REG_DEP_ANTI);
+      /* Again, don't depend an insn on itself.  */
+      if (insn == next)
+       return;
 
+      /* Make the dependence to NEXT, the last insn of the group,
+        instead of the original ELEM.  */
+      elem = next;
     }
 
 
@@ -380,6 +385,76 @@ add_dependence_list_and_free (insn, listp, dep_type)
     }
 }
 
+/* Remove ELEM wrapped in an INSN_LIST from the LOG_LINKS
+   of INSN.  Abort if not found.  */
+
+static void
+remove_dependence (insn, elem)
+     rtx insn;
+     rtx elem;
+{
+  rtx prev, link, next;
+  int found = 0;
+
+  for (prev = 0, link = LOG_LINKS (insn); link; link = next)
+    {
+      next = XEXP (link, 1);
+      if (XEXP (link, 0) == elem)
+       {
+         if (prev)
+           XEXP (prev, 1) = next;
+         else
+           LOG_LINKS (insn) = next;
+
+#ifdef INSN_SCHEDULING
+         /* If we are removing a dependency from the LOG_LINKS list,
+            make sure to remove it from the cache too.  */
+         if (true_dependency_cache != NULL)
+           {
+             if (REG_NOTE_KIND (link) == 0)
+               RESET_BIT (true_dependency_cache[INSN_LUID (insn)],
+                          INSN_LUID (elem));
+             else if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
+               RESET_BIT (anti_dependency_cache[INSN_LUID (insn)],
+                          INSN_LUID (elem));
+             else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
+               RESET_BIT (output_dependency_cache[INSN_LUID (insn)],
+                          INSN_LUID (elem));
+           }
+#endif
+
+         free_INSN_LIST_node (link);
+
+         found = 1;
+       }
+      else
+       prev = link;
+    }
+
+  if (!found)
+    abort ();
+  return;
+}
+
+/* Return an insn which represents a SCHED_GROUP, which is
+   the last insn in the group.  */
+
+static rtx
+group_leader (insn)
+     rtx insn;
+{
+  rtx prev;
+
+  do
+    {
+      prev = insn;
+      insn = next_nonnote_insn (insn);
+    }
+  while (insn && INSN_P (insn) && SCHED_GROUP_P (insn));
+
+  return prev;
+}
+
 /* Set SCHED_GROUP_P and care for the rest of the bookkeeping that
    goes along with that.  */
 
@@ -391,21 +466,22 @@ set_sched_group_p (insn)
 
   SCHED_GROUP_P (insn) = 1;
 
-  for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
-    {
-      prev = insn;
-      do
-       {
-         prev = prev_nonnote_insn (prev);
-         if (XEXP (link, 0) == prev)
-           break;
-       }
-      while (SCHED_GROUP_P (prev));
-      if (XEXP (link, 0) != prev)
-       add_dependence (prev, XEXP (link, 0), REG_DEP_ANTI);
-    }
+  /* There may be a note before this insn now, but all notes will
+     be removed before we actually try to schedule the insns, so
+     it won't cause a problem later.  We must avoid it here
+     though.  */
   prev = prev_nonnote_insn (insn);
-  add_dependence (insn, prev, REG_DEP_ANTI);
+  
+  /* Make a copy of all dependencies on the immediately previous
+     insn, and add to this insn.  This is so that all the
+     dependencies will apply to the group.  Remove an explicit
+     dependence on this insn as SCHED_GROUP_P now represents it.  */
+  
+  if (find_insn_list (prev, LOG_LINKS (insn)))
+    remove_dependence (insn, prev);
+  
+  for (link = LOG_LINKS (prev); link; link = XEXP (link, 1))
+    add_dependence (insn, XEXP (link, 0), REG_NOTE_KIND (link));
 }
 \f
 /* Process an insn's memory dependencies.  There are four kinds of
@@ -1370,9 +1446,11 @@ compute_forward_dependences (head, tail)
       if (! INSN_P (insn))
        continue;
 
+      insn = group_leader (insn);
+      
       for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
        {
-         rtx x = XEXP (link, 0);
+         rtx x = group_leader (XEXP (link, 0));
          rtx new_link;
 
          if (x != XEXP (link, 0))
index 29189a68d0c6f4441cbf717f52d7a8aa01461a73..59f7ac043294a6d5e69ea6528b3c8a262d55f4f1 100644 (file)
@@ -90,9 +90,16 @@ init_ready_list (ready)
      Count number of insns in the target block being scheduled.  */
   for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
     {
-      if (INSN_DEP_COUNT (insn) == 0)
+      rtx next;
+
+      if (! INSN_P (insn))
+       continue;
+      next = NEXT_INSN (insn);
+
+      if (INSN_DEP_COUNT (insn) == 0
+         && (! INSN_P (next) || SCHED_GROUP_P (next) == 0))
        ready_add (ready, insn);
-      if (!(SCHED_GROUP_P (insn)))
+      if (! SCHED_GROUP_P (insn))
        target_n_insns++;
     }
 }
index 36a53f73c26162bc35f7f299dcfb5395b59791ba..0bbe148a283323aef7e10774485eb98174c6643b 100644 (file)
@@ -2023,9 +2023,17 @@ init_ready_list (ready)
      Count number of insns in the target block being scheduled.  */
   for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
     {
-      if (INSN_DEP_COUNT (insn) == 0)
+      rtx next;
+
+      if (! INSN_P (insn))
+       continue;
+      next = NEXT_INSN (insn);
+
+      if (INSN_DEP_COUNT (insn) == 0
+         && (! INSN_P (next) || SCHED_GROUP_P (next) == 0))
        ready_add (ready, insn);
-      target_n_insns++;
+      if (! SCHED_GROUP_P (insn))
+       target_n_insns++;
     }
 
   /* Add to ready list all 'ready' insns in valid source blocks.
@@ -2059,8 +2067,19 @@ init_ready_list (ready)
                                                             insn, insn) <= 3)))
                        && check_live (insn, bb_src)
                        && is_exception_free (insn, bb_src, target_bb))))
-             if (INSN_DEP_COUNT (insn) == 0)
-               ready_add (ready, insn);
+             {
+               rtx next;
+
+               /* Note that we haven't squirreled away the notes for
+                  blocks other than the current.  So if this is a
+                  speculative insn, NEXT might otherwise be a note.  */
+               next = next_nonnote_insn (insn);
+               if (INSN_DEP_COUNT (insn) == 0
+                   && (! next
+                       || ! INSN_P (next)
+                       || SCHED_GROUP_P (next) == 0))
+                 ready_add (ready, insn);
+             }
          }
       }
 }
@@ -2078,6 +2097,7 @@ can_schedule_ready_p (insn)
   /* An interblock motion?  */
   if (INSN_BB (insn) != target_bb)
     {
+      rtx temp;
       basic_block b1;
 
       if (IS_SPECULATIVE_INSN (insn))
@@ -2094,9 +2114,18 @@ can_schedule_ready_p (insn)
        }
       nr_inter++;
 
+      /* Find the beginning of the scheduling group.  */
+      /* ??? Ought to update basic block here, but later bits of
+        schedule_block assumes the original insn block is
+        still intact.  */
+
+      temp = insn;
+      while (SCHED_GROUP_P (temp))
+       temp = PREV_INSN (temp);
+
       /* Update source block boundaries.  */
-      b1 = BLOCK_FOR_INSN (insn);
-      if (insn == b1->head && insn == b1->end)
+      b1 = BLOCK_FOR_INSN (temp);
+      if (temp == b1->head && temp == b1->end)
        {
          /* We moved all the insns in the basic block.
             Emit a note after the last insn and update the
@@ -2110,9 +2139,9 @@ can_schedule_ready_p (insn)
          /* We took insns from the end of the basic block,
             so update the end of block boundary so that it
             points to the first insn we did not move.  */
-         b1->end = PREV_INSN (insn);
+         b1->end = PREV_INSN (temp);
        }
-      else if (insn == b1->head)
+      else if (temp == b1->head)
        {
          /* We took insns from the start of the basic block,
             so update the start of block boundary so that
@@ -2332,6 +2361,17 @@ add_branch_dependences (head, tail)
          CANT_MOVE (insn) = 1;
 
          last = insn;
+         /* Skip over insns that are part of a group.
+            Make each insn explicitly depend on the previous insn.
+            This ensures that only the group header will ever enter
+            the ready queue (and, when scheduled, will automatically
+            schedule the SCHED_GROUP_P block).  */
+         while (SCHED_GROUP_P (insn))
+           {
+             rtx temp = prev_nonnote_insn (insn);
+             add_dependence (insn, temp, REG_DEP_ANTI);
+             insn = temp;
+           }
        }
 
       /* Don't overrun the bounds of the basic block.  */
@@ -2353,6 +2393,10 @@ add_branch_dependences (head, tail)
 
        add_dependence (last, insn, REG_DEP_ANTI);
        INSN_REF_COUNT (insn) = 1;
+       
+       /* Skip over insns that are part of a group.  */
+       while (SCHED_GROUP_P (insn))
+         insn = prev_nonnote_insn (insn);
       }
 }