[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