Message ID | 20120210142507.GA18768@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
On 02/10/2012 06:25 AM, Jakub Jelinek wrote: > PR middle-end/51929 > * cgraphunit.c (verify_edge_corresponds_to_fndecl): If node is > a same_body_alias, also test whether e->callee isn't a former > or current clone of the decl this is a same body alias of. Do we want a similar change to the use of former_clone_of in cgraph_update_edges_for_call_stmt_node? Maybe we should wrap the former_clone_of checking in a function to make that simpler. Jason
On Tue, Feb 14, 2012 at 11:12:31AM -0800, Jason Merrill wrote: > On 02/10/2012 06:25 AM, Jakub Jelinek wrote: > > PR middle-end/51929 > > * cgraphunit.c (verify_edge_corresponds_to_fndecl): If node is > > a same_body_alias, also test whether e->callee isn't a former > > or current clone of the decl this is a same body alias of. > > Do we want a similar change to the use of former_clone_of in > cgraph_update_edges_for_call_stmt_node? Maybe we should wrap the I don't think so. new_call in that case is what we are changing the call to, and we should never change some call into a call to same body alias function, calls to same body alias functions should be just those that haven't been changed yet. > former_clone_of checking in a function to make that simpler. Jakub
On 02/14/2012 11:49 AM, Jakub Jelinek wrote: >> Do we want a similar change to the use of former_clone_of in >> cgraph_update_edges_for_call_stmt_node? > > I don't think so. Then let's say the patch is OK tomorrow unless Jan objects today. Jason
> On Tue, Feb 14, 2012 at 11:12:31AM -0800, Jason Merrill wrote: > > On 02/10/2012 06:25 AM, Jakub Jelinek wrote: > > > PR middle-end/51929 > > > * cgraphunit.c (verify_edge_corresponds_to_fndecl): If node is > > > a same_body_alias, also test whether e->callee isn't a former > > > or current clone of the decl this is a same body alias of. > > > > Do we want a similar change to the use of former_clone_of in > > cgraph_update_edges_for_call_stmt_node? Maybe we should wrap the > > I don't think so. new_call in that case is what we are changing the > call to, and we should never change some call into a call to same body alias > function, calls to same body alias functions should be just those that > haven't been changed yet. Yes, I think cgraph_update_edges_for_call_stmt_node is fine here. I am not sure how long we will be able to maintain the edges sanity check. It is useful, but as we start doing more and more involved redirections we may need to disable it eventually. Honza > > > former_clone_of checking in a function to make that simpler. > > Jakub
--- gcc/cgraphunit.c.jj 2012-02-03 13:31:41.000000000 +0100 +++ gcc/cgraphunit.c 2012-02-10 12:35:44.682099203 +0100 @@ -471,11 +471,17 @@ verify_edge_corresponds_to_fndecl (struc return false; node = cgraph_function_or_thunk_node (node, NULL); - if ((e->callee->former_clone_of != node->decl) + if ((e->callee->former_clone_of != node->decl + && (!node->same_body_alias + || e->callee->former_clone_of != node->thunk.alias)) /* IPA-CP sometimes redirect edge to clone and then back to the former - function. This ping-pong has to go, eventaully. */ + function. This ping-pong has to go, eventually. */ && (node != cgraph_function_or_thunk_node (e->callee, NULL)) - && !clone_of_p (node, e->callee)) + && !clone_of_p (node, e->callee) + /* If decl is a same body alias of some other decl, allow e->callee to be + a clone of a clone of that other decl too. */ + && (!node->same_body_alias + || !clone_of_p (cgraph_get_node (node->thunk.alias), e->callee))) return true; else return false; @@ -667,7 +673,7 @@ verify_cgraph_node (struct cgraph_node * for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++) if (ref->use != IPA_REF_ALIAS) { - error ("Alias has non-alias refernece"); + error ("Alias has non-alias reference"); error_found = true; } else if (ref_found) --- gcc/testsuite/g++.dg/ipa/pr51929.C.jj 2012-02-10 12:36:55.792748549 +0100 +++ gcc/testsuite/g++.dg/ipa/pr51929.C 2012-02-09 19:42:10.000000000 +0100 @@ -0,0 +1,32 @@ +// PR middle-end/51929 +// { dg-do compile } +// { dg-options "-O -fno-guess-branch-probability -fipa-cp -fipa-cp-clone --param=max-inline-insns-single=25" } + +struct A +{ + A (A, unsigned); + A (const char *); + ~A () { a1 (a4 ()); } + void a1 (int); + unsigned a2 (); + char *a3 (); + int a4 (); +}; + +template <typename T> +struct B +{ + A b; + B (A x, int y = 1) : b (x.a3 (), x.a2 ()) { if (y & 1) b.a2 (); } +}; + +extern template struct B <char>; +A a1 ("foo"), a2 ("bar"); +B<char> b1 (a1), b2 (a2, 8); + +void +foo () +{ + A a3 ("baz"); + B<char> b3 (a1), b4 (a3); +}