diff mbox

Simplify and speedup df notes creation

Message ID 20100611144347.GG18540@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka June 11, 2010, 2:43 p.m. UTC
Hi,
df-notes is trying to reust old notes by collecting them to linklist and then
re-insert the originals if they did not change. This seems just useless
excercise since creation of new note is cheap in theory (we maintain freelist),
but it is somewhat slow because we do 3 function calls.

This patch removes the linklists and brings add_reg_note inline.  Doing so hits
the problems with our twisty include files.  It can not go to rtl.h since it
would be compiled into gen files (and also gen_rtx_EXPR_LIST is not defined
there yet). I ended up putting it into emit-rtl.h where it seem to belong most
from other choices that introduces need to include emit-rtl into few extra
files. In lists.c we need also function.h since note allocation needs crtl.
I am open to alternatives here and I will mind updating dependencies if the
patch is accepted.

The patch reduces time spent in df_notes in WHOPR cc1 build from 1.3% to 1.08%
Still I find it hard to believe we actually have to spend so much time by such
a simple task.

Bootstrapped/regtested x86_64-linux

	* regrename.c: Include emit-rtl.h
	* rtlanal.c (alloc_reg_note, add_reg_note): Move to emit-rtl.h
	* lists.c: Include function.h and emit-rtl.h
	(unused_expr_list): Make global.
	(alloc_EXPR_LIST): Move to emit-rtl.h
	(free_EXPR_LIST_node): LIkewise.
	* emit-rtl.h (alloc_EXPR_LIST, free_EXPR_LIST_node,
	alloc_reg_note, add_reg_note): New.
	* sched-deps.c: Include emit-rtl.h* df-problems.c: Include emit-rtl.h.
	(df_kill_notes): Do not collect dead  notes.
	(df_set_note): Just call add_reg_note.
	(df_set_unused_notes_for_mw, df_set_dead_notes_for_mw,
	df_create_unused_note): Do not deal with lists of old notes.
	(df_note_bb_compute): Likewise.
	* sched-rgn.c: Move function.h include later; include emit-rtl.h.

Comments

Paolo Bonzini June 11, 2010, 3:20 p.m. UTC | #1
On 06/11/2010 04:43 PM, Jan Hubicka wrote:
> df-notes is trying to reust old notes by collecting them to linklist and then
> re-insert the originals if they did not change. This seems just useless
> excercise since creation of new note is cheap in theory (we maintain freelist),
> but it is somewhat slow because we do 3 function calls.
>
> This patch removes the linklists and brings add_reg_note inline.

Makes sense, and especially it allows to inline the INSN_LIST/EXPR_LIST 
choice in most of the callees; this might be a small improvement but 
it's obviously there.  The switch statement in alloc_reg_note should be 
well-predicted but not unfortunately the common case is the default and 
requires to go through 2-3 jumps.

Is it really required to inline alloc_EXPR_LIST?  Can you measure the 
.text size with it inlined and without?

> Doing so hits
> the problems with our twisty include files.  It can not go to rtl.h since it
> would be compiled into gen files (and also gen_rtx_EXPR_LIST is not defined
> there yet). I ended up putting it into emit-rtl.h where it seem to belong most
> from other choices that introduces need to include emit-rtl into few extra
> files. In lists.c we need also function.h since note allocation needs crtl.
> I am open to alternatives here and I will mind updating dependencies if the
> patch is accepted.

What about moving all of lists.c to emit-rtl.c?  A lot of it is also 
duplicate for EXPR_LIST and INSN_LIST, the free lists could be reduced 
to one with more simplification using gen_rtx_fmt_ee.  It's all stuff 
for other patches though.

The df bits are fine except that you have two of these:

-  return old;
+  return;

Paolo
Jan Hubicka June 11, 2010, 3:38 p.m. UTC | #2
> On 06/11/2010 04:43 PM, Jan Hubicka wrote:
>> df-notes is trying to reust old notes by collecting them to linklist and then
>> re-insert the originals if they did not change. This seems just useless
>> excercise since creation of new note is cheap in theory (we maintain freelist),
>> but it is somewhat slow because we do 3 function calls.
>>
>> This patch removes the linklists and brings add_reg_note inline.
>
> Makes sense, and especially it allows to inline the INSN_LIST/EXPR_LIST  
> choice in most of the callees; this might be a small improvement but  
> it's obviously there.  The switch statement in alloc_reg_note should be  
> well-predicted but not unfortunately the common case is the default and  
> requires to go through 2-3 jumps.
>
> Is it really required to inline alloc_EXPR_LIST?  Can you measure the  

I guess the patch would be win without inline too, but the hot path through
alloc_EXPR_LIST is very short and simple, so I would say it is good candidate
for inlining.
> .text size with it inlined and without?

Will do.
>
>> Doing so hits
>> the problems with our twisty include files.  It can not go to rtl.h since it
>> would be compiled into gen files (and also gen_rtx_EXPR_LIST is not defined
>> there yet). I ended up putting it into emit-rtl.h where it seem to belong most
>> from other choices that introduces need to include emit-rtl into few extra
>> files. In lists.c we need also function.h since note allocation needs crtl.
>> I am open to alternatives here and I will mind updating dependencies if the
>> patch is accepted.
>
> What about moving all of lists.c to emit-rtl.c?  A lot of it is also  
> duplicate for EXPR_LIST and INSN_LIST, the free lists could be reduced  
> to one with more simplification using gen_rtx_fmt_ee.  It's all stuff  
> for other patches though.

Well, I guess we can have one freelist and change the RTX type since they
are equivalent in memory layout...

Honza
>
> The df bits are fine except that you have two of these:
>
> -  return old;
> +  return;
>
> Paolo
Jan Hubicka June 21, 2010, 10:41 p.m. UTC | #3
> On 06/11/2010 04:43 PM, Jan Hubicka wrote:
>> df-notes is trying to reust old notes by collecting them to linklist and then
>> re-insert the originals if they did not change. This seems just useless
>> excercise since creation of new note is cheap in theory (we maintain freelist),
>> but it is somewhat slow because we do 3 function calls.
>>
>> This patch removes the linklists and brings add_reg_note inline.
>
> Makes sense, and especially it allows to inline the INSN_LIST/EXPR_LIST  
> choice in most of the callees; this might be a small improvement but  
> it's obviously there.  The switch statement in alloc_reg_note should be  
> well-predicted but not unfortunately the common case is the default and  
> requires to go through 2-3 jumps.
>
> Is it really required to inline alloc_EXPR_LIST?  Can you measure the  
> .text size with it inlined and without?
Hi,
I completely forgot about this.  The sizes are as follows:
Without patch 8894264
With patch    8899192
df-problems change alone 8893448. 
So the inlining is about 5kb.

Honza
Jan Hubicka June 30, 2010, 11:29 p.m. UTC | #4
Hi,
it looks this patch got stuck.  I would like to withdraw the part making notes
creation inlinine at least until the progress on restructuring headers gets
more far.
I bootstrapped the patch with df-problems.c change alone (that removes the cache)
and tried to benchmark difference on combine.c compilation at -O1.  After averaging
30 runs removing peaks I get 2.695s for mainline and 2.687s for patch.

So would be OK to apply the df-problems.c change?
Honza
Paolo Bonzini July 1, 2010, 5:59 a.m. UTC | #5
On Thu, Jul 1, 2010 at 01:29, Jan Hubicka <hubicka@ucw.cz> wrote:
> So would be OK to apply the df-problems.c change?

Yes.

Paolo
diff mbox

Patch

Index: regrename.c
===================================================================
--- regrename.c	(revision 160554)
+++ regrename.c	(working copy)
@@ -39,6 +39,7 @@ 
 #include "timevar.h"
 #include "tree-pass.h"
 #include "df.h"
+#include "emit-rtl.h"
 
 #if HOST_BITS_PER_WIDE_INT <= MAX_RECOG_OPERANDS
 #error "Use a different bitmap implementation for untracked_operands."
Index: rtlanal.c
===================================================================
--- rtlanal.c	(revision 160554)
+++ rtlanal.c	(working copy)
@@ -1865,43 +1865,6 @@  find_regno_fusage (const_rtx insn, enum
 }
 
 
-/* Allocate a register note with kind KIND and datum DATUM.  LIST is
-   stored as the pointer to the next register note.  */
-
-rtx
-alloc_reg_note (enum reg_note kind, rtx datum, rtx list)
-{
-  rtx note;
-
-  switch (kind)
-    {
-    case REG_CC_SETTER:
-    case REG_CC_USER:
-    case REG_LABEL_TARGET:
-    case REG_LABEL_OPERAND:
-      /* These types of register notes use an INSN_LIST rather than an
-	 EXPR_LIST, so that copying is done right and dumps look
-	 better.  */
-      note = alloc_INSN_LIST (datum, list);
-      PUT_REG_NOTE_KIND (note, kind);
-      break;
-
-    default:
-      note = alloc_EXPR_LIST (kind, datum, list);
-      break;
-    }
-
-  return note;
-}
-
-/* Add register note with kind KIND and datum DATUM to INSN.  */
-
-void
-add_reg_note (rtx insn, enum reg_note kind, rtx datum)
-{
-  REG_NOTES (insn) = alloc_reg_note (kind, datum, REG_NOTES (insn));
-}
-
 /* Remove register note NOTE from the REG_NOTES of INSN.  */
 
 void
Index: lists.c
===================================================================
--- lists.c	(revision 160554)
+++ lists.c	(working copy)
@@ -26,6 +26,8 @@  along with GCC; see the file COPYING3.
 #include "toplev.h"
 #include "rtl.h"
 #include "ggc.h"
+#include "function.h"
+#include "emit-rtl.h"
 
 static void free_list (rtx *, rtx *);
 
@@ -35,7 +37,7 @@  static void free_list (rtx *, rtx *);
 static GTY ((deletable)) rtx unused_insn_list;
 
 /* An EXPR_LIST containing all EXPR_LISTs allocated but currently unused.  */
-static GTY ((deletable)) rtx unused_expr_list;
+GTY ((deletable)) rtx unused_expr_list;
 
 /* This function will free an entire list of either EXPR_LIST, INSN_LIST
    or DEPS_LIST nodes.  This is to be used only on lists that consist
@@ -124,28 +126,6 @@  alloc_INSN_LIST (rtx val, rtx next)
   return r;
 }
 
-/* This call is used in place of a gen_rtx_EXPR_LIST. If there is a cached
-   node available, we'll use it, otherwise a call to gen_rtx_EXPR_LIST
-   is made.  */
-rtx
-alloc_EXPR_LIST (int kind, rtx val, rtx next)
-{
-  rtx r;
-
-  if (unused_expr_list)
-    {
-      r = unused_expr_list;
-      unused_expr_list = XEXP (r, 1);
-      XEXP (r, 0) = val;
-      XEXP (r, 1) = next;
-      PUT_REG_NOTE_KIND (r, kind);
-    }
-  else
-    r = gen_rtx_EXPR_LIST ((enum machine_mode) kind, val, next);
-
-  return r;
-}
-
 /* This function will free up an entire list of EXPR_LIST nodes.  */
 void
 free_EXPR_LIST_list (rtx *listp)
@@ -164,14 +144,6 @@  free_INSN_LIST_list (rtx *listp)
   free_list (listp, &unused_insn_list);
 }
 
-/* This function will free up an individual EXPR_LIST node.  */
-void
-free_EXPR_LIST_node (rtx ptr)
-{
-  XEXP (ptr, 1) = unused_expr_list;
-  unused_expr_list = ptr;
-}
-
 /* This function will free up an individual INSN_LIST node.  */
 void
 free_INSN_LIST_node (rtx ptr)
Index: emit-rtl.h
===================================================================
--- emit-rtl.h	(revision 160554)
+++ emit-rtl.h	(working copy)
@@ -104,4 +104,72 @@  get_max_uid (void)
 {
   return crtl->emit.x_cur_insn_uid;
 }
+
+/* This call is used in place of a gen_rtx_EXPR_LIST. If there is a cached
+   node available, we'll use it, otherwise a call to gen_rtx_EXPR_LIST
+   is made.  */
+static inline rtx
+alloc_EXPR_LIST (int kind, rtx val, rtx next)
+{
+  rtx r;
+
+  if (unused_expr_list)
+    {
+      r = unused_expr_list;
+      unused_expr_list = XEXP (r, 1);
+      XEXP (r, 0) = val;
+      XEXP (r, 1) = next;
+      PUT_REG_NOTE_KIND (r, kind);
+    }
+  else
+    r = gen_rtx_EXPR_LIST ((enum machine_mode) kind, val, next);
+
+  return r;
+}
+
+/* This function will free up an individual EXPR_LIST node.  */
+static inline void
+free_EXPR_LIST_node (rtx ptr)
+{
+  XEXP (ptr, 1) = unused_expr_list;
+  unused_expr_list = ptr;
+}
+
+
+/* Allocate a register note with kind KIND and datum DATUM.  LIST is
+   stored as the pointer to the next register note.  */
+
+static inline rtx
+alloc_reg_note (enum reg_note kind, rtx datum, rtx list)
+{
+  rtx note;
+
+  switch (kind)
+    {
+    case REG_CC_SETTER:
+    case REG_CC_USER:
+    case REG_LABEL_TARGET:
+    case REG_LABEL_OPERAND:
+      /* These types of register notes use an INSN_LIST rather than an
+	 EXPR_LIST, so that copying is done right and dumps look
+	 better.  */
+      note = alloc_INSN_LIST (datum, list);
+      PUT_REG_NOTE_KIND (note, kind);
+      break;
+
+    default:
+      note = alloc_EXPR_LIST (kind, datum, list);
+      break;
+    }
+
+  return note;
+}
+
+/* Add register note with kind KIND and datum DATUM to INSN.  */
+
+static inline void
+add_reg_note (rtx insn, enum reg_note kind, rtx datum)
+{
+  REG_NOTES (insn) = alloc_reg_note (kind, datum, REG_NOTES (insn));
+}
 #endif /* GCC_EMIT_RTL_H */
Index: sched-deps.c
===================================================================
--- sched-deps.c	(revision 160554)
+++ sched-deps.c	(working copy)
@@ -43,6 +43,7 @@  along with GCC; see the file COPYING3.
 #include "cselib.h"
 #include "ira.h"
 #include "target.h"
+#include "emit-rtl.h"
 
 #ifdef INSN_SCHEDULING
 
Index: df-problems.c
===================================================================
--- df-problems.c	(revision 160554)
+++ df-problems.c	(working copy)
@@ -44,6 +44,7 @@  along with GCC; see the file COPYING3.
 #include "except.h"
 #include "dce.h"
 #include "vecprim.h"
+#include "emit-rtl.h"
 
 /* Note that turning REG_DEAD_DEBUGGING on will cause
    gcc.c-torture/unsorted/dump-noaddr.c to fail because it prints
@@ -3121,12 +3069,10 @@  df_ignore_stack_reg (int regno ATTRIBUTE
    them to OLD_DEAD_NOTES and OLD_UNUSED_NOTES.  */
 
 static void
-df_kill_notes (rtx insn, rtx *old_dead_notes, rtx *old_unused_notes)
+df_kill_notes (rtx insn)
 {
   rtx *pprev = &REG_NOTES (insn);
   rtx link = *pprev;
-  rtx dead = NULL;
-  rtx unused = NULL;
 
   while (link)
     {
@@ -3146,8 +3092,7 @@  df_kill_notes (rtx insn, rtx *old_dead_n
 #ifdef REG_DEAD_DEBUGGING
 	      df_print_note ("deleting: ", insn, link);
 #endif
-	      XEXP (link, 1) = dead;
-	      dead = link;
+	      free_EXPR_LIST_node (link);
 	      *pprev = link = next;
 	    }
 	  break;
@@ -3166,8 +3111,7 @@  df_kill_notes (rtx insn, rtx *old_dead_n
 #ifdef REG_DEAD_DEBUGGING
 	      df_print_note ("deleting: ", insn, link);
 #endif
-	      XEXP (link, 1) = unused;
-	      unused = link;
+	      free_EXPR_LIST_node (link);
 	      *pprev = link = next;
 	    }
 	  break;
@@ -3178,43 +3122,16 @@  df_kill_notes (rtx insn, rtx *old_dead_n
 	  break;
 	}
     }
-
-  *old_dead_notes = dead;
-  *old_unused_notes = unused;
 }
 
 
-/* Set a NOTE_TYPE note for REG in INSN.  Try to pull it from the OLD
-   list, otherwise create a new one.  */
+/* Set a NOTE_TYPE note for REG in INSN.  */
 
-static inline rtx
-df_set_note (enum reg_note note_type, rtx insn, rtx old, rtx reg)
+static inline void
+df_set_note (enum reg_note note_type, rtx insn, rtx reg)
 {
-  rtx curr = old;
-  rtx prev = NULL;
-
-  gcc_assert (!DEBUG_INSN_P (insn));
-
-  while (curr)
-    if (XEXP (curr, 0) == reg)
-      {
-	if (prev)
-	  XEXP (prev, 1) = XEXP (curr, 1);
-	else
-	  old = XEXP (curr, 1);
-	XEXP (curr, 1) = REG_NOTES (insn);
-	REG_NOTES (insn) = curr;
-	return old;
-      }
-    else
-      {
-	prev = curr;
-	curr = XEXP (curr, 1);
-      }
-
-  /* Did not find the note.  */
+  gcc_checking_assert (!DEBUG_INSN_P (insn));
   add_reg_note (insn, note_type, reg);
-  return old;
 }
 
 /* A subroutine of df_set_unused_notes_for_mw, with a selection of its
@@ -3250,8 +3167,8 @@  df_whole_mw_reg_unused_p (struct df_mw_h
    instruction.
 */
 
-static rtx
-df_set_unused_notes_for_mw (rtx insn, rtx old, struct df_mw_hardreg *mws,
+static void
+df_set_unused_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
 			    bitmap live, bitmap do_not_gen,
 			    bitmap artificial_uses)
 {
@@ -3266,7 +3183,7 @@  df_set_unused_notes_for_mw (rtx insn, rt
   if (df_whole_mw_reg_unused_p (mws, live, artificial_uses))
     {
       unsigned int regno = mws->start_regno;
-      old = df_set_note (REG_UNUSED, insn, old, mws->mw_reg);
+      df_set_note (REG_UNUSED, insn, mws->mw_reg);
 
 #ifdef REG_DEAD_DEBUGGING
       df_print_note ("adding 1: ", insn, REG_NOTES (insn));
@@ -3280,14 +3197,13 @@  df_set_unused_notes_for_mw (rtx insn, rt
 	if (!bitmap_bit_p (live, r)
 	    && !bitmap_bit_p (artificial_uses, r))
 	  {
-	    old = df_set_note (REG_UNUSED, insn, old, regno_reg_rtx[r]);
+	    df_set_note (REG_UNUSED, insn, regno_reg_rtx[r]);
 #ifdef REG_DEAD_DEBUGGING
 	    df_print_note ("adding 2: ", insn, REG_NOTES (insn));
 #endif
 	  }
 	bitmap_set_bit (do_not_gen, r);
       }
-  return old;
 }
 
 
@@ -3324,8 +3240,8 @@  df_whole_mw_reg_dead_p (struct df_mw_har
    from being set if the instruction both reads and writes the
    register.  */
 
-static rtx
-df_set_dead_notes_for_mw (rtx insn, rtx old, struct df_mw_hardreg *mws,
+static void
+df_set_dead_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
 			  bitmap live, bitmap do_not_gen,
 			  bitmap artificial_uses, bool *added_notes_p)
 {
@@ -3353,9 +3269,9 @@  df_set_dead_notes_for_mw (rtx insn, rtx
       if (is_debug)
 	{
 	  *added_notes_p = true;
-	  return old;
+	  return;
 	}
-      old = df_set_note (REG_DEAD, insn, old, mws->mw_reg);
+      df_set_note (REG_DEAD, insn, mws->mw_reg);
 #ifdef REG_DEAD_DEBUGGING
       df_print_note ("adding 1: ", insn, REG_NOTES (insn));
 #endif
@@ -3370,23 +3286,23 @@  df_set_dead_notes_for_mw (rtx insn, rtx
 	    if (is_debug)
 	      {
 		*added_notes_p = true;
-		return old;
+		return;
 	      }
-	    old = df_set_note (REG_DEAD, insn, old, regno_reg_rtx[r]);
+	    df_set_note (REG_DEAD, insn, regno_reg_rtx[r]);
 #ifdef REG_DEAD_DEBUGGING
 	    df_print_note ("adding 2: ", insn, REG_NOTES (insn));
 #endif
 	  }
     }
-  return old;
+  return;
 }
 
 
 /* Create a REG_UNUSED note if necessary for DEF in INSN updating
    LIVE.  Do not generate notes for registers in ARTIFICIAL_USES.  */
 
-static rtx
-df_create_unused_note (rtx insn, rtx old, df_ref def,
+static void
+df_create_unused_note (rtx insn, df_ref def,
 		       bitmap live, bitmap artificial_uses)
 {
   unsigned int dregno = DF_REF_REGNO (def);
@@ -3406,13 +3322,13 @@  df_create_unused_note (rtx insn, rtx old
     {
       rtx reg = (DF_REF_LOC (def))
                 ? *DF_REF_REAL_LOC (def): DF_REF_REG (def);
-      old = df_set_note (REG_UNUSED, insn, old, reg);
+      df_set_note (REG_UNUSED, insn, reg);
 #ifdef REG_DEAD_DEBUGGING
       df_print_note ("adding 3: ", insn, REG_NOTES (insn));
 #endif
     }
 
-  return old;
+  return;
 }
 
 /* Node of a linked list of uses of dead REGs in debug insns.  */
@@ -3635,8 +3551,6 @@  df_note_bb_compute (unsigned int bb_inde
     {
       unsigned int uid = INSN_UID (insn);
       struct df_mw_hardreg **mws_rec;
-      rtx old_dead_notes;
-      rtx old_unused_notes;
       int debug_insn;
 
       if (!INSN_P (insn))
@@ -3645,7 +3559,7 @@  df_note_bb_compute (unsigned int bb_inde
       debug_insn = DEBUG_INSN_P (insn);
 
       bitmap_clear (do_not_gen);
-      df_kill_notes (insn, &old_dead_notes, &old_unused_notes);
+      df_kill_notes (insn);
 
       /* Process the defs.  */
       if (CALL_P (insn))
@@ -3665,10 +3579,9 @@  df_note_bb_compute (unsigned int bb_inde
 	      struct df_mw_hardreg *mws = *mws_rec;
 	      if ((DF_MWS_REG_DEF_P (mws))
 		  && !df_ignore_stack_reg (mws->start_regno))
-		old_unused_notes
-		  = df_set_unused_notes_for_mw (insn, old_unused_notes,
-						mws, live, do_not_gen,
-						artificial_uses);
+	      df_set_unused_notes_for_mw (insn,
+					  mws, live, do_not_gen,
+					  artificial_uses);
 	      mws_rec++;
 	    }
 
@@ -3680,9 +3593,8 @@  df_note_bb_compute (unsigned int bb_inde
 	      unsigned int dregno = DF_REF_REGNO (def);
 	      if (!DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))
 		{
-		  old_unused_notes
-		    = df_create_unused_note (insn, old_unused_notes,
-					     def, live, artificial_uses);
+		  df_create_unused_note (insn,
+					 def, live, artificial_uses);
 		  bitmap_set_bit (do_not_gen, dregno);
 		}
 
@@ -3698,10 +3610,9 @@  df_note_bb_compute (unsigned int bb_inde
 	    {
 	      struct df_mw_hardreg *mws = *mws_rec;
 	      if (DF_MWS_REG_DEF_P (mws))
-		old_unused_notes
-		  = df_set_unused_notes_for_mw (insn, old_unused_notes,
-						mws, live, do_not_gen,
-						artificial_uses);
+		df_set_unused_notes_for_mw (insn,
+					    mws, live, do_not_gen,
+					    artificial_uses);
 	      mws_rec++;
 	    }
 
@@ -3709,9 +3620,8 @@  df_note_bb_compute (unsigned int bb_inde
 	    {
 	      df_ref def = *def_rec;
 	      unsigned int dregno = DF_REF_REGNO (def);
-	      old_unused_notes
-		= df_create_unused_note (insn, old_unused_notes,
-					 def, live, artificial_uses);
+	      df_create_unused_note (insn,
+				     def, live, artificial_uses);
 
 	      if (!DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))
 		bitmap_set_bit (do_not_gen, dregno);
@@ -3731,11 +3641,10 @@  df_note_bb_compute (unsigned int bb_inde
 	    {
 	      bool really_add_notes = debug_insn != 0;
 
-	      old_dead_notes
-		= df_set_dead_notes_for_mw (insn, old_dead_notes,
-					    mws, live, do_not_gen,
-					    artificial_uses,
-					    &really_add_notes);
+	      df_set_dead_notes_for_mw (insn,
+					mws, live, do_not_gen,
+					artificial_uses,
+					&really_add_notes);
 
 	      if (really_add_notes)
 		debug_insn = -1;
@@ -3777,7 +3686,7 @@  df_note_bb_compute (unsigned int bb_inde
 		{
 		  rtx reg = (DF_REF_LOC (use))
                             ? *DF_REF_REAL_LOC (use) : DF_REF_REG (use);
-		  old_dead_notes = df_set_note (REG_DEAD, insn, old_dead_notes, reg);
+		  df_set_note (REG_DEAD, insn, reg);
 
 #ifdef REG_DEAD_DEBUGGING
 		  df_print_note ("adding 4: ", insn, REG_NOTES (insn));
@@ -3788,19 +3697,6 @@  df_note_bb_compute (unsigned int bb_inde
 	    }
 	}
 
-      while (old_unused_notes)
-	{
-	  rtx next = XEXP (old_unused_notes, 1);
-	  free_EXPR_LIST_node (old_unused_notes);
-	  old_unused_notes = next;
-	}
-      while (old_dead_notes)
-	{
-	  rtx next = XEXP (old_dead_notes, 1);
-	  free_EXPR_LIST_node (old_dead_notes);
-	  old_dead_notes = next;
-	}
-
       if (debug_insn == -1)
 	{
 	  /* ??? We could probably do better here, replacing dead
Index: sched-rgn.c
===================================================================
--- sched-rgn.c	(revision 160554)
+++ sched-rgn.c	(working copy)
@@ -54,7 +54,6 @@  along with GCC; see the file COPYING3.
 #include "tm_p.h"
 #include "hard-reg-set.h"
 #include "regs.h"
-#include "function.h"
 #include "flags.h"
 #include "insn-config.h"
 #include "insn-attr.h"
@@ -69,6 +68,8 @@  along with GCC; see the file COPYING3.
 #include "timevar.h"
 #include "tree-pass.h"
 #include "dbgcnt.h"
+#include "function.h"
+#include "emit-rtl.h"
 
 #ifdef INSN_SCHEDULING