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. Honza * ipa-inline-analysis.c (compute_inline_parameters): Be more reailistic on estimating thunk bodies; do not set inline_failed to CIF_THUNK for calls from thunk. * ipa-inline-transform.c (inline_call): When inlining into thunk produce gimple body. (preserve_function_body_p): No need to preserve function body * cif-codes.def (CIF_THUNK): Remove. * g++.dg/ipa/ivinline-7.C * g++.dg/ipa/ivinline-9.C Index: ipa-inline-analysis.c =================================================================== --- ipa-inline-analysis.c (revision 236211) +++ 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; * ipa-inline-transform.c (inline_call): When inlining into thunk turn it into gimple function. (preserve_function_body_p): No need to preserve body to inline thunk. Index: ipa-inline-transform.c =================================================================== --- ipa-inline-transform.c (revision 236211) +++ 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: cif-code.def =================================================================== --- cif-code.def (revision 236211) +++ 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: testsuite/g++.dg/ipa/ivinline-7.C =================================================================== --- testsuite/g++.dg/ipa/ivinline-7.C (revision 236211) +++ 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 236211) +++ 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" } } */