On 12/17/13 11:00, Jan Hubicka wrote:
Here we should devirtualize since B's foo is dominating target and we correctly
do so.
We however do more, we trace the code into:
for (i = 0; i < 10000; i++)
{
if (i%7==0)
{
ap = new A();
ap->foo();
}
else
{
ap = new B();
ap->foo();
}
that should allow us to devirtualize completely. Instead of doing that we get
stuck
on stupid
<bb 5>:
ap_8 = operator new (16);
ap_8->i = 0;
ap_8->_vptr.A = &MEM[(void *)&_ZTV1A + 16B];
_19 = foo;
PROF_26 = [obj_type_ref] OBJ_TYPE_REF(_19;(struct A)ap_8->0);
if (PROF_26 == foo)
goto <bb 8>;
else
goto <bb 7>;
<bb 6>:
ap_13 = operator new (16);
MEM[(struct B *)ap_13].D.2237.i = 0;
MEM[(struct B *)ap_13].b = 0;
MEM[(struct B *)ap_13].D.2237._vptr.A = &MEM[(void *)&_ZTV1B + 16B];
_1 = foo;
PROF_30 = [obj_type_ref] OBJ_TYPE_REF(_1;(struct A)ap_13->0);
if (PROF_30 == foo)
goto <bb 8>;
else
goto <bb 7>;
There are several reasons for it
1) most of our passes do not expect OBJ_TYPE_REF in arguments and cowardly
consider it volatile
2) tracer happens too late and there is no VRP pass to cleanup afterwards
3) folding machinery expect OBJ_TYPE_REF to be only in argument.
After some consideration I decided to not update gimple_ic to remove
OBJ_TYPE_REF,
since this is a perfect example where OBJ_TYPE_REF may be useful after inlining:
in a more complex cases a type based devirt may kick in and save a day even
late after unrolling/tracing and other code specialization.
This is first trivial patch to make VRP behaving correctly.
Bootstrapped/regtested x86_64-linux OK?
* tree-vrp.c (extract_range_from_unary_expr_1): Add OBJ_TYPE_REF
s/Add/Handle. Please add the PR marker as well.
OK with that trivial nit.
jeff