From 545614570cb5ee234331fc93c562eb146dbba579 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 29 Dec 2001 21:01:15 +0100 Subject: [PATCH] cfglayout.c (insert_intra_before_1): New. * cfglayout.c (insert_intra_before_1): New. (insert_inter_bb_scope_notes): Emit sibling block notes which don't span multiple basic blocks. * gcc.dg/debug-3.c: New test. * gcc.dg/debug-4.c: New test. * gcc.dg/debug-5.c: New test. From-SVN: r48380 --- gcc/ChangeLog | 6 +++ gcc/cfglayout.c | 69 ++++++++++++++++++++++++++++------ gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/gcc.dg/debug-3.c | 35 +++++++++++++++++ gcc/testsuite/gcc.dg/debug-4.c | 27 +++++++++++++ gcc/testsuite/gcc.dg/debug-5.c | 47 +++++++++++++++++++++++ 6 files changed, 178 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug-3.c create mode 100644 gcc/testsuite/gcc.dg/debug-4.c create mode 100644 gcc/testsuite/gcc.dg/debug-5.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 07a78e47ec2..ea0c88651f2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2001-12-29 Jakub Jelinek + + * cfglayout.c (insert_intra_before_1): New. + (insert_inter_bb_scope_notes): Emit sibling block notes which don't + span multiple basic blocks. + 2001-12-29 Richard Henderson * loop.c (prescan_loop): Set has_multiple_exit_targets for exception diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c index e0adb53c71a..8ddce1479a3 100644 --- a/gcc/cfglayout.c +++ b/gcc/cfglayout.c @@ -95,6 +95,7 @@ static void relate_bbs_with_scopes PARAMS ((scope)); static scope make_new_scope PARAMS ((int, rtx)); static void build_scope_forest PARAMS ((scope_forest_info *)); static void remove_scope_notes PARAMS ((void)); +static void insert_intra_before_1 PARAMS ((scope, rtx *, basic_block)); static void insert_intra_1 PARAMS ((scope, rtx *, basic_block)); static void insert_intra_bb_scope_notes PARAMS ((basic_block)); static void insert_inter_bb_scope_notes PARAMS ((basic_block, basic_block)); @@ -578,6 +579,32 @@ insert_intra_1 (s, ip, bb) } } +/* Insert scope note pairs for a contained scope tree S before insn IP. */ + +static void +insert_intra_before_1 (s, ip, bb) + scope s; + rtx *ip; + basic_block bb; +{ + scope p; + + if (NOTE_BLOCK (s->note_beg)) + { + *ip = emit_note_before (NOTE_INSN_BLOCK_END, *ip); + NOTE_BLOCK (*ip) = NOTE_BLOCK (s->note_end); + } + + for (p = s->inner; p; p = p->next) + insert_intra_before_1 (p, ip, bb); + + if (NOTE_BLOCK (s->note_beg)) + { + *ip = emit_note_before (NOTE_INSN_BLOCK_BEG, *ip); + NOTE_BLOCK (*ip) = NOTE_BLOCK (s->note_beg); + } +} + /* Insert NOTE_INSN_BLOCK_END notes and NOTE_INSN_BLOCK_BEG notes for scopes that are contained within BB. */ @@ -661,15 +688,24 @@ insert_inter_bb_scope_notes (bb1, bb2) if (bb1) { rtx end = bb1->end; - scope s; + scope s, p; ip = RBI (bb1)->eff_end; for (s = RBI (bb1)->scope; s != com; s = s->outer) - if (NOTE_BLOCK (s->note_beg)) - { - ip = emit_note_after (NOTE_INSN_BLOCK_END, ip); - NOTE_BLOCK (ip) = NOTE_BLOCK (s->note_end); - } + { + if (NOTE_BLOCK (s->note_beg)) + { + ip = emit_note_after (NOTE_INSN_BLOCK_END, ip); + NOTE_BLOCK (ip) = NOTE_BLOCK (s->note_end); + } + + /* Now emit all sibling scopes which don't span any basic + blocks. */ + if (s->outer) + for (p = s->outer->inner; p; p = p->next) + if (p != s && p->bb_beg == bb1 && p->bb_beg == p->bb_end) + insert_intra_1 (p, &ip, bb1); + } /* Emitting note may move the end of basic block to unwanted place. */ bb1->end = end; @@ -678,15 +714,24 @@ insert_inter_bb_scope_notes (bb1, bb2) /* Open scopes. */ if (bb2) { - scope s; + scope s, p; ip = bb2->head; for (s = RBI (bb2)->scope; s != com; s = s->outer) - if (NOTE_BLOCK (s->note_beg)) - { - ip = emit_note_before (NOTE_INSN_BLOCK_BEG, ip); - NOTE_BLOCK (ip) = NOTE_BLOCK (s->note_beg); - } + { + if (NOTE_BLOCK (s->note_beg)) + { + ip = emit_note_before (NOTE_INSN_BLOCK_BEG, ip); + NOTE_BLOCK (ip) = NOTE_BLOCK (s->note_beg); + } + + /* Now emit all sibling scopes which don't span any basic + blocks. */ + if (s->outer) + for (p = s->outer->inner; p; p = p->next) + if (p != s && p->bb_beg == bb2 && p->bb_beg == p->bb_end) + insert_intra_before_1 (p, &ip, bb2); + } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 132dc255ddc..75d38d829b9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2001-12-29 Jakub Jelinek + + * gcc.dg/debug-3.c: New test. + * gcc.dg/debug-4.c: New test. + * gcc.dg/debug-5.c: New test. + 2001-12-29 Richard Henderson * g++.dg/eh/loop1.C: New. diff --git a/gcc/testsuite/gcc.dg/debug-3.c b/gcc/testsuite/gcc.dg/debug-3.c new file mode 100644 index 00000000000..b94c4eb8abf --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug-3.c @@ -0,0 +1,35 @@ +/* This testcase failed, because scope containing baz was deleted + (spanned 0 basic blocks) and DWARF-2 couldn't find baz origin. */ +/* { dg-do compile } */ +/* { dg-options "-O3 -g" } */ + +struct A { char *a, *b, *c, *d; }; + +static int +bar (struct A *x) +{ + return x->c - x->b; +} + +void fnptr (void (*fn) (void)); + +void +foo (void) +{ + struct A e; + + { + void baz (void) + { + bar (&e); + } + fnptr (baz); + } + { + struct A *f; + + f = &e; + if (f->c - f->a > f->d - f->a) + f->c = f->d; + } +} diff --git a/gcc/testsuite/gcc.dg/debug-4.c b/gcc/testsuite/gcc.dg/debug-4.c new file mode 100644 index 00000000000..f3cf0c2997e --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug-4.c @@ -0,0 +1,27 @@ +/* This testcase failed, because scope containing baz was not emitted + (doesn't contain any instructions) and DWARF-2 couldn't find baz origin. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g" } */ + +struct A { char *a, *b, *c, *d; }; + +static int +bar (struct A *x) +{ + return x->c - x->b; +} + +void +foo (void) +{ + struct A e; + + { + int baz (void) + { + return bar (&e); + } + } + if (e.c - e.a > e.d - e.a) + e.c = e.d; +} diff --git a/gcc/testsuite/gcc.dg/debug-5.c b/gcc/testsuite/gcc.dg/debug-5.c new file mode 100644 index 00000000000..4d1d229b661 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug-5.c @@ -0,0 +1,47 @@ +/* This testcase failed, because scope containing baz was deleted + (spanned 0 basic blocks) and DWARF-2 couldn't find baz origin. */ +/* { dg-do compile } */ +/* { dg-options "-O3 -g" } */ + +extern void abort (void); + +struct A { char *a, *b, *c, *d; }; + +static int +bar (struct A *x) +{ + return x->c - x->b; +} + +static int +bar2 (struct A *x) +{ + int a = x->c - x->b; + x->c += 26; + return a; +} + +void fnptr (void (*fn) (void)); + +void +foo (void) +{ + struct A e; + + if (bar2 (&e) < 0) + abort (); + { + void baz (void) + { + bar (&e); + } + fnptr (baz); + } + { + struct A *f; + + f = &e; + if (f->c - f->a > f->d - f->a) + f->c = f->d; + } +} -- 2.30.2