summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2001-12-27 14:19:59 -0800
committerRichard Henderson <rth@gcc.gnu.org>2001-12-27 14:19:59 -0800
commitdf8992f8f3270619b200bd065b3da9de118efc77 (patch)
treea7f9af2b63f2968b5377756f9c3886f53c2600dd
parentbb2ae697ab610f10045da76435c9934d06dce608 (diff)
downloadgcc-df8992f8f3270619b200bd065b3da9de118efc77.tar.gz
haifa-sched.c (reemit_other_notes): New.
* 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
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/cfglayout.c3
-rw-r--r--gcc/function.c24
-rw-r--r--gcc/haifa-sched.c74
-rw-r--r--gcc/sched-ebb.c4
-rw-r--r--gcc/sched-rgn.c4
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/debug-1.c14
-rw-r--r--gcc/testsuite/gcc.dg/debug-2.c20
9 files changed, 138 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e42d64be1ff..c6c6b921e2a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index 14f08eb39ef..e0adb53c71a 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -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;
diff --git a/gcc/function.c b/gcc/function.c
index f5a3102bf4d..097aea44684 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -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;
+}
/* Allocate a function structure and reset its contents to the defaults. */
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index 7b9a2e82126..ca6cfbb1d4f 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -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)
diff --git a/gcc/sched-ebb.c b/gcc/sched-ebb.c
index d4a9f777653..13b9fe6602d 100644
--- a/gcc/sched-ebb.c
+++ b/gcc/sched-ebb.c
@@ -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;
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index ab5adee8159..68242046221 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 698296b87a0..915a148a432 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..1e53b14eb5c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug-1.c
@@ -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
index 00000000000..4305059ba7b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug-2.c
@@ -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;
+ }
+}