Hi,
On Thu, 5 Jul 2007, Richard Guenther wrote:
> > What makes "(i + 1) * 4" the canonical form of "(i * 4) + 4" compared to
> > other expressions like "(i * 4) + 8"?
>
> It's an arbitrary decision by fold. For (i + 2) * 4 the canonical form
> is (i * 4) + 8. For (i * j) + j the canonical form is (i + 1) * j,
> for (i * j) + 2 * j it is (i + 2) * j. Now we can easily make constants
> special here.
What makes this arbitrary decision a good decision considering that it
lacks any context?
> > > The real fix is in the
> > > value numberer that should value number both kinds the same.
> >
> > Sorry, I have no idea what this means.
>
> This means that without context, neither (i + 1) * 4 nor (i * 4) + 4
> is better or cheaper. With context that allows simplification this
> simplification should be possible regardless of what form the
> expression is in.
Maybe it should, but that doesn't make the job of other optimizers simpler
if they have to deal with such a mixture of expressions.
For example how should one find all the common subexpression (i * 4) this
way?
> Remember that fold only does the transformation
> if it sees the full expression, so writing
>
> tmp1 = i + 1;
> tmp1 = tmp1 * 4;
> tmp2 = i * 4;
> tmp2 = tmp2 + 4;
> if (tmp1 == tmp2)
> ...
>
> should be optimized as well, but fold does nothing about that.
Exactly and that's why I think this transformation is done far too early.
It doesn't make sense that these two examples produce different code:
int foo1(int x)
{
return (x * 4) + 4;
}
int foo2(int x)
{
int y = x * 4;
return y + 4;
}
bye, Roman