haifa-sched.c (reemit_other_notes): New.
authorRichard Henderson <rth@redhat.com>
Thu, 27 Dec 2001 22:19:59 +0000 (14:19 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 27 Dec 2001 22:19:59 +0000 (14:19 -0800)
        * haifa-sched.c (reemit_other_notes): New.
        (schedule_block): Use it.
        * sched-ebb.c (schedule_ebbs): Call remove_unnecessary_notes.
        * sched-rgn.c (schedule_insns): Likewise.
        * cfglayout.c (remove_scope_notes): Handle removing note at
        the end of the insn chain.
        * function.c (debug_find_var_in_block_tree): New.

        * gcc.dg/debug-1.c, gcc.dg/debug-2.c: New.

From-SVN: r48333

gcc/ChangeLog
gcc/cfglayout.c
gcc/function.c
gcc/haifa-sched.c
gcc/sched-ebb.c
gcc/sched-rgn.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/debug-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/debug-2.c [new file with mode: 0644]

index e42d64b..c6c6b92 100644 (file)
@@ -1,3 +1,13 @@
+2001-12-27  Richard Henderson  <rth@redhat.com>
+
+       * haifa-sched.c (reemit_other_notes): New.
+       (schedule_block): Use it.
+       * sched-ebb.c (schedule_ebbs): Call remove_unnecessary_notes.
+       * sched-rgn.c (schedule_insns): Likewise.
+       * cfglayout.c (remove_scope_notes): Handle removing note at
+       the end of the insn chain.
+       * function.c (debug_find_var_in_block_tree): New.
+
 2001-12-27  Alan Modra  <amodra@bigpond.net.au>
            David Edelsohn  <edelsohn@gnu.org>
 
index 14f08eb..e0adb53 100644 (file)
@@ -540,7 +540,8 @@ remove_scope_notes ()
          if (PREV_INSN (x))
            {
              NEXT_INSN (PREV_INSN (x)) = next;
-             PREV_INSN (next) = PREV_INSN (x);
+             if (next)
+               PREV_INSN (next) = PREV_INSN (x);
 
               NEXT_INSN (x) = NULL;
               PREV_INSN (x) = NULL;
index f5a3102..097aea4 100644 (file)
@@ -277,6 +277,7 @@ static void reorder_fix_fragments PARAMS ((tree));
 static tree blocks_nreverse    PARAMS ((tree));
 static int all_blocks          PARAMS ((tree, tree *));
 static tree *get_block_vector   PARAMS ((tree, int *));
+extern tree debug_find_var_in_block_tree PARAMS ((tree, tree));
 /* We always define `record_insns' even if its not used so that we
    can always export `prologue_epilogue_contains'.  */
 static void record_insns       PARAMS ((rtx, varray_type *)) ATTRIBUTE_UNUSED;
@@ -6051,6 +6052,29 @@ number_blocks (fn)
 
   return;
 }
+
+/* If VAR is present in a subblock of BLOCK, return the subblock.  */
+
+tree
+debug_find_var_in_block_tree (var, block)
+     tree var;
+     tree block;
+{
+  tree t;
+
+  for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
+    if (t == var)
+      return block;
+
+  for (t = BLOCK_SUBBLOCKS (block); t; t = TREE_CHAIN (t))
+    {
+      tree ret = debug_find_var_in_block_tree (var, t);
+      if (ret)
+       return ret;
+    }
+
+  return NULL_TREE;
+}
 \f
 /* Allocate a function structure and reset its contents to the defaults.  */
 
index 7b9a2e8..ca6cfbb 100644 (file)
@@ -319,6 +319,7 @@ static void adjust_priority PARAMS ((rtx));
 static rtx unlink_other_notes PARAMS ((rtx, rtx));
 static rtx unlink_line_notes PARAMS ((rtx, rtx));
 static rtx reemit_notes PARAMS ((rtx, rtx));
+static rtx reemit_other_notes PARAMS ((rtx, rtx));
 
 static rtx *ready_lastpos PARAMS ((struct ready_list *));
 static void ready_sort PARAMS ((struct ready_list *));
@@ -1575,6 +1576,60 @@ reemit_notes (insn, last)
   return retval;
 }
 
+
+/* NOTE_LIST is the end of a chain of notes previously found among the
+   insns.  Insert them at the beginning of the insns.  Actually, insert
+   NOTE_INSN_BLOCK_END notes at the end of the insns.  Doing otherwise
+   tends to collapse lexical blocks into empty regions, which is somewhat
+   less than useful.  */
+/* ??? Ideally we'd mark each insn with the block it originated from,
+   and preserve that information.  This requires some moderately
+   sophisticated block reconstruction code, since block nestings must
+   be preserved.  */
+
+static rtx
+reemit_other_notes (head, tail)
+     rtx head, tail;
+{
+  bool saw_block_beg = false;
+
+  while (note_list)
+    {
+      rtx note_tail = note_list;
+      note_list = PREV_INSN (note_tail);
+
+      if (NOTE_LINE_NUMBER (note_tail) == NOTE_INSN_BLOCK_END
+         /* We can only extend the lexical block while we havn't
+            seen a BLOCK_BEG note.  Otherwise we risk mis-nesting
+            the notes.  */
+         && ! saw_block_beg)
+       {
+         rtx insert_after = tail;
+         if (GET_CODE (NEXT_INSN (tail)) == BARRIER)
+           insert_after = NEXT_INSN (tail);
+
+         PREV_INSN (note_tail) = insert_after;
+         NEXT_INSN (note_tail) = NEXT_INSN (insert_after);
+         if (NEXT_INSN (insert_after))
+           PREV_INSN (NEXT_INSN (insert_after)) = note_tail;
+         NEXT_INSN (insert_after) = note_tail;
+       }
+      else
+       {
+         if (NOTE_LINE_NUMBER (note_tail) == NOTE_INSN_BLOCK_BEG)
+           saw_block_beg = true;
+
+         PREV_INSN (note_tail) = PREV_INSN (head);
+         NEXT_INSN (PREV_INSN (head)) = note_tail;
+         NEXT_INSN (note_tail) = head;
+         PREV_INSN (head) = note_tail;
+         head = note_tail;
+       }
+    }
+
+  return head;
+}
+
 /* Move INSN, and all insns which should be issued before it,
    due to SCHED_GROUP_P flag.  Reemit notes if needed.
 
@@ -1800,24 +1855,7 @@ schedule_block (b, rgn_n_insns)
   head = NEXT_INSN (prev_head);
   tail = last;
 
-  /* Restore-other-notes: NOTE_LIST is the end of a chain of notes
-     previously found among the insns.  Insert them at the beginning
-     of the insns.  */
-  if (note_list != 0)
-    {
-      rtx note_head = note_list;
-
-      while (PREV_INSN (note_head))
-       {
-         note_head = PREV_INSN (note_head);
-       }
-
-      PREV_INSN (note_head) = PREV_INSN (head);
-      NEXT_INSN (PREV_INSN (head)) = note_head;
-      PREV_INSN (head) = note_list;
-      NEXT_INSN (note_list) = head;
-      head = note_head;
-    }
+  head = reemit_other_notes (head, tail);
 
   /* Debugging.  */
   if (sched_verbose)
index d4a9f77..13b9fe6 100644 (file)
@@ -285,6 +285,10 @@ schedule_ebbs (dump_file)
   if (n_basic_blocks == 0)
     return;
 
+  /* Remove lexical block notes for empty regions.  These get shuffled
+     about during scheduling and confuse the debugging issue.  */
+  remove_unnecessary_notes ();
+
   sched_init (dump_file);
 
   current_sched_info = &ebb_sched_info;
index ab5adee..6824204 100644 (file)
@@ -2896,6 +2896,10 @@ schedule_insns (dump_file)
   if (n_basic_blocks == 0)
     return;
 
+  /* Remove lexical block notes for empty regions.  These get shuffled
+     about during scheduling and confuse the debugging issue.  */
+  remove_unnecessary_notes ();
+
   nr_inter = 0;
   nr_spec = 0;
 
index 698296b..915a148 100644 (file)
@@ -1,3 +1,7 @@
+2001-12-27  Richard Henderson  <rth@redhat.com>
+
+       * gcc.dg/debug-1.c, gcc.dg/debug-2.c: New.
+
 2001-12-26  Nathan Sidwell  <nathan@codesourcery.com>
 
        * g++.dg/eh/ctor1.C: New test.
diff --git a/gcc/testsuite/gcc.dg/debug-1.c b/gcc/testsuite/gcc.dg/debug-1.c
new file mode 100644 (file)
index 0000000..1e53b14
--- /dev/null
@@ -0,0 +1,14 @@
+/* Verify that the scheduler does not discard the lexical block.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -g -dA" } */
+/* { dg-final { scan-assembler "xyzzy" } } */
+
+long foo(long p)
+{
+  {
+    long xyzzy = 0;
+    if (p)
+      xyzzy = 2;
+    return xyzzy;
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/debug-2.c b/gcc/testsuite/gcc.dg/debug-2.c
new file mode 100644 (file)
index 0000000..4305059
--- /dev/null
@@ -0,0 +1,20 @@
+/* Verify that the scheduler does not discard the lexical block.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -g -dA" } */
+/* { dg-final { scan-assembler "xyzzy" } } */
+
+long foo(long p)
+{
+  if (1)
+    {
+      long xyzzy = 0;
+      if (p)
+        xyzzy = 2;
+      return xyzzy;
+    }
+  else
+    {
+      int x = 0;
+      return x;
+    }
+}