This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Compilation of object creation in C++
- From: "Uday P. Khedker" <uday at cse dot iitb dot ac dot in>
- To: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Cc: Richard Biener <richard dot guenther at gmail dot com>, Andrew Pinski <pinskia at gmail dot com>, RATHI SWATI KAILASH <swatirathi at cse dot iitb dot ac dot in>
- Date: Fri, 21 Aug 2015 16:14:09 +0530
- Subject: Re: Compilation of object creation in C++
- Authentication-results: sourceware.org; auth=none
- References: <55D46192 dot 5090509 at cse dot iitb dot ac dot in> <55D4658B dot 4090405 at cse dot iitb dot ac dot in> <CA+=Sn1nhAKQcOzH5Y-2xMUEVzoRwhtNOMWc-Ar0VwS_+mdCcyg at mail dot gmail dot com> <55D47239 dot 7090804 at cse dot iitb dot ac dot in> <CAFiYyc0ihK-640MNBz6xTkKP9Tbbq=T2La9-8sW3MNOVb3Aq0Q at mail dot gmail dot com>
On 08/19/2015 04:44 PM, Andrew Pinski wrote:
On Wed, Aug 19, 2015 at 7:16 PM, Uday P. Khedker <uday@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 <uday@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).
The situation we are looking at involves interprocedural propagation with complex calls such as a->f->g->h(). We
plan to use a demand driven flow, context, and field sensitive sensitive points-to analysis which involves just about enough
computation required to resolves such calls.
Uday.