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