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
This commit is contained in:
Jakub Jelinek 2001-12-29 21:01:15 +01:00 committed by Jakub Jelinek
parent 9d430eb5b1
commit 545614570c
6 changed files with 178 additions and 12 deletions

View File

@ -1,3 +1,9 @@
2001-12-29 Jakub Jelinek <jakub@redhat.com>
* 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 <rth@redhat.com>
* loop.c (prescan_loop): Set has_multiple_exit_targets for exception

View File

@ -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);
}
}
}

View File

@ -1,3 +1,9 @@
2001-12-29 Jakub Jelinek <jakub@redhat.com>
* 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 <rth@redhat.com>
* g++.dg/eh/loop1.C: New.

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}
}