Hi,
On Fri, 25 Sep 2009, Richard Guenther wrote:
which is one memory load better and possibly one store better.
Am I right in saying that this option is only useful if conditional
execution (predication or select) is available (because the
conditional is made explicit in the phi) ?
Well, yes. The pass tries to uncover conditional store operations,
To be exact, it tries to _avoid_ conditional store operations in favor of
conditional loads or conditional moves. That's why the pass is only
active by default with HAVE_conditional_move (see toplev.c).
so if ifcvt does not have any means to create them (which IIRC is more
than just in case of HAVE_conditional_execution),
This OTOH is true. There's also HAVE_conditional_move, and simple
conditional moves can also be generated via bit magic without any special
target support. So it's not that good a condition on which to
enable/disable the pass.
So either you want to switch off the pass for your target only, or try to
fiddle with the pass a bit to avoid transforming in your situation.
Your testcase was something like:
*p = a
if (bar())
*p = b
transformed into
*p = a
temp = bar() ? b : *p
*p = temp
The problem here is the call to bar(). That in addition to the fact that
the pointer was an argument means that 'a' can't be forwarded into the
read of *p in the condition (because bar() might have changed the
contents). If the condition weren't a call (or at least only a const/pure
call) later passes would have transformed the whole thing into:
*p = a;
temp = condition ? b : a;
*p = temp;
The first store would have been dead, and hence you had ended up with
*p = condition ? b : a;
which I would think is also more optimal on the SH than the initial code.
So with the right amount of magic you might avoid the transformation if
it can be easily detected that the read probably can not be optimized
later.
Ciao,
Michael.