From: Alexandre Oliva Date: Mon, 6 Jun 2011 13:25:06 +0000 (+0000) Subject: dce.c (reset_unmarked_insns_debug_uses): New. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a7a110bb82c953b94043a98f1123cb6aaeff2bac;p=gcc.git dce.c (reset_unmarked_insns_debug_uses): New. * 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. From-SVN: r174699 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 59bf1fc2c99..c45fe7211b3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2011-06-06 Alexandre Oliva + + * 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. + 2011-06-06 Alexandre Oliva * tree-pretty-print.c (dump_function_header): Add flags. diff --git a/gcc/dce.c b/gcc/dce.c index ec54c6681b8..93464fedeed 100644 --- a/gcc/dce.c +++ b/gcc/dce.c @@ -493,6 +493,43 @@ remove_reg_equal_equiv_notes_for_defs (rtx insn) 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); diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 60835c75528..dcde8920d7e 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -1333,6 +1333,11 @@ subst_stack_regs_in_debug_insn (rtx *loc, void *data) 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, void *data) 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); } }