This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[dataflow]: PATCH committed to fix another libcall issue in dce.
- From: Kenneth Zadeck <zadeck at naturalbridge dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, Andrew Pinski <pinskia at physics dot uc dot edu>, "Berlin, Daniel" <dberlin at dberlin dot org>, Seongbae Park <seongbae dot park at gmail dot com>, "Zadeck, Kenneth" <zadeck at naturalbridge dot com>
- Date: Mon, 25 Dec 2006 15:37:09 -0500
- Subject: [dataflow]: PATCH committed to fix another libcall issue in dce.
This time for sure!!!!
This patch allows dce to properly delete noop moves from the inside of
libcalls.
This appears to be the last regression for the dataflow branch on the
sony ps3, but pinskia cannot do a full bootstrap and regtest until he
returns from holiday.
This does not add any other regressions to x86-64 or ppc. Until the
next merge, we cannot test on ia-64.
2006-12-25 Kenneth Zadeck <zadeck@naturalbridge.com>
* dce.c (delete_corresponding_reg_eq_notes): Added comment.
(delete_unmarked_insns): Added code to delete noop moves
inside of libcalls. Changed to used delete_insn_and_edges.
Index: dce.c
===================================================================
--- dce.c (revision 120165)
+++ dce.c (working copy)
@@ -204,6 +204,10 @@ delete_corresponding_reg_eq_notes (rtx i
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);
}
@@ -223,10 +227,34 @@ delete_unmarked_insns (void)
something_changed = false;
FOR_EACH_BB (bb)
FOR_BB_INSNS_SAFE (bb, insn, next)
- if (INSN_P (insn)
- && ((!marked_insn_p (insn)) || noop_move_p (insn))
- && dbg_cnt (new_dce))
+ if (INSN_P (insn))
{
+ if (noop_move_p (insn))
+ {
+ /* Note that this code does not handle the case where
+ the last insn of libcall is deleted. As it turns out
+ this case is excluded in the call to noop_move_p. */
+ rtx note = find_reg_note (insn, REG_LIBCALL, NULL_RTX);
+ if (note && (XEXP (note, 0) != insn))
+ {
+ rtx new_libcall_insn = next_real_insn (insn);
+ rtx retval_note = find_reg_note (XEXP (note, 0),
+ REG_RETVAL, NULL_RTX);
+ REG_NOTES (new_libcall_insn)
+ = gen_rtx_INSN_LIST (REG_LIBCALL, XEXP (note, 0),
+ REG_NOTES (new_libcall_insn));
+ XEXP (retval_note, 0) = new_libcall_insn;
+ }
+ }
+ else if (marked_insn_p (insn))
+ continue;
+
+ /* WARNING, this debugging can itself cause problems if the
+ edge of the counter causes part of a libcall to be
+ deleted but not all of it. */
+ if (!dbg_cnt (new_dce))
+ continue;
+
if (dump_file)
fprintf (dump_file, "DCE: Deleting insn %d\n", INSN_UID (insn));
@@ -235,8 +263,7 @@ delete_unmarked_insns (void)
to prevent dangling REG_EQUAL. */
delete_corresponding_reg_eq_notes (insn);
- /* XXX: This may need to be changed to delete_insn_and_edges */
- delete_insn (insn);
+ delete_insn_and_edges (insn);
something_changed = true;
}
}