[PATCH] Don't reset debug stmts in delete_trivially_dead_insns unnecessarily
Eric Botcazou
ebotcazou@adacore.com
Wed Oct 13 16:04:00 GMT 2010
> 2010-10-05 Jakub Jelinek <jakub@redhat.com>
>
> * cse.c (is_dead_reg): Change into inline function that is not
> called through for_each_rtx.
> (set_live_p): Adjust caller.
> (insn_live_p): Don't reset DEBUG_INSNs here.
> (struct dead_debug_insn_data): New data.
> (count_stores, is_dead_debug_insn, replace_dead_reg): New functions.
> (delete_trivially_dead_insns): If there is just one setter for the
> dead reg that is referenced by some DEBUG_INSNs, create a DEBUG_EXPR
> and add DEBUG_INSN for it right before the removed setter and
> use the DEBUG_EXPR instead of the dead pseudo.
OK modulo the following nits:
> /* Return true if a register is dead. Can be used in for_each_rtx. */
>
> -static int
> -is_dead_reg (rtx *loc, void *data)
> +static inline int
> +is_dead_reg (rtx x, int *counts)
Outdated head comment, and it would be nice to mention X in it now.
> +/* Count the number of stores into pseudo. */
> +
> +static void
> +count_stores (rtx x, const_rtx set ATTRIBUTE_UNUSED, void *data)
> +{
> + int *counts = (int *) data;
> + if (REG_P (x) && REGNO (x) >= FIRST_PSEUDO_REGISTER)
> + counts[REGNO (x)]++;
> +}
Mention that it's a callback for note_stores (or document the parameters).
> +/* Return if a DEBUG_INSN needs to be reset because some dead
> + pseudo doesn't have a replacement. */
> +
> +static int
> +is_dead_debug_insn (rtx *loc, void *data)
> +{
> + rtx x = *loc;
> + struct dead_debug_insn_data *ddid = (struct dead_debug_insn_data *)
> data; +
> + if (is_dead_reg (x, ddid->counts))
> + {
> + if (ddid->replacements && ddid->replacements[REGNO (x)] != NULL_RTX)
> + ddid->seen_repl = true;
> + else
> + return 1;
> + }
> + return 0;
> +}
Mention that it's a callback for for_each_rtx.
> +/* Replace a dead pseudo in a DEBUG_INSN with replacement DEBUG_EXPR. */
> +
> +static rtx
> +replace_dead_reg (rtx x, const_rtx old_rtx ATTRIBUTE_UNUSED, void *data)
> +{
> + rtx *replacements = (rtx *) data;
> +
> + if (REG_P (x)
> + && REGNO (x) >= FIRST_PSEUDO_REGISTER
> + && replacements[REGNO (x)] != NULL_RTX)
> + {
> + if (GET_MODE (x) == GET_MODE (replacements[REGNO (x)]))
> + return replacements[REGNO (x)];
> + return lowpart_subreg (GET_MODE (x), replacements[REGNO (x)],
> + GET_MODE (replacements[REGNO (x)]));
> + }
> + return NULL_RTX;
> +}
Mention that it's a callback for simplify_replace_fn_rtx.
> + if (MAY_HAVE_DEBUG_INSNS)
> + {
> + counts = XCNEWVEC (int, nreg * 3);
> + for (insn = insns; insn; insn = NEXT_INSN (insn))
> + if (DEBUG_INSN_P (insn))
> + count_reg_usage (INSN_VAR_LOCATION_LOC (insn), counts + nreg,
> + NULL_RTX, 1);
> + else if (INSN_P (insn))
> + {
> + count_reg_usage (insn, counts, NULL_RTX, 1);
> + note_stores (PATTERN (insn), count_stores, counts + nreg * 2);
> + }
> + }
> + else
> + {
> + counts = XCNEWVEC (int, nreg);
> + for (insn = insns; insn; insn = NEXT_INSN (insn))
> + if (INSN_P (insn))
> + count_reg_usage (insn, counts, NULL_RTX, 1);
> + }
Add a comment about what COUNTS will contain at the end of the computation.
> + if (MAY_HAVE_DEBUG_INSNS
> + && (set = single_set (insn)) != NULL_RTX
> + && is_dead_reg (SET_DEST (set), counts)
> + /* Used at least once in some DEBUG_INSN. */
> + && counts[REGNO (SET_DEST (set)) + nreg] > 0
> + /* And set exactly once. */
> + && counts[REGNO (SET_DEST (set)) + nreg * 2] == 1
> + && !side_effects_p (SET_SRC (set))
> + && asm_noperands (PATTERN (insn)) < 0)
> + {
> + rtx dval, bind;
> +
> + /* Create DEBUG_EXPR (and DEBUG_EXPR_DECL). */
> + dval = make_debug_expr_from_rtl (SET_DEST (set));
> +
> + /* Emit a debug bind insn before the insn in which
> + reg dies. */
> + bind = gen_rtx_VAR_LOCATION (GET_MODE (SET_DEST (set)),
> + DEBUG_EXPR_TREE_DECL (dval),
> + SET_SRC (set),
> + VAR_INIT_STATUS_INITIALIZED);
> + count_reg_usage (bind, counts + nreg, NULL_RTX, 1);
> +
> + bind = emit_debug_insn_before (bind, insn);
> + df_insn_rescan (bind);
> +
> + if (replacements == NULL)
> + replacements = XCNEWVEC (rtx, nreg);
> + replacements[REGNO (SET_DEST (set))] = dval;
> + }
> +
> + count_reg_usage (insn, counts, NULL_RTX, -1);
> + ndead++;
> + }
> delete_insn_and_edges (insn);
> - ndead++;
> }
Add a comment about the high-level purpose of the code (e.g. the ChangeLog).
--
Eric Botcazou
More information about the Gcc-patches
mailing list