aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/dce.c13
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.dg/cleanup-12.c69
4 files changed, 88 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e332be8..f025459 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -5,6 +5,10 @@
SImode and update m. Don't run gen_lowpart_common on arbitrary
memory address, force it to register first.
+ PR middle-end/32758
+ * dce.c (dce_process_block): Don't delete setters of
+ artificially used registers.
+
2007-08-30 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* config/s390/s390.md ("*add<mode>3_alc_carry1_cc",
diff --git a/gcc/dce.c b/gcc/dce.c
index c9ff13f..c5af55e 100644
--- a/gcc/dce.c
+++ b/gcc/dce.c
@@ -527,6 +527,7 @@ static bool
dce_process_block (basic_block bb, bool redo_out)
{
bitmap local_live = BITMAP_ALLOC (&dce_tmp_bitmap_obstack);
+ bitmap au;
rtx insn;
bool block_changed;
struct df_ref **def_rec, **use_rec;
@@ -569,6 +570,15 @@ dce_process_block (basic_block bb, bool redo_out)
bitmap_set_bit (local_live, DF_REF_REGNO (use));
}
+ /* These regs are considered always live so if they end up dying
+ because of some def, we need to bring the back again.
+ Calling df_simulate_fixup_sets has the disadvantage of calling
+ df_has_eh_preds once per insn, so we cache the information here. */
+ if (df_has_eh_preds (bb))
+ au = df->eh_block_artificial_uses;
+ else
+ au = df->regular_block_artificial_uses;
+
FOR_BB_INSNS_REVERSE (bb, insn)
if (INSN_P (insn))
{
@@ -580,7 +590,8 @@ dce_process_block (basic_block bb, bool redo_out)
/* The insn is needed if there is someone who uses the output. */
for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
- if (bitmap_bit_p (local_live, DF_REF_REGNO (*def_rec)))
+ if (bitmap_bit_p (local_live, DF_REF_REGNO (*def_rec))
+ || bitmap_bit_p (au, DF_REF_REGNO (*def_rec)))
{
needed = true;
break;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8e6ffd5..0fd4677 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -4,6 +4,9 @@
(AI): Add AI_ALIGN.
* gcc.dg/sync-3.c: New test.
+ PR middle-end/32758
+ * gcc.dg/cleanup-12.c: New test.
+
2007-08-30 Uros Bizjak <ubizjak@gmail.com>
* lib/gcc-dg.exp (cleanup-profile-file): New procedure.
diff --git a/gcc/testsuite/gcc.dg/cleanup-12.c b/gcc/testsuite/gcc.dg/cleanup-12.c
new file mode 100644
index 0000000..90de90a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cleanup-12.c
@@ -0,0 +1,69 @@
+/* PR middle-end/32758 */
+/* HP-UX libunwind.so doesn't provide _UA_END_OF_STACK */
+/* { dg-do run } */
+/* { dg-options "-O2 -fexceptions" } */
+/* { dg-skip-if "" { "ia64-*-hpux11.*" } { "*" } { "" } } */
+/* Verify unwind info in presence of alloca. */
+
+#include <unwind.h>
+#include <stdlib.h>
+#include <string.h>
+
+static _Unwind_Reason_Code
+force_unwind_stop (int version, _Unwind_Action actions,
+ _Unwind_Exception_Class exc_class,
+ struct _Unwind_Exception *exc_obj,
+ struct _Unwind_Context *context,
+ void *stop_parameter)
+{
+ if (actions & _UA_END_OF_STACK)
+ abort ();
+ return _URC_NO_REASON;
+}
+
+static void force_unwind (void)
+{
+ struct _Unwind_Exception *exc = malloc (sizeof (*exc));
+ memset (&exc->exception_class, 0, sizeof (exc->exception_class));
+ exc->exception_cleanup = 0;
+
+#ifndef __USING_SJLJ_EXCEPTIONS__
+ _Unwind_ForcedUnwind (exc, force_unwind_stop, 0);
+#else
+ _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0);
+#endif
+
+ abort ();
+}
+
+__attribute__((noinline))
+void foo (void *x __attribute__((unused)))
+{
+ force_unwind ();
+}
+
+__attribute__((noinline))
+int bar (unsigned int x)
+{
+ void *y = __builtin_alloca (x);
+ foo (y);
+ return 1;
+}
+
+static void handler (void *p __attribute__((unused)))
+{
+ exit (0);
+}
+
+__attribute__((noinline))
+static void doit ()
+{
+ char dummy __attribute__((cleanup (handler)));
+ bar (1024);
+}
+
+int main ()
+{
+ doit ();
+ abort ();
+}