diff options
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/ChangeLog | 6 | ||||
| -rw-r--r-- | gcc/cfglayout.c | 69 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.dg/debug-3.c | 35 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.dg/debug-4.c | 27 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.dg/debug-5.c | 47 | 
6 files changed, 178 insertions, 12 deletions
| diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 07a78e4..ea0c886 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c index e0adb53..8ddce14 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 132dc25..75d38d8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/gcc.dg/debug-3.c b/gcc/testsuite/gcc.dg/debug-3.c new file mode 100644 index 0000000..b94c4eb --- /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 0000000..f3cf0c2 --- /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 0000000..4d1d229 --- /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; +  } +} | 
