From 9dcd77b5d4ba45bea3176e89f83f4ef8168cfe1e Mon Sep 17 00:00:00 2001
From: geoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Fri, 25 Feb 2000 18:17:40 +0000
Subject: [PATCH] * haifa-sched.c (schedule_block): Explain the real reason we
 delete REG_SAVE_NOTEs on the first insn of a block. Don't delete
 REG_SAVE_NOTES for NOTE_INSN_SETJMP.

* compile/20000224-1.c: New test.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@32150 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                                 |  6 +++
 gcc/haifa-sched.c                             | 29 ++++++++-----
 gcc/testsuite/gcc.c-torture/ChangeLog         |  4 ++
 .../gcc.c-torture/compile/20000224-1.c        | 41 +++++++++++++++++++
 4 files changed, 70 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/20000224-1.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 92aea2909df3..edb1176f10ad 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2000-02-25  Geoff Keating  <geoffk@cygnus.com>
+
+	* haifa-sched.c (schedule_block): Explain the real reason
+	we delete REG_SAVE_NOTEs on the first insn of a block.
+	Don't delete REG_SAVE_NOTES for NOTE_INSN_SETJMP.
+
 2000-02-24  Mark Mitchell  <mark@codesourcery.com>
 
 	* input.h (push_srcloc): New function.
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index 939ddab2715e..ae81a259d3eb 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -5744,22 +5744,31 @@ schedule_block (bb, rgn_n_insns)
      had different notions of what the "head" insn was.  */
   get_bb_head_tail (bb, &head, &tail);
 
-  /* Interblock scheduling could have moved the original head insn from this
-     block into a proceeding block.  This may also cause schedule_block and
-     compute_forward_dependences to have different notions of what the
-     "head" insn was.
-
-     If the interblock movement happened to make this block start with
-     some notes (LOOP, EH or SETJMP) before the first real insn, then
-     HEAD will have various special notes attached to it which must be
-     removed so that we don't end up with extra copies of the notes.  */
+  /* 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.
+
+     FIXME: Probably the same thing should be done with REG_SAVE_NOTEs
+     referencing NOTE_INSN_SETJMP at the end of the block.  */
   if (GET_RTX_CLASS (GET_CODE (head)) == 'i')
     {
       rtx note;
 
       for (note = REG_NOTES (head); note; note = XEXP (note, 1))
 	if (REG_NOTE_KIND (note) == REG_SAVE_NOTE)
-	  remove_note (head, note);
+	  {
+	    if (INTVAL (XEXP (note, 0)) != NOTE_INSN_SETJMP)
+	      {
+		remove_note (head, note);
+		note = XEXP (note, 1);
+		remove_note (head, note);
+	      }
+	    else
+	      note = XEXP (note, 1);
+	  }
     }
 
   next_tail = NEXT_INSN (tail);
diff --git a/gcc/testsuite/gcc.c-torture/ChangeLog b/gcc/testsuite/gcc.c-torture/ChangeLog
index de4f61d8f2ed..e58e53e2c2b4 100644
--- a/gcc/testsuite/gcc.c-torture/ChangeLog
+++ b/gcc/testsuite/gcc.c-torture/ChangeLog
@@ -1,3 +1,7 @@
+2000-02-25  Geoff Keating  <geoffk@cygnus.com>
+
+	* compile/20000224-1.c: New test.
+
 2000-02-25  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
 
 	* compile/cpp-2.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/compile/20000224-1.c b/gcc/testsuite/gcc.c-torture/compile/20000224-1.c
new file mode 100644
index 000000000000..3572c33cb7fa
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20000224-1.c
@@ -0,0 +1,41 @@
+enum Lisp_Type
+{
+  Lisp_Int                     
+  ,Lisp_Record                 
+  ,Lisp_Cons                   
+  ,Lisp_String                 
+  ,Lisp_Vector                 
+  ,Lisp_Symbol
+  ,Lisp_Char                     
+};
+typedef
+union Lisp_Object
+  {
+    struct
+      {
+        enum Lisp_Type type: 3L ;
+        unsigned long  markbit: 1;
+        unsigned long  val: 60;
+      } gu;
+    long  i;
+  }
+Lisp_Object;
+extern int initialized;
+void
+init_device_faces (int *d)
+{
+  if (initialized)
+    {
+      Lisp_Object tdevice;
+      do {
+          tdevice = (union Lisp_Object)
+                        { gu:
+                          { markbit: 0,
+                            type: Lisp_Record,
+                            val: ((unsigned long )d)
+                          }
+                        };
+      } while (0);
+      call_critical_lisp_code (tdevice);
+    }
+}
-- 
GitLab