On Jun 6, 2011, Eric Botcazou <ebotca...@adacore.com> wrote: >> Indeed, sorry, I misread it.
> Mind installing these bits separately? Nope. Testing it separately now. > My understanding is that they are > independent correctness fixes. Yeah, I guess they are. They won't make debug info any worse, although they may remove incorrect debug info, and they won't preserve debug info that we currently discard, which the other part of the patch retains. Here's what I'm going to check in if regstrapping succeeds.
for gcc/ChangeLog from Alexandre Oliva <aol...@redhat.com> * dce.c (reset_unmarked_insns_debug_uses): New. (delete_unmarked_insns): Skip debug insns. (prescan_insns_for_dce): Likewise. (rest_of_handle_ud_dce): Reset debug uses of removed sets. * reg-stack.c (subst_stack_regs_in_debug_insn): Signal when no active reg can be found. (subst_all_stack_regs_in_debug_insn): New. Reset debug insn then. (convert_regs_1): Use it. Index: gcc/dce.c =================================================================== --- gcc/dce.c.orig 2011-05-26 05:03:08.552989108 -0300 +++ gcc/dce.c 2011-05-27 03:09:07.711388764 -0300 @@ -493,6 +493,43 @@ remove_reg_equal_equiv_notes_for_defs (r remove_reg_equal_equiv_notes_for_regno (DF_REF_REGNO (*def_rec)); } +/* Scan all BBs for debug insns and reset those that reference values + defined in unmarked insns. */ + +static void +reset_unmarked_insns_debug_uses (void) +{ + basic_block bb; + rtx insn, next; + + FOR_EACH_BB_REVERSE (bb) + FOR_BB_INSNS_REVERSE_SAFE (bb, insn, next) + if (DEBUG_INSN_P (insn)) + { + df_ref *use_rec; + + for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++) + { + df_ref use = *use_rec; + struct df_link *defs; + for (defs = DF_REF_CHAIN (use); defs; defs = defs->next) + { + rtx insn; + if (DF_REF_IS_ARTIFICIAL (defs->ref)) + continue; + insn = DF_REF_INSN (defs->ref); + if (!marked_insn_p (insn)) + break; + } + if (!defs) + continue; + /* ??? FIXME could we propagate the values assigned to + each of the DEFs? */ + INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC (); + df_insn_rescan_debug_internal (insn); + } + } +} /* Delete every instruction that hasn't been marked. */ @@ -505,7 +542,7 @@ delete_unmarked_insns (void) FOR_EACH_BB_REVERSE (bb) FOR_BB_INSNS_REVERSE_SAFE (bb, insn, next) - if (INSN_P (insn)) + if (NONDEBUG_INSN_P (insn)) { /* Always delete no-op moves. */ if (noop_move_p (insn)) @@ -579,7 +616,7 @@ prescan_insns_for_dce (bool fast) FOR_EACH_BB (bb) { FOR_BB_INSNS_REVERSE_SAFE (bb, insn, prev) - if (INSN_P (insn)) + if (NONDEBUG_INSN_P (insn)) { /* Don't mark argument stores now. They will be marked if needed when the associated CALL is marked. */ @@ -713,6 +750,9 @@ rest_of_handle_ud_dce (void) } VEC_free (rtx, heap, worklist); + if (MAY_HAVE_DEBUG_INSNS) + reset_unmarked_insns_debug_uses (); + /* Before any insns are deleted, we must remove the chains since they are not bidirectional. */ df_remove_problem (df_chain); Index: gcc/reg-stack.c =================================================================== --- gcc/reg-stack.c.orig 2011-05-26 05:03:08.554989112 -0300 +++ gcc/reg-stack.c 2011-05-27 03:11:23.756589358 -0300 @@ -1333,6 +1333,11 @@ subst_stack_regs_in_debug_insn (rtx *loc return 0; hard_regno = get_hard_regnum (regstack, *loc); + + /* If we can't find an active register, reset this debug insn. */ + if (hard_regno == -1) + return 1; + gcc_assert (hard_regno >= FIRST_STACK_REG); replace_reg (loc, hard_regno); @@ -1340,6 +1345,23 @@ subst_stack_regs_in_debug_insn (rtx *loc return -1; } +/* Substitute hardware stack regs in debug insn INSN, using stack + layout REGSTACK. If we can't find a hardware stack reg for any of + the REGs in it, reset the debug insn. */ + +static void +subst_all_stack_regs_in_debug_insn (rtx insn, struct stack_def *regstack) +{ + int ret = for_each_rtx (&INSN_VAR_LOCATION_LOC (insn), + subst_stack_regs_in_debug_insn, + regstack); + + if (ret == 1) + INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC (); + else + gcc_checking_assert (ret == 0); +} + /* Substitute new registers in PAT, which is part of INSN. REGSTACK is the current register layout. Return whether a control flow insn was deleted in the process. */ @@ -2947,8 +2969,7 @@ convert_regs_1 (basic_block block) debug_insns_with_starting_stack++; else { - for_each_rtx (&PATTERN (insn), subst_stack_regs_in_debug_insn, - ®stack); + subst_all_stack_regs_in_debug_insn (insn, ®stack); /* Nothing must ever die at a debug insn. If something is referenced in it that becomes dead, it should have @@ -2986,8 +3007,7 @@ convert_regs_1 (basic_block block) continue; debug_insns_with_starting_stack--; - for_each_rtx (&PATTERN (insn), subst_stack_regs_in_debug_insn, - &bi->stack_in); + subst_all_stack_regs_in_debug_insn (insn, &bi->stack_in); } }
-- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist Red Hat Brazil Compiler Engineer