diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2012-04-13 15:56:21 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2012-04-13 15:56:21 +0000 |
commit | 1adbb3614d87c487eb0b3c3eebbe1c6bb6e7438f (patch) | |
tree | 283216c0c3a9019c8feb931e55ba7d5c90f81f3e /gcc/dce.c | |
parent | 6ae1d471b16228d47bbcfbe3b2b90c323a0af1ba (diff) | |
download | gcc-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.c | 58 |
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)); |