Hi! If DCE is not going to remove some insn, as it is needed, but the pseudo it sets is REG_DEAD before some debug insn which uses the pseudo, DCE + valtrack still insert a debug temporary before the insn with the value instead of after it with the pseudo it sets. This is undesirable if SET_SRC of the insn is something that is never useable in debug info (e.g. ASM_OPERANDS) or just wastes size of RTL by unnecessarily duplicating the rhs. This patch fixes it, when insn is needed and is not a control insn that must be at the end of a bb (we can't insert debug insns after those (unless it would be put at the beginning of all successor bbs)). The existing DEBUG_TEMP_AFTER_WITH_REG mode isn't usable for this, because it omits emitting a debug temporary if there is just a single trivial debug use (which is desirable for df-*.c uses but not for dce).
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2012-10-26 Jakub Jelinek <ja...@redhat.com> PR debug/54953 * valtrack.h (DEBUG_TEMP_AFTER_WITH_REG_FORCE): New. * valtrack.c (dead_debug_insert_temp): Use emit_debug_insn_after even for where == DEBUG_TEMP_AFTER_WITH_REG_FORCE. * dce.c (word_dce_process_block, dce_process_block): Pass DEBUG_TEMP_AFTER_WITH_REG_FORCE if insn is needed and therefore not going to be eliminated. --- gcc/valtrack.h.jj 2012-10-03 09:01:35.000000000 +0200 +++ gcc/valtrack.h 2012-10-26 10:21:31.655376061 +0200 @@ -130,7 +130,12 @@ enum debug_temp_where /* Bind a newly-created debug temporary to a REG for UREGNO, and insert the debug insn after INSN. REG is expected to be set at INSN. */ - DEBUG_TEMP_AFTER_WITH_REG = 1 + DEBUG_TEMP_AFTER_WITH_REG = 1, + /* Like DEBUG_TEMP_AFTER_WITH_REG, but force addition of a debug + temporary even if there is just a single debug use. This is used + on regs that are becoming REG_DEAD on INSN and so uses of the + reg later on are invalid. */ + DEBUG_TEMP_AFTER_WITH_REG_FORCE = 2 }; extern void dead_debug_global_init (struct dead_debug_global *, bitmap); --- gcc/valtrack.c.jj 2012-10-03 09:01:35.000000000 +0200 +++ gcc/valtrack.c 2012-10-26 10:22:38.646999016 +0200 @@ -648,7 +648,8 @@ dead_debug_insert_temp (struct dead_debu DEBUG_EXPR_TREE_DECL (dval), breg, VAR_INIT_STATUS_INITIALIZED); - if (where == DEBUG_TEMP_AFTER_WITH_REG) + if (where == DEBUG_TEMP_AFTER_WITH_REG + || where == DEBUG_TEMP_AFTER_WITH_REG_FORCE) bind = emit_debug_insn_after (bind, insn); else bind = emit_debug_insn_before (bind, insn); --- gcc/dce.c.jj 2012-10-19 11:01:03.000000000 +0200 +++ gcc/dce.c 2012-10-26 10:24:11.956465043 +0200 @@ -1,5 +1,5 @@ /* RTL dead code elimination. - Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This file is part of GCC. @@ -880,7 +880,10 @@ word_dce_process_block (basic_block bb, 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); + marked_insn_p (insn) + && !control_flow_insn_p (insn) + ? DEBUG_TEMP_AFTER_WITH_REG_FORCE + : DEBUG_TEMP_BEFORE_WITH_VALUE); } if (dump_file) @@ -981,7 +984,9 @@ dce_process_block (basic_block bb, bool if (debug.used && !bitmap_empty_p (debug.used)) 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); + needed && !control_flow_insn_p (insn) + ? DEBUG_TEMP_AFTER_WITH_REG_FORCE + : DEBUG_TEMP_BEFORE_WITH_VALUE); } dead_debug_local_finish (&debug, NULL); Jakub