diff gcc/haifa-sched.c @ 63:b7f97abdc517 gcc-4.6-20100522

update gcc from gcc-4.5.0 to gcc-4.6
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Mon, 24 May 2010 12:47:05 +0900
parents 77e2b8dfacca
children f6334be47118
line wrap: on
line diff
--- a/gcc/haifa-sched.c	Fri Feb 12 23:41:23 2010 +0900
+++ b/gcc/haifa-sched.c	Mon May 24 12:47:05 2010 +0900
@@ -1,6 +1,6 @@
 /* Instruction scheduling pass.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
    and currently maintained by, Jim Wilson (wilson@cygnus.com)
@@ -718,7 +718,7 @@
 
   if (current_nr_blocks > 1)
     FOR_BB_INSNS (bb, insn)
-      if (INSN_P (insn))
+      if (NONDEBUG_INSN_P (insn))
 	setup_ref_regs (PATTERN (insn));
   initiate_reg_pressure_info (df_get_live_in (bb));
 #ifdef EH_RETURN_DATA_REGNO
@@ -766,7 +766,8 @@
   struct reg_use_data *next;
 
   for (next = use->next_regno_use; next != use; next = next->next_regno_use)
-    if (QUEUE_INDEX (next->insn) != QUEUE_SCHEDULED)
+    if (NONDEBUG_INSN_P (next->insn)
+	&& QUEUE_INDEX (next->insn) != QUEUE_SCHEDULED)
       return false;
   return true;
 }
@@ -1585,7 +1586,8 @@
     max_reg_pressure[ira_reg_class_cover[i]]
       = curr_reg_pressure[ira_reg_class_cover[i]];
   for (insn = NEXT_INSN (after);
-       insn != NULL_RTX && BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (after);
+       insn != NULL_RTX && ! BARRIER_P (insn)
+	 && BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (after);
        insn = NEXT_INSN (insn))
     if (NONDEBUG_INSN_P (insn))
       {
@@ -1694,6 +1696,7 @@
 	 sd_iterator_cond (&sd_it, &dep);)
       {
 	rtx dbg = DEP_PRO (dep);
+	struct reg_use_data *use, *next;
 
 	gcc_assert (DEBUG_INSN_P (dbg));
 
@@ -1715,6 +1718,20 @@
 	INSN_VAR_LOCATION_LOC (dbg) = gen_rtx_UNKNOWN_VAR_LOC ();
 	df_insn_rescan (dbg);
 
+	/* Unknown location doesn't use any registers.  */
+	for (use = INSN_REG_USE_LIST (dbg); use != NULL; use = next)
+	  {
+	    struct reg_use_data *prev = use;
+
+	    /* Remove use from the cyclic next_regno_use chain first.  */
+	    while (prev->next_regno_use != use)
+	      prev = prev->next_regno_use;
+	    prev->next_regno_use = use->next_regno_use;
+	    next = use->next_insn_use;
+	    free (use);
+	  }
+	INSN_REG_USE_LIST (dbg) = NULL;
+
 	/* We delete rather than resolve these deps, otherwise we
 	   crash in sched_free_deps(), because forward deps are
 	   expected to be released before backward deps.  */
@@ -1803,89 +1820,82 @@
 
 /* Functions for handling of notes.  */
 
-/* Insert the INSN note at the end of the notes list.  */
-static void
-add_to_note_list (rtx insn, rtx *note_list_end_p)
-{
-  PREV_INSN (insn) = *note_list_end_p;
-  if (*note_list_end_p)
-    NEXT_INSN (*note_list_end_p) = insn;
-  *note_list_end_p = insn;
-}
-
 /* Add note list that ends on FROM_END to the end of TO_ENDP.  */
 void
 concat_note_lists (rtx from_end, rtx *to_endp)
 {
   rtx from_start;
 
+  /* It's easy when have nothing to concat.  */
   if (from_end == NULL)
-    /* It's easy when have nothing to concat.  */
     return;
 
+  /* It's also easy when destination is empty.  */
   if (*to_endp == NULL)
-    /* It's also easy when destination is empty.  */
     {
       *to_endp = from_end;
       return;
     }
 
   from_start = from_end;
-  /* A note list should be traversed via PREV_INSN.  */
   while (PREV_INSN (from_start) != NULL)
     from_start = PREV_INSN (from_start);
 
-  add_to_note_list (from_start, to_endp);
+  PREV_INSN (from_start) = *to_endp;
+  NEXT_INSN (*to_endp) = from_start;
   *to_endp = from_end;
 }
 
-/* Delete notes beginning with INSN and put them in the chain
-   of notes ended by NOTE_LIST.
-   Returns the insn following the notes.  */
-static rtx
-unlink_other_notes (rtx insn, rtx tail)
+/* Delete notes between HEAD and TAIL and put them in the chain
+   of notes ended by NOTE_LIST.  */
+void
+remove_notes (rtx head, rtx tail)
 {
-  rtx prev = PREV_INSN (insn);
-
-  while (insn != tail && NOTE_NOT_BB_P (insn))
+  rtx next_tail, insn, next;
+
+  note_list = 0;
+  if (head == tail && !INSN_P (head))
+    return;
+
+  next_tail = NEXT_INSN (tail);
+  for (insn = head; insn != next_tail; insn = next)
     {
-      rtx next = NEXT_INSN (insn);
-      basic_block bb = BLOCK_FOR_INSN (insn);
-
-      /* Delete the note from its current position.  */
-      if (prev)
-	NEXT_INSN (prev) = next;
-      if (next)
-	PREV_INSN (next) = prev;
-
-      if (bb)
-        {
-          /* Basic block can begin with either LABEL or
-             NOTE_INSN_BASIC_BLOCK.  */
-          gcc_assert (BB_HEAD (bb) != insn);
-
-          /* Check if we are removing last insn in the BB.  */
-          if (BB_END (bb) == insn)
-            BB_END (bb) = prev;
-        }
-
-      /* See sched_analyze to see how these are handled.  */
-      if (NOTE_KIND (insn) != NOTE_INSN_EH_REGION_BEG
-	  && NOTE_KIND (insn) != NOTE_INSN_EH_REGION_END)
-        add_to_note_list (insn, &note_list);
-
-      insn = next;
+      next = NEXT_INSN (insn);
+      if (!NOTE_P (insn))
+	continue;
+
+      switch (NOTE_KIND (insn))
+	{
+	case NOTE_INSN_BASIC_BLOCK:
+	  continue;
+
+	case NOTE_INSN_EPILOGUE_BEG:
+	  if (insn != tail)
+	    {
+	      remove_insn (insn);
+	      add_reg_note (next, REG_SAVE_NOTE,
+			    GEN_INT (NOTE_INSN_EPILOGUE_BEG));
+	      break;
+	    }
+	  /* FALLTHRU */
+
+	default:
+	  remove_insn (insn);
+
+	  /* Add the note to list that ends at NOTE_LIST.  */
+	  PREV_INSN (insn) = note_list;
+	  NEXT_INSN (insn) = NULL_RTX;
+	  if (note_list)
+	    NEXT_INSN (note_list) = insn;
+	  note_list = insn;
+	  break;
+	}
+
+      gcc_assert ((sel_sched_p () || insn != tail) && insn != head);
     }
-
-  if (insn == tail)
-    {
-      gcc_assert (sel_sched_p ());
-      return prev;
-    }
-
-  return insn;
 }
 
+
 /* Return the head and tail pointers of ebb starting at BEG and ending
    at END.  */
 void
@@ -1939,62 +1949,6 @@
   return 1;
 }
 
-/* Delete notes between HEAD and TAIL and put them in the chain
-   of notes ended by NOTE_LIST.  */
-static void
-rm_other_notes (rtx head, rtx tail)
-{
-  rtx next_tail;
-  rtx insn;
-
-  note_list = 0;
-  if (head == tail && (! INSN_P (head)))
-    return;
-
-  next_tail = NEXT_INSN (tail);
-  for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
-    {
-      rtx prev;
-
-      /* Farm out notes, and maybe save them in NOTE_LIST.
-         This is needed to keep the debugger from
-         getting completely deranged.  */
-      if (NOTE_NOT_BB_P (insn))
-	{
-	  prev = insn;
-	  insn = unlink_other_notes (insn, next_tail);
-
-	  gcc_assert ((sel_sched_p ()
-		       || prev != tail) && prev != head && insn != next_tail);
-	}
-    }
-}
-
-/* Same as above, but also process REG_SAVE_NOTEs of HEAD.  */
-void
-remove_notes (rtx head, rtx tail)
-{
-  /* rm_other_notes only removes notes which are _inside_ the
-     block---that is, it won't remove notes before the first real insn
-     or after the last real insn of the block.  So if the first insn
-     has a REG_SAVE_NOTE which would otherwise be emitted before the
-     insn, it is redundant with the note before the start of the
-     block, and so we have to take it out.  */
-  if (INSN_P (head))
-    {
-      rtx note;
-
-      for (note = REG_NOTES (head); note; note = XEXP (note, 1))
-	if (REG_NOTE_KIND (note) == REG_SAVE_NOTE)
-	  remove_note (head, note);
-    }
-
-  /* Remove remaining note insns from the block, save them in
-     note_list.  These notes are restored at the end of
-     schedule_block ().  */
-  rm_other_notes (head, tail);
-}
-
 /* Restore-other-notes: NOTE_LIST is the end of a chain of notes
    previously found among the insns.  Insert them just before HEAD.  */
 rtx
@@ -2315,11 +2269,9 @@
   fprintf (sched_dump, "\n");
 }
 
-/* Search INSN for REG_SAVE_NOTE note pairs for
-   NOTE_INSN_EHREGION_{BEG,END}; and convert them back into
-   NOTEs.  The REG_SAVE_NOTE note following first one is contains the
-   saved value for NOTE_BLOCK_NUMBER which is useful for
-   NOTE_INSN_EH_REGION_{BEG,END} NOTEs.  */
+/* Search INSN for REG_SAVE_NOTE notes and convert them back into insn
+   NOTEs.  This is used for NOTE_INSN_EPILOGUE_BEG, so that sched-ebb
+   replaces the epilogue note in the correct basic block.  */
 void
 reemit_notes (rtx insn)
 {