This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] Handle equivalent loop invariants as one in loop-invariant.c


Steven Bosscher <stevenb@suse.de> writes:

> +/* Finds the reference corresponding to the use of REG in INSN.
> +   DF is the dataflow object.  */
> +
> +struct ref *
> +df_find_use (struct df *df, rtx insn, rtx reg)
> +{
> +  struct df_link *uses;
> +
> +  for (uses = DF_INSN_USES (df, insn); uses; uses = uses->next)
> +    {
> +      rtx areg = DF_REF_REG (uses->ref);
> +      if (GET_CODE (areg) == SUBREG)
> +	areg = SUBREG_REG (areg);
> +
> +      if (rtx_equal_p (areg, reg))
> +	return uses->ref;
> +    }
> +
> +  return NULL;
> +}
> +

This seems more or less parallel to df_find_def and df_reg_used, but
those functions don't check for a SUBREG.  It seems to me that the
functions should be entirely parallel; if it right to check for a
SUBREG here, then presumably it is right to check for one in
df_find_def.


> +/* Compares invariant expressions E1 and E2 in modes MODE1 and MODE2 used in
> +   insns INSN1 and INSN2.  */
> +
> +static bool
> +invariant_expr_equal_p (rtx insn1, rtx e1, enum machine_mode mode1,
> +			rtx insn2, rtx e2, enum machine_mode mode2)
> +{
> +  enum rtx_code code = GET_CODE (e1);
> +  int i, j;
> +  const char *fmt;
> +  struct ref *use1, *use2;
> +  struct invariant *inv1 = NULL, *inv2 = NULL;
> +  rtx sub1, sub2;
> +  enum machine_mode submode1, submode2;
> +
> +  gcc_assert (GET_MODE (e1) == VOIDmode || GET_MODE (e1) == mode1);
> +  gcc_assert (GET_MODE (e2) == VOIDmode || GET_MODE (e2) == mode2);
> +
> +  if (code != GET_CODE (e2) || mode1 != mode2)
> +    return false;
> +
> +  switch (code)
> +    {
> +    case CONST_INT:
> +    case CONST_DOUBLE:
> +    case SYMBOL_REF:
> +    case CONST:
> +    case LABEL_REF:
> +      return rtx_equal_p (e1, e2);
> +
> +    case REG:
> +      use1 = df_find_use (df, insn1, e1);
> +      use2 = df_find_use (df, insn2, e2);
> +      if (use1)
> +	inv1 = invariant_for_use (use1);
> +      if (use2)
> +	inv2 = invariant_for_use (use2);
> +
> +      if (!inv1 && !inv2)
> +	return rtx_equal_p (e1, e2);
> +
> +      if (!inv1 || !inv2)
> +	return false;
> +
> +      gcc_assert (inv1->eqto != ~0u);
> +      gcc_assert (inv2->eqto != ~0u);
> +      return inv1->eqto == inv2->eqto;
> +
> +    default:
> +      break;
> +    }
> +
> +  fmt = GET_RTX_FORMAT (code);
> +  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
> +    {
> +      if (fmt[i] == 'e')
> +	{
> +	  sub1 = XEXP (e1, i);
> +	  sub2 = XEXP (e2, i);
> +	  submode1 = GET_MODE (sub1);
> +	  if (submode1 == VOIDmode)
> +	    submode1 = mode1;
> +	  submode2 = GET_MODE (sub2);
> +	  if (submode2 == VOIDmode)
> +	    submode2 = mode2;
> +
> +	  if (!invariant_expr_equal_p (insn1, sub1, submode1,
> +				       insn2, sub2, submode2))
> +	    return false;
> +	}
> +
> +      else if (fmt[i] == 'E')
> +	{
> +	  if (XVECLEN (e1, i) != XVECLEN (e2, i))
> +	    return false;
> +
> +	  for (j = 0; j < XVECLEN (e1, i); j++)
> +	    {
> +	      sub1 = XVECEXP (e1, i, j);
> +	      sub2 = XVECEXP (e2, i, j);
> +	      submode1 = GET_MODE (sub1);
> +	      if (submode1 == VOIDmode)
> +		submode1 = mode1;
> +	      submode2 = GET_MODE (sub2);
> +	      if (submode2 == VOIDmode)
> +		submode2 = mode2;
> +
> +	      if (!invariant_expr_equal_p (insn1, sub1, submode1,
> +					   insn2, sub2, submode2))
> +		return false;
> +	    }
> +	}
> +    }
> +
> +  return true;
> +}


I don't see why you need to do the submode stuff here.  What if you
just do
    if (code != GET_CODE (e2)
        || (mode1 != mode2
            && mode1 != VOIDmode
            && mode2 != VOIDmode))
at the start?  It doesn't seem like you are using the mode for
anything substantial.


Otherwise the patch looks OK.

Ian


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]