This is the mail archive of the
mailing list for the GCC project.
Re: [Patch] rtx_cost of SUBREG
- From: Roger Sayle <roger at eyesopen dot com>
- To: Eric Botcazou <ebotcazou at libertysurf dot fr>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sat, 22 Jan 2005 13:14:16 -0700 (MST)
- Subject: Re: [Patch] rtx_cost of SUBREG
[Cc'd to gcc-patches to avoid repeating this again later :>]
On Sat, 22 Jan 2005, Eric Botcazou wrote:
> Thanks for the quick resolution. I can only say that I didn't think of
> checking the cost of the modified expression at all. I'll start another
> round of testing tomorrow morning and get back to you when the fastest
> machines are finished.
No problem. If you're interested in the "gory" details, the failure
goes like this.
Given an expression like "ior(x,and(y,z))", this optimization first
attempts to build the intermediate "and(ior(x,y),ior(x,z))" and if
that fails to simplify it relies on "apply_distributive_law" to undo
the problem, by spotting the common first operands, i.e.
"and(ior(x,y),ior(x,z))" -> "ior(x,and(y,z)" (the original).
In this case, the problem is that one of the operands (Y or Z above)
is itself an IOR, so instead we get...
But the problem is that even if we don't simplify ior(p,q,r)", we may
end up reassociating its terms such that instead of ior(p,ior(q,r)" we
end up with something like ior(ior(p,q),r) where apply_distributive_law
is no longer able to recognize the shared "p".
There were two possible resolutions, the first one I considered was
to disallow this transformation if either operand of the AND was an
if (GET_CODE (op0) == AND
&& GET_CODE (XEXP (op0, 0)) != IOR
&& GET_CODE (XEXP (op0, 1)) != IOR)
the issue here is that its these inner operands being IOR of a constant
that are typically the biggest winner of this transformation, allowing
the outer IOR const_int to be combined with the inner IOR const_int.
The alternative/combinatorics of searching for a common term in
apply_distributive_law also seemed computationally too expensive, so
my final (proposed) solution is to test whether the result of this
transformation is cheaper than the original, which resolves the failure
and should produce better code still.
Finally, the reason the SUBREG change triggered this latent problem is
another transformation in combine.c:
y = gen_binary (AND, GET_MODE (x), XEXP (x, 0), GEN_INT (cval));
if (rtx_cost (y, SET) < rtx_cost (x, SET))
x = y;
where gen_binary is able to optimize AND by a constant into a SUBREG.
Previously the COSTS_N_INSNS(1) meant that the SUBREG was as expensive
as the AND of an immediate constant. Now that SUBREGs are cheaper, we
can eliminate the explicit operation.
I hope that explains things.
> > I'd also be interested if it fixes some or all of the other sparc
> > regressions that you're seeing.
> I'll tell you. But, assuming it doesn't, I'll debug them myself.
If there's anything I can do to help... When a patch I've approved
breaks something, I feel some (small) responsibility for looking into
it, especially when it's RTL simplification related.