summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2008-07-10 07:39:54 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2008-07-10 07:39:54 +0000
commit6c504100f9396621dad2ff7b386c8157887ed0a4 (patch)
treed543916a368659cba776054160616092ec3f7128 /gcc
parentf397ca89a463ba16c66e8db3b82a82256f834f8b (diff)
downloadgcc-6c504100f9396621dad2ff7b386c8157887ed0a4.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@137689 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/combine-stack-adj.c73
-rw-r--r--gcc/dwarf2out.c26
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/g++.dg/eh/async-unwind1.C61
5 files changed, 182 insertions, 7 deletions
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 <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>
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 <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.
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;
+}