re PR rtl-optimization/36419 (Wrong unwind info with -Os -fasynchronous-unwind-tables)
PR rtl-optimization/36419 * combine-stack-adj.c (adjust_frame_related_expr): New function. (combine_stack_adjustments_for_block): Call it if needed. Delete correct insn. * dwarf2out.c (dwarf2out_frame_debug_expr): Adjust DW_CFA_GNU_args_size if CSA pass merged some adjustments into prologue sp adjustment. * g++.dg/eh/async-unwind1.C: New test. From-SVN: r137689
This commit is contained in:
parent
b1caaefc1c
commit
a182fb6bfe
@ -1,12 +1,20 @@
|
||||
2008-07-10 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/36419
|
||||
* combine-stack-adj.c (adjust_frame_related_expr): New function.
|
||||
(combine_stack_adjustments_for_block): Call it if needed. Delete
|
||||
correct insn.
|
||||
* dwarf2out.c (dwarf2out_frame_debug_expr): Adjust
|
||||
DW_CFA_GNU_args_size if CSA pass merged some adjustments into
|
||||
prologue sp adjustment.
|
||||
|
||||
2008-07-10 Peter Maydell <pmaydell@chiark.greenend.org.uk>
|
||||
|
||||
PR other/28322
|
||||
* opts.c (print_ignored_options): report postponed diagnostics for
|
||||
* opts.c (print_ignored_options): Report postponed diagnostics for
|
||||
unknown -Wno-* options as warnings, not errors.
|
||||
(postpone_unknown_option_error): renamed to
|
||||
postpone_unknown_option_warning.
|
||||
* gcc.dg/pr28322-2.c: check that emitted diagnostic for -Wno-foobar
|
||||
is a warning and not an error.
|
||||
(postpone_unknown_option_error): Renamed to...
|
||||
(postpone_unknown_option_warning): ... this.
|
||||
|
||||
2008-07-09 Doug Kwan <dougkwan@google.com>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Combine stack adjustments.
|
||||
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
|
||||
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
@ -272,6 +272,72 @@ record_stack_memrefs (rtx *xp, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Adjust or create REG_FRAME_RELATED_EXPR note when merging a stack
|
||||
adjustment into a frame related insn. */
|
||||
|
||||
static void
|
||||
adjust_frame_related_expr (rtx last_sp_set, rtx insn,
|
||||
HOST_WIDE_INT this_adjust)
|
||||
{
|
||||
rtx note = find_reg_note (last_sp_set, REG_FRAME_RELATED_EXPR, NULL_RTX);
|
||||
rtx new_expr = NULL_RTX;
|
||||
|
||||
if (note == NULL_RTX && RTX_FRAME_RELATED_P (insn))
|
||||
return;
|
||||
|
||||
if (note
|
||||
&& GET_CODE (XEXP (note, 0)) == SEQUENCE
|
||||
&& XVECLEN (XEXP (note, 0), 0) >= 2)
|
||||
{
|
||||
rtx expr = XEXP (note, 0);
|
||||
rtx last = XVECEXP (expr, 0, XVECLEN (expr, 0) - 1);
|
||||
int i;
|
||||
|
||||
if (GET_CODE (last) == SET
|
||||
&& RTX_FRAME_RELATED_P (last) == RTX_FRAME_RELATED_P (insn)
|
||||
&& SET_DEST (last) == stack_pointer_rtx
|
||||
&& GET_CODE (SET_SRC (last)) == PLUS
|
||||
&& XEXP (SET_SRC (last), 0) == stack_pointer_rtx
|
||||
&& GET_CODE (XEXP (SET_SRC (last), 1)) == CONST_INT)
|
||||
{
|
||||
XEXP (SET_SRC (last), 1)
|
||||
= GEN_INT (INTVAL (XEXP (SET_SRC (last), 1)) + this_adjust);
|
||||
return;
|
||||
}
|
||||
|
||||
new_expr = gen_rtx_SEQUENCE (VOIDmode,
|
||||
rtvec_alloc (XVECLEN (expr, 0) + 1));
|
||||
for (i = 0; i < XVECLEN (expr, 0); i++)
|
||||
XVECEXP (new_expr, 0, i) = XVECEXP (expr, 0, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_expr = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (2));
|
||||
if (note)
|
||||
XVECEXP (new_expr, 0, 0) = XEXP (note, 0);
|
||||
else
|
||||
{
|
||||
rtx expr = copy_rtx (single_set_for_csa (last_sp_set));
|
||||
|
||||
XEXP (SET_SRC (expr), 1)
|
||||
= GEN_INT (INTVAL (XEXP (SET_SRC (expr), 1)) - this_adjust);
|
||||
RTX_FRAME_RELATED_P (expr) = 1;
|
||||
XVECEXP (new_expr, 0, 0) = expr;
|
||||
}
|
||||
}
|
||||
|
||||
XVECEXP (new_expr, 0, XVECLEN (new_expr, 0) - 1)
|
||||
= copy_rtx (single_set_for_csa (insn));
|
||||
RTX_FRAME_RELATED_P (XVECEXP (new_expr, 0, XVECLEN (new_expr, 0) - 1))
|
||||
= RTX_FRAME_RELATED_P (insn);
|
||||
if (note)
|
||||
XEXP (note, 0) = new_expr;
|
||||
else
|
||||
REG_NOTES (last_sp_set)
|
||||
= gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, new_expr,
|
||||
REG_NOTES (last_sp_set));
|
||||
}
|
||||
|
||||
/* Subroutine of combine_stack_adjustments, called for each basic block. */
|
||||
|
||||
static void
|
||||
@ -343,6 +409,9 @@ combine_stack_adjustments_for_block (basic_block bb)
|
||||
last_sp_adjust + this_adjust,
|
||||
this_adjust))
|
||||
{
|
||||
if (RTX_FRAME_RELATED_P (last_sp_set))
|
||||
adjust_frame_related_expr (last_sp_set, insn,
|
||||
this_adjust);
|
||||
/* It worked! */
|
||||
delete_insn (insn);
|
||||
last_sp_adjust += this_adjust;
|
||||
@ -373,7 +442,7 @@ combine_stack_adjustments_for_block (basic_block bb)
|
||||
deallocation+allocation conspired to cancel, we can
|
||||
delete the old deallocation insn. */
|
||||
if (last_sp_set && last_sp_adjust == 0)
|
||||
delete_insn (insn);
|
||||
delete_insn (last_sp_set);
|
||||
free_csa_memlist (memlist);
|
||||
memlist = NULL;
|
||||
last_sp_set = insn;
|
||||
|
@ -1579,6 +1579,32 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label)
|
||||
&& (!MEM_P (SET_DEST (elem)) || GET_CODE (expr) == SEQUENCE)
|
||||
&& (RTX_FRAME_RELATED_P (elem) || par_index == 0))
|
||||
dwarf2out_frame_debug_expr (elem, label);
|
||||
else if (GET_CODE (elem) == SET
|
||||
&& par_index != 0
|
||||
&& !RTX_FRAME_RELATED_P (elem))
|
||||
{
|
||||
/* Stack adjustment combining might combine some post-prologue
|
||||
stack adjustment into a prologue stack adjustment. */
|
||||
HOST_WIDE_INT offset = stack_adjust_offset (elem);
|
||||
|
||||
if (offset != 0)
|
||||
{
|
||||
if (cfa.reg == STACK_POINTER_REGNUM)
|
||||
cfa.offset += offset;
|
||||
|
||||
#ifndef STACK_GROWS_DOWNWARD
|
||||
offset = -offset;
|
||||
#endif
|
||||
|
||||
args_size += offset;
|
||||
if (args_size < 0)
|
||||
args_size = 0;
|
||||
|
||||
def_cfa_1 (label, &cfa);
|
||||
if (flag_asynchronous_unwind_tables)
|
||||
dwarf2out_args_size (label, args_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1,3 +1,14 @@
|
||||
2008-07-10 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/36419
|
||||
* g++.dg/eh/async-unwind1.C: New test.
|
||||
|
||||
2008-07-10 Peter Maydell <pmaydell@chiark.greenend.org.uk>
|
||||
|
||||
PR other/28322
|
||||
* gcc.dg/pr28322-2.c: Check that emitted diagnostic for -Wno-foobar
|
||||
is a warning and not an error.
|
||||
|
||||
2008-07-09 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* gcc.dg/no-asm-1.c: New test.
|
||||
|
61
gcc/testsuite/g++.dg/eh/async-unwind1.C
Normal file
61
gcc/testsuite/g++.dg/eh/async-unwind1.C
Normal file
@ -0,0 +1,61 @@
|
||||
// PR rtl-optimization/36419
|
||||
// { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } }
|
||||
// { dg-options "-Os -fasynchronous-unwind-tables -mpreferred-stack-boundary=4" }
|
||||
|
||||
extern "C" void abort ();
|
||||
|
||||
int v = -1;
|
||||
unsigned int n;
|
||||
|
||||
__attribute__((noinline, used))
|
||||
void foo (int a, int)
|
||||
{
|
||||
if (v < 0)
|
||||
v = ((unsigned long) &a) & 15;
|
||||
else if ((((unsigned long) &a) & 15) != v)
|
||||
abort ();
|
||||
if (n++ == 0)
|
||||
throw 1;
|
||||
}
|
||||
|
||||
__attribute__((noinline, used))
|
||||
void baz (int a, int, int, int, int, int, int)
|
||||
{
|
||||
if (v < 0)
|
||||
v = ((unsigned long) &a) & 15;
|
||||
else if ((((unsigned long) &a) & 15) != v)
|
||||
abort ();
|
||||
if (n++ == 0)
|
||||
throw 1;
|
||||
}
|
||||
|
||||
struct A { A () { }; ~A (); char c[24]; };
|
||||
|
||||
__attribute__((noinline))
|
||||
A::~A ()
|
||||
{
|
||||
asm volatile ("" : : : "memory");
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
void bar ()
|
||||
{
|
||||
A a;
|
||||
try
|
||||
{
|
||||
foo (1, 2);
|
||||
baz (3, 4, 5, 6, 7, 8, 9);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
foo (1, 2);
|
||||
baz (3, 4, 5, 6, 7, 8, 9);
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
bar ();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user