This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] Handle equivalent loop invariants as one in loop-invariant.c
- From: Ian Lance Taylor <ian at airs dot com>
- To: Steven Bosscher <stevenb at suse dot de>
- Cc: gcc-patches at gcc dot gnu dot org, Zdenek Dvorak <rakdver at atrey dot karlin dot mff dot cuni dot cz>, Daniel Berlin <dberlin at dberlin dot org>
- Date: 20 Dec 2005 22:36:13 -0800
- Subject: Re: [patch] Handle equivalent loop invariants as one in loop-invariant.c
- References: <20051124153449.GA7201@atrey.karlin.mff.cuni.cz> <200512121942.29800.stevenb@suse.de> <m33bky15rn.fsf@gossamer.airs.com> <200512181924.36706.stevenb@suse.de>
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