re PR debug/42918 ("-fcompare-debug failure" with "-O2 -ftracer" (2))

PR debug/42918
	* caller-save.c (save_call_clobbered_regs): If BB ends with
	a DEBUG_INSN, move any notes in between last real insn and the last
	DEBUG_INSN after the last DEBUG_INSN.

	* gcc.dg/pr42918.c: New test.

From-SVN: r156823
This commit is contained in:
Jakub Jelinek 2010-02-17 09:54:59 +01:00 committed by Jakub Jelinek
parent 32ade5590e
commit 169e464e66
4 changed files with 66 additions and 2 deletions

View file

@ -1,3 +1,10 @@
2010-02-17 Jakub Jelinek <jakub@redhat.com>
PR debug/42918
* caller-save.c (save_call_clobbered_regs): If BB ends with
a DEBUG_INSN, move any notes in between last real insn and the last
DEBUG_INSN after the last DEBUG_INSN.
2010-02-16 Joern Rennecke <joern.rennecke@embecosm.com>
* tm.texi (TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD_SPEC):

View file

@ -1,6 +1,6 @@
/* Save and restore call-clobbered registers which are live across a call.
Copyright (C) 1989, 1992, 1994, 1995, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
This file is part of GCC.
@ -754,7 +754,7 @@ setup_save_areas (void)
void
save_call_clobbered_regs (void)
{
struct insn_chain *chain, *next;
struct insn_chain *chain, *next, *last = NULL;
enum machine_mode save_mode [FIRST_PSEUDO_REGISTER];
/* Computed in mark_set_regs, holds all registers set by the current
@ -861,6 +861,7 @@ save_call_clobbered_regs (void)
if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
n_regs_saved++;
}
last = chain;
}
else if (DEBUG_INSN_P (insn) && n_regs_saved)
mark_referenced_regs (&PATTERN (insn),
@ -874,6 +875,36 @@ save_call_clobbered_regs (void)
remain saved. If the last insn in the block is a JUMP_INSN, put
the restore before the insn, otherwise, put it after the insn. */
if (DEBUG_INSN_P (insn) && last && last->block == chain->block)
{
rtx ins, prev;
basic_block bb = BLOCK_FOR_INSN (insn);
/* When adding hard reg restores after a DEBUG_INSN, move
all notes between last real insn and this DEBUG_INSN after
the DEBUG_INSN, otherwise we could get code
-g/-g0 differences. */
for (ins = PREV_INSN (insn); ins != last->insn; ins = prev)
{
prev = PREV_INSN (ins);
if (NOTE_P (ins))
{
NEXT_INSN (prev) = NEXT_INSN (ins);
PREV_INSN (NEXT_INSN (ins)) = prev;
PREV_INSN (ins) = insn;
NEXT_INSN (ins) = NEXT_INSN (insn);
NEXT_INSN (insn) = ins;
if (NEXT_INSN (ins))
PREV_INSN (NEXT_INSN (ins)) = ins;
if (BB_END (bb) == insn)
BB_END (bb) = ins;
}
else
gcc_assert (DEBUG_INSN_P (ins));
}
}
last = NULL;
if (n_regs_saved)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (TEST_HARD_REG_BIT (hard_regs_saved, regno))

View file

@ -1,3 +1,8 @@
2010-02-17 Jakub Jelinek <jakub@redhat.com>
PR debug/42918
* gcc.dg/pr42918.c: New test.
2010-02-16 H.J. Lu <hongjiu.lu@intel.com>
* g++.dg/ext/attrib36.C: Require ILP32.

View file

@ -0,0 +1,21 @@
/* PR debug/42918 */
/* { dg-do compile } */
/* { dg-options "-O2 -fcompare-debug -ftracer" } */
extern int fi (void);
extern void fv (void);
int
f (int i, int j)
{
if (!j)
{
fv ();
goto lab;
}
i = fi ();
if (i == j)
fv ();
lab:
return i;
}