On Fri, Aug 21, 2015 at 12:44 PM, Uday P. Khedker <u...@cse.iitb.ac.in> wrote: > > > 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).
Did you tell GCC this is a 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. I see. Richard. > Uday. > > > >