From a182fb6bfe35332c0890dfe6f89e433123f12f04 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 10 Jul 2008 09:39:54 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 18 ++++-- gcc/combine-stack-adj.c | 73 ++++++++++++++++++++++++- gcc/dwarf2out.c | 26 +++++++++ gcc/testsuite/ChangeLog | 11 ++++ gcc/testsuite/g++.dg/eh/async-unwind1.C | 61 +++++++++++++++++++++ 5 files changed, 182 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/eh/async-unwind1.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3e9ce90d36c..c5b36ecbf6c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,12 +1,20 @@ +2008-07-10 Jakub Jelinek + + 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 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 diff --git a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c index bf7cccf2df7..afcb35b33ea 100644 --- a/gcc/combine-stack-adj.c +++ b/gcc/combine-stack-adj.c @@ -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; diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 80bdc0a4bb0..46ab10481d5 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7518595c775..3c153292307 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2008-07-10 Jakub Jelinek + + PR rtl-optimization/36419 + * g++.dg/eh/async-unwind1.C: New test. + +2008-07-10 Peter Maydell + + 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 * gcc.dg/no-asm-1.c: New test. diff --git a/gcc/testsuite/g++.dg/eh/async-unwind1.C b/gcc/testsuite/g++.dg/eh/async-unwind1.C new file mode 100644 index 00000000000..69b2c345e75 --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/async-unwind1.C @@ -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; +} -- 2.30.2