On Mon, Jan 7, 2013 at 8:45 PM, Jeff Law <[email protected]> wrote:
> Before diving into the patch I think we should figure out why we see such
> different effects of eliminating these paths from the CFG. Your assertion
> is eliminating them will result in more false positives and less
> optimization while my assertion is the opposite.
Warnings:
$ cat q.c
#if 0
#define UNREACHABLE() __builtin_unreachable()
#else
#define UNREACHABLE() break
#endif
typedef enum fruits { banana = 0, apple = 1, pear = 2, orange = 3 } fruit;
extern void price_fruit_of_the_day (int);
void
discount_of_the_day (fruit f)
{
int p, c = (int) f;
switch (f)
{
case banana:
UNREACHABLE ();
case apple:
p = 3 * c + 4;
break;
case pear:
case orange:
p = 7;
break;
}
price_fruit_of_the_day (p);
}
$ # Compiled with UNREACHABLE defined as break:
$ ./cc1 -quiet -W -Wall -Wextra q.c -fdump-tree-all -O1
q.c: In function 'discount_of_the_day':
q.c:28:26: warning: 'p' may be used uninitialized in this function
[-Wmaybe-uninitialized]
price_fruit_of_the_day (p);
^
$ # Compiled with UNREACHABLE defined as builtin_unreachable:
$ ./cc1 -quiet -W -Wall -Wextra q.c -fdump-tree-all -O1
$
For optimizations it's a bit more difficult. The situations I'm
looking at, are all sinking related, and I suspect that most missed
optimizations will be of this form:
int foo (int b, int c, int d)
{
int res, r = 0;
res = 5 * d + b;
if (d)
__builtin_unreachable ();
if (c)
r = res;
return r;
}
The "res =" statement can be sunk into the conditional arm of "if(c)"
and tree-ssa-sink.c is able to do so. But secondary effects are missed
(and test cases for this are hard to reduce to mailing list acceptable
size ;-) because tree-ssa-sink walks the post-dominator tree and, with
the right amount of bad luck, it visits the "res=" statement _before_
the part of the (forward-)dominator tree below "if(d)" because the
basic block containing "res=" has EXIT as its immediate
post-dominator, because that's where __builtin_unreachable() leads to.
The "optimistic" post-dominator of "res=" is the "if(c)" block, of
course, because the builtin_unreachable is a kind-of assert, not
something that can really ever happen.
I already showed how the control dependence graph looks Wrong with
__builtin_unreachable calls in place. Any transformation using the CDG
will also be less effective because of this.
Ciao!
Steven