On 08/19/2015 04:44 PM, Andrew Pinski wrote:
On Wed, Aug 19, 2015 at 7:16 PM, Uday P. Khedker
<u...@cse.iitb.ac.in>
wrote:
Why is this different? Why is __comp_ctor not invoked in each
case?
This looks like the function has been inlined as it is short.
Thanks, this is a useful lead. Setting -fno-inline seems to do the
trick and
now the behaviour is same. C intermediate language
On 08/19/2015 06:00 PM, Richard Biener wrote:
On Wed, Aug 19, 2015 at 2:10 PM, Uday P. Khedker
<u...@cse.iitb.ac.in>
wrote:
Andrew Pinski wrote on Wednesday 19 August 2015 04:44 PM:
Most of this is already in GCC 5 and above. Including the IPA
pass.
Have you looked into that pass yet?
From what I have read, it involves flow insensitive analysis
whereas we
are
looking at flow sensitive analysis.
It also performs flow-sensitive analysis, exactly like you suggest
by
looking
for constructor calls or patterns that involve setting the vtable
pointer
exposed through inlining.
When I said flow sensitive, I have interprocedural version in mind.
When I
looked up ipa-devirt.c,
there seems to be a traversal using FOR_EACH_DEFINED_FUNCTION (n),
but
nothing in it
indicates, an interprocedural transfer of information. I also looked
up Jan
Hubicka's blogs
(http://hubicka.blogspot.ca/2014/01/devirtualization-in-c-part-2-low-level.html)
and if I have understood it correctly, the analysis done by constant
propagation and global
value numbering is at the intraprocedural level (haven't looked up
these
passes though).
Here's a rather trivial example where gcc-5.1 misses
devirtualization
class A
{
public:
virtual void f() {cout << "\tA:f" << endl;}
};
class B : public A
{ public:
void f() {cout << "\tB:f" << endl;}
};
class C : public B
{
public:
void f() {cout<< "\tC:f" << endl;}
};
void fun1 (A *a, int i)
{
cout << "\nhi in fun1" << i << endl ;
a->f();
}
int main()
{
A *a1;
a1 = new A;
fun1 (a1, 10);
A *a2;
a2 = new A;
fun1 (a2, 5);
}
Assuming that there is no other translation unit and this is the
complete
program, the call a->f() is always for class
A but the dump in .058i.devirt says
Procesing function void fun1(A*, int)/232
Targets of polymorphic call of type 28:struct A token 0
Outer type (dynamic):struct A (or a derived type) offset 0
This is partial list; extra targets may be defined in other
units.
(derived types included)
virtual void A::f()/229 virtual void B::f()/230 virtual void
C::f()/231
suggesting that A, B, and C are possible classes.
Even a simple field and context insensitive interprocedural analysis
would
figure out that only one call is
possible (assuming this is the complete program).