This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Compilation of object creation in C++

On 2015-08-21 16:16, Richard Biener wrote:
On Fri, Aug 21, 2015 at 12:44 PM, Uday P. Khedker <> wrote:

On 08/19/2015 04:44 PM, Andrew Pinski wrote:

On Wed, Aug 19, 2015 at 7:16 PM, Uday P. Khedker <>

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 <>

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
looking at flow sensitive analysis.

It also performs flow-sensitive analysis, exactly like you suggest by
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

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
               virtual void f() {cout << "\tA:f" << endl;}

class B : public A
{     public:
              void f() {cout << "\tB:f" << endl;}

class C : public B
              void f() {cout<< "\tC:f" << endl;}

void fun1 (A *a, int i)
    cout << "\nhi in fun1" << i << endl ;

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

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?

Yes, we did specify the -fwhole-program option with optimization level O3.
Is there any other option we should try?

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.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]