> On 05/16/2016 12:22 AM, Jan Hubicka wrote: > > Hi, > > this patch teach inliner to inline into thunks. This is easy to do - all we > > need > > is to produce a gimple body when we decide to do so. This fixes some ages > > old xfails > > and enables some 40k inlines in Firefox. Not all those inlines are win, > > because > > the codst model of thunks is wrong. We need to model that thunk calls are > > really just > > simple jumps. I will do that incrementally. > > > > Bootstrapped/regtested x86_64-linux, will commit it tomorrow. > > Hi Honza. > > I've spotted a new ICE after I've applied all your patches (4) related > to thunk expansion. > > tc.ii:13:80: error: Thunk is not supposed to have body > int C::m_fn2(B &p1, int p2, int p3, int &p4) { m_fn1()->m_fn2(p1, p2, p3, > p4); }
I forgot two hunks in the final patch, here is version I comitted (which also fixes the ICE you mention): Index: cgraph.c =================================================================== --- cgraph.c (revision 236269) +++ cgraph.c (working copy) @@ -3324,7 +3324,7 @@ cgraph_node::verify_node (void) error ("More than one edge out of thunk node"); error_found = true; } - if (gimple_has_body_p (decl)) + if (gimple_has_body_p (decl) && !global.inlined_to) { error ("Thunk is not supposed to have body"); error_found = true; Index: cgraphclones.c =================================================================== --- cgraphclones.c (revision 236269) +++ cgraphclones.c (working copy) @@ -337,8 +337,6 @@ duplicate_thunk_for_node (cgraph_node *t cgraph_edge *e = new_thunk->create_edge (node, NULL, 0, CGRAPH_FREQ_BASE); - e->call_stmt_cannot_inline_p = true; - e->inline_failed = CIF_THUNK; symtab->call_edge_duplication_hooks (thunk->callees, e); symtab->call_cgraph_duplication_hooks (thunk, new_thunk); return new_thunk; Index: cif-code.def =================================================================== --- cif-code.def (revision 236269) +++ cif-code.def (working copy) @@ -95,10 +95,6 @@ DEFCIFCODE(MISMATCHED_ARGUMENTS, CIF_FIN DEFCIFCODE(LTO_MISMATCHED_DECLARATIONS, CIF_FINAL_ERROR, N_("mismatched declarations during linktime optimization")) -/* Caller is thunk. */ -DEFCIFCODE(THUNK, CIF_FINAL_ERROR, - N_("thunk call")) - /* Call was originally indirect. */ DEFCIFCODE(ORIGINALLY_INDIRECT_CALL, CIF_FINAL_NORMAL, N_("originally indirect function call not considered for inlining")) Index: ipa-inline-analysis.c =================================================================== --- ipa-inline-analysis.c (revision 236269) +++ ipa-inline-analysis.c (working copy) @@ -2932,11 +2932,13 @@ compute_inline_parameters (struct cgraph struct inline_edge_summary *es = inline_edge_summary (node->callees); struct predicate t = true_predicate (); - node->callees->inline_failed = CIF_THUNK; node->local.can_change_signature = false; - es->call_stmt_size = INLINE_SIZE_SCALE; - es->call_stmt_time = INLINE_TIME_SCALE; - account_size_time (info, INLINE_SIZE_SCALE * 2, INLINE_TIME_SCALE * 2, &t); + es->call_stmt_size = eni_size_weights.call_cost; + es->call_stmt_time = eni_time_weights.call_cost; + account_size_time (info, INLINE_SIZE_SCALE * 2, + INLINE_TIME_SCALE * 2, &t); + t = not_inlined_predicate (); + account_size_time (info, 2 * INLINE_SIZE_SCALE, 0, &t); inline_update_overall_summary (node); info->self_size = info->size; info->self_time = info->time; Index: ipa-inline-transform.c =================================================================== --- ipa-inline-transform.c (revision 236269) +++ ipa-inline-transform.c (working copy) @@ -314,12 +314,20 @@ inline_call (struct cgraph_edge *e, bool /* Don't even think of inlining inline clone. */ gcc_assert (!callee->global.inlined_to); - e->inline_failed = CIF_OK; - DECL_POSSIBLY_INLINED (callee->decl) = true; - to = e->caller; if (to->global.inlined_to) to = to->global.inlined_to; + if (to->thunk.thunk_p) + { + if (in_lto_p) + to->get_untransformed_body (); + to->expand_thunk (false, true); + e = to->callees; + } + + + e->inline_failed = CIF_OK; + DECL_POSSIBLY_INLINED (callee->decl) = true; if (DECL_FUNCTION_PERSONALITY (callee->decl)) DECL_FUNCTION_PERSONALITY (to->decl) @@ -580,7 +588,7 @@ preserve_function_body_p (struct cgraph_ gcc_assert (!node->alias && !node->thunk.thunk_p); /* Look if there is any clone around. */ - if (node->clones) + if (node->clones && !node->clones->thunk.thunk_p) return true; return false; } Index: testsuite/g++.dg/ipa/ivinline-7.C =================================================================== --- testsuite/g++.dg/ipa/ivinline-7.C (revision 236269) +++ testsuite/g++.dg/ipa/ivinline-7.C (working copy) @@ -76,4 +76,4 @@ int main (int argc, char *argv[]) } /* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::.*foo" "inline" } } */ -/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main" "inline" { xfail *-*-* } } } */ +/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main" "inline" } } */ Index: testsuite/g++.dg/ipa/ivinline-9.C =================================================================== --- testsuite/g++.dg/ipa/ivinline-9.C (revision 236269) +++ testsuite/g++.dg/ipa/ivinline-9.C (working copy) @@ -90,4 +90,4 @@ int main (int argc, char *argv[]) } /* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::.*foo" "inline" } } */ -/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main" "inline" { xfail *-*-* } } } */ +/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main" "inline" } } */