> > > +/* If E does not lead to a thunk, simply redirect it to N.  Otherwise 
> > > create
> > > +   one or more equivalent thunks for N and redirect E to the first in the
> > > +   chain.  */
> > > +
> > > +void
> > > +redirect_edge_duplicating_thunks (struct cgraph_edge *e, struct 
> > > cgraph_node *n,
> > > +                           bitmap args_to_skip)
> > > +{
> > > +  cgraph_node *orig_to = cgraph_function_or_thunk_node (e->callee);
> > > +  if (orig_to->thunk.thunk_p)
> > > +    n = duplicate_thunk_for_node (orig_to, n, args_to_skip);
> > 
> > Is there anything that would pevent us from creating a new thunk for
> > each call?
> 
> No, given how late we have discovered it, it probably only happens
> very rarely.  Moreover, since you have plans to always inline only
> directly called thunks for the next release, which should be the
> ultimate solution, I did not think it was necessary or even
> appropriate at this stage.

A lot of code iterate over thunks/aliases and expect this to be cheap operation.
We thus need to be sure we won't create very many thunks or aliases of a given
function internally.

In order to trigger quadratic behaviour here, we only need a single function
call used very often in a big project, like mozilla, to create uncontrolled
numbers of thunks.  I would suggest to just walk existing thunks before
creating new looking if there is one mathcing our needs.  Same code is in
making local aliases. This change is pre-approved.
> 
> > 
> > Also I think you need to avoid this logic when THIS parameter is being 
> > optimized out
> > (i.e. it is part of skip_args)
> 
> You are of course right.  However, skipping the creation of a new
> thunk when we are also removing parameter this leads to verification
> errors again, so I had to also teach the verifier that this case is
> actually OK.  Moreover, although it seems that currently all
That is fine with me.
> non-this_adjusting thunks are expanded before IPA-CP runs, I made sure
> the skipping logic checked that flag.

Yes, we only keep the simple thunks in non-lowered form, but I do not
see how it makes difference for you.
> 
> Accidently, the two original testcases are removing parameter this so
> I added a new one, which also shows how current trunk miscompiles
> stuff.  Unfortunately, at the moment it relies on speculative edges
> and so when IPA-CP correctly redirects calls to a thunk, inlining
> gives up and removes the edge, so the IPA-CP transformation is not
> run-time checked.  However, the cgraph verifier does see the edge
> before that happens and is OK with it.

You can probably play with anonymous namespaces and final flags to get
it devirtualized unconditnally.
> 
> I have also took the liberty of removing an extra call to
> cgraph_function_or_thunk_node (clone_of_p calls it too) and a clearly
> obsolete comment from verify_edge_corresponds_to_fndecl.
> 
> Bootstrapped and tested on x86_64-linux.  OK for trunk?
> 
> Thanks,
> 
> Martin
> 
> 
> 2014-03-31  Martin Jambor  <mjam...@suse.cz>
> 
>         * cgraph.h (cgraph_clone_node): New parameter added to declaration.
>         Adjust all callers.
>       * cgraph.c (clone_of_p): Also return true if thunks match.
>       (verify_edge_corresponds_to_fndecl): Removed extraneous call to
>       cgraph_function_or_thunk_node and an obsolete comment.
>         * cgraphclones.c (build_function_type_skip_args): Moved upwards in the
>         file.
>         (build_function_decl_skip_args): Likewise.
>       (set_new_clone_decl_and_node_flags): New function.
>         (duplicate_thunk_for_node): Likewise.
>         (redirect_edge_duplicating_thunks): Likewise.
>         (cgraph_clone_node): New parameter args_to_skip, pass it to
>         redirect_edge_duplicating_thunks which is called instead of
>         cgraph_redirect_edge_callee.
>         (cgraph_create_virtual_clone): Pass args_to_skip to cgraph_clone_node,
>       moved setting of a lot of flags to set_new_clone_decl_and_node_flags.
> 
> testsuite/
>         * g++.dg/ipa/pr60640-1.C: New test.
>         * g++.dg/ipa/pr60640-2.C: Likewise.
>         * g++.dg/ipa/pr60640-3.C: Likewise.

OK, with the change above.

Honza

Reply via email to