summaryrefslogtreecommitdiff
path: root/gcc/dce.c
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2012-04-13 15:56:21 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2012-04-13 15:56:21 +0000
commit1adbb3614d87c487eb0b3c3eebbe1c6bb6e7438f (patch)
tree283216c0c3a9019c8feb931e55ba7d5c90f81f3e /gcc/dce.c
parent6ae1d471b16228d47bbcfbe3b2b90c323a0af1ba (diff)
downloadgcc-1adbb3614d87c487eb0b3c3eebbe1c6bb6e7438f.tar.gz
re PR debug/48866 (gcc hangs when -g is set)
PR debug/48866 * df.h (enum debug_temp_where): New. (dead_debug_init, dead_debug_finish) Declare. (dead_debug_add, dead_debug_insert_temp): Declare. (struct dead_debug_use, struct dead_debug): Moved from... * df-problems.c: ... here. (df_set_unused_notes_for_mw): Bind debug uses of unused regno to a debug temp. (df_create_unused_note): Likewise. (df_set_dead_notes_for_mw): Move comment where it belongs. (dead_debug_init): Export. (dead_debug_reset_uses): New, factored out of... (dead_debug_finish): ...this. Export. (dead_debug_reset): Remove. (dead_debug_add): Export. (dead_debug_insert_before): Rename to... (dead_debug_insert_temp): ... this. Add where argument. Export. Locate stored value for BEFORE_WITH_VALUE. Avoid repeat inserts. Return insertion count. (df_note_bb_compute): Adjust. * dce.c (word_dce_process_block): Adjust dead debug uses. (dce_process_block): Likewise. From-SVN: r186422
Diffstat (limited to 'gcc/dce.c')
-rw-r--r--gcc/dce.c58
1 files changed, 49 insertions, 9 deletions
diff --git a/gcc/dce.c b/gcc/dce.c
index a36ac61dea8..c706296c663 100644
--- a/gcc/dce.c
+++ b/gcc/dce.c
@@ -807,6 +807,7 @@ word_dce_process_block (basic_block bb, bool redo_out)
bitmap local_live = BITMAP_ALLOC (&dce_tmp_bitmap_obstack);
rtx insn;
bool block_changed;
+ struct dead_debug debug;
if (redo_out)
{
@@ -828,11 +829,24 @@ word_dce_process_block (basic_block bb, bool redo_out)
}
bitmap_copy (local_live, DF_WORD_LR_OUT (bb));
+ dead_debug_init (&debug, NULL);
FOR_BB_INSNS_REVERSE (bb, insn)
- if (NONDEBUG_INSN_P (insn))
+ if (DEBUG_INSN_P (insn))
+ {
+ df_ref *use_rec;
+ for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++)
+ if (DF_REF_REGNO (*use_rec) >= FIRST_PSEUDO_REGISTER
+ && (GET_MODE_SIZE (GET_MODE (DF_REF_REAL_REG (*use_rec)))
+ == 2 * UNITS_PER_WORD)
+ && !bitmap_bit_p (local_live, 2 * DF_REF_REGNO (*use_rec))
+ && !bitmap_bit_p (local_live, 2 * DF_REF_REGNO (*use_rec) + 1))
+ dead_debug_add (&debug, *use_rec, DF_REF_REGNO (*use_rec));
+ }
+ else if (INSN_P (insn))
{
bool any_changed;
+
/* No matter if the instruction is needed or not, we remove
any regno in the defs from the live set. */
any_changed = df_word_lr_simulate_defs (insn, local_live);
@@ -844,6 +858,15 @@ word_dce_process_block (basic_block bb, bool redo_out)
if (marked_insn_p (insn))
df_word_lr_simulate_uses (insn, local_live);
+ if (debug.used && !bitmap_empty_p (debug.used))
+ {
+ df_ref *def_rec;
+
+ for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
+ dead_debug_insert_temp (&debug, DF_REF_REGNO (*def_rec), insn,
+ DEBUG_TEMP_BEFORE_WITH_VALUE);
+ }
+
if (dump_file)
{
fprintf (dump_file, "finished processing insn %d live out = ",
@@ -856,6 +879,7 @@ word_dce_process_block (basic_block bb, bool redo_out)
if (block_changed)
bitmap_copy (DF_WORD_LR_IN (bb), local_live);
+ dead_debug_finish (&debug, NULL);
BITMAP_FREE (local_live);
return block_changed;
}
@@ -873,6 +897,7 @@ dce_process_block (basic_block bb, bool redo_out, bitmap au)
rtx insn;
bool block_changed;
df_ref *def_rec;
+ struct dead_debug debug;
if (redo_out)
{
@@ -896,22 +921,36 @@ dce_process_block (basic_block bb, bool redo_out, bitmap au)
bitmap_copy (local_live, DF_LR_OUT (bb));
df_simulate_initialize_backwards (bb, local_live);
+ dead_debug_init (&debug, NULL);
FOR_BB_INSNS_REVERSE (bb, insn)
- if (INSN_P (insn))
+ if (DEBUG_INSN_P (insn))
+ {
+ df_ref *use_rec;
+ for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++)
+ if (!bitmap_bit_p (local_live, DF_REF_REGNO (*use_rec))
+ && !bitmap_bit_p (au, DF_REF_REGNO (*use_rec)))
+ dead_debug_add (&debug, *use_rec, DF_REF_REGNO (*use_rec));
+ }
+ else if (INSN_P (insn))
{
bool needed = marked_insn_p (insn);
/* The insn is needed if there is someone who uses the output. */
if (!needed)
for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
- if (bitmap_bit_p (local_live, DF_REF_REGNO (*def_rec))
- || bitmap_bit_p (au, DF_REF_REGNO (*def_rec)))
- {
- needed = true;
- mark_insn (insn, true);
- break;
- }
+ {
+ dead_debug_insert_temp (&debug, DF_REF_REGNO (*def_rec), insn,
+ DEBUG_TEMP_BEFORE_WITH_VALUE);
+
+ if (bitmap_bit_p (local_live, DF_REF_REGNO (*def_rec))
+ || bitmap_bit_p (au, DF_REF_REGNO (*def_rec)))
+ {
+ needed = true;
+ mark_insn (insn, true);
+ break;
+ }
+ }
/* No matter if the instruction is needed or not, we remove
any regno in the defs from the live set. */
@@ -923,6 +962,7 @@ dce_process_block (basic_block bb, bool redo_out, bitmap au)
df_simulate_uses (insn, local_live);
}
+ dead_debug_finish (&debug, NULL);
df_simulate_finalize_backwards (bb, local_live);
block_changed = !bitmap_equal_p (local_live, DF_LR_IN (bb));