summaryrefslogtreecommitdiff
path: root/gcc/dce.c
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2007-08-30 08:27:33 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2007-08-30 08:27:33 +0000
commit011634f25a3eebed2a4a9a2041046a83695ff4f6 (patch)
tree843bcc42b95f46f88f072aea7f1fd140c519891d /gcc/dce.c
parenta5a5e7f1823e3b1f544c67a123fabb1629d6b388 (diff)
downloadgcc-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
Diffstat (limited to 'gcc/dce.c')
-rw-r--r--gcc/dce.c13
1 files changed, 12 insertions, 1 deletions
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;