diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-08-30 08:27:33 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-08-30 08:27:33 +0000 |
commit | 011634f25a3eebed2a4a9a2041046a83695ff4f6 (patch) | |
tree | 843bcc42b95f46f88f072aea7f1fd140c519891d | |
parent | a5a5e7f1823e3b1f544c67a123fabb1629d6b388 (diff) | |
download | gcc-011634f25a3eebed2a4a9a2041046a83695ff4f6.tar.gz |
PR middle-end/32758
* dce.c (dce_process_block): Don't delete setters of
artificially used registers.
* gcc.dg/cleanup-12.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@127923 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/dce.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cleanup-12.c | 69 |
4 files changed, 88 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e332be879d8..f0254593a26 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 c9ff13fa17b..c5af55ecc12 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 8e6ffd5904a..0fd46770896 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 00000000000..90de90ac831 --- /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 (); +} |