diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2010-11-16 22:13:52 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2010-11-16 22:13:52 +0000 |
commit | 885c9b5d3a53c531fca622b4a3b0ef03df92daed (patch) | |
tree | d3ce62c6785fad984002bec2dbfc693e299f8950 /gcc/dce.c | |
parent | 2b12962772d3b0e85d860609f32bfb28515d5ba9 (diff) | |
download | gcc-885c9b5d3a53c531fca622b4a3b0ef03df92daed.zip gcc-885c9b5d3a53c531fca622b4a3b0ef03df92daed.tar.gz gcc-885c9b5d3a53c531fca622b4a3b0ef03df92daed.tar.bz2 |
re PR rtl-optimization/46315 (-O2 -fno-strict-overflow causes wrong code generation)
PR rtl-optimization/46315
* rtl.h (remove_reg_equal_equiv_notes_for_regno): Declare.
* rtlanal.c (remove_reg_equal_equiv_notes_for_regno): New function
extracted from...
* dce.c (delete_corresponding_reg_eq_notes): ...here. Rename into...
(remove_reg_equal_equiv_notes_for_defs): ...this.
(delete_unmarked_insns): Adjust to above renaming.
* ifcvt.c (dead_or_predicable): Remove REG_EQUAL and REG_EQUIV notes
referring to registers set in the insns being moved, if any.
* df-core.c (df_ref_dump): New function extracted from...
(df_refs_chain_dump): ...here. Call it.
(df_regs_chain_dump): Likewise.
* df-problems.c (df_chain_dump): Print 'e' for uses in notes.
* df-scan.c (df_scan_start_dump): Likewise. Fix long line.
From-SVN: r166827
Diffstat (limited to 'gcc/dce.c')
-rw-r--r-- | gcc/dce.c | 34 |
1 files changed, 7 insertions, 27 deletions
@@ -466,36 +466,16 @@ find_call_stack_args (rtx call_insn, bool do_mark, bool fast, } -/* Delete all REG_EQUAL notes of the registers INSN writes, to prevent - bad dangling REG_EQUAL notes. */ +/* Remove all REG_EQUAL and REG_EQUIV notes referring to the registers INSN + writes to. */ static void -delete_corresponding_reg_eq_notes (rtx insn) +remove_reg_equal_equiv_notes_for_defs (rtx insn) { df_ref *def_rec; + for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) - { - df_ref def = *def_rec; - unsigned int regno = DF_REF_REGNO (def); - /* This loop is a little tricky. We cannot just go down the - chain because it is being modified by the actions in the - loop. So we just get the head. We plan to drain the list - anyway. */ - while (DF_REG_EQ_USE_CHAIN (regno)) - { - df_ref eq_use = DF_REG_EQ_USE_CHAIN (regno); - rtx noted_insn = DF_REF_INSN (eq_use); - rtx note = find_reg_note (noted_insn, REG_EQUAL, NULL_RTX); - if (!note) - note = find_reg_note (noted_insn, REG_EQUIV, NULL_RTX); - - /* This assert is generally triggered when someone deletes a - REG_EQUAL or REG_EQUIV note by hacking the list manually - rather than calling remove_note. */ - gcc_assert (note); - remove_note (noted_insn, note); - } - } + remove_reg_equal_equiv_notes_for_regno (DF_REF_REGNO (*def_rec)); } @@ -544,9 +524,9 @@ delete_unmarked_insns (void) if (dump_file) fprintf (dump_file, "DCE: Deleting insn %d\n", INSN_UID (insn)); - /* Before we delete the insn we have to delete REG_EQUAL notes + /* Before we delete the insn we have to remove the REG_EQUAL notes for the destination regs in order to avoid dangling notes. */ - delete_corresponding_reg_eq_notes (insn); + remove_reg_equal_equiv_notes_for_defs (insn); /* If a pure or const call is deleted, this may make the cfg have unreachable blocks. We rememeber this and call |