This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Enable inlining into thunks
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: Martin Liška <mliska at suse dot cz>
- Cc: Jan Hubicka <hubicka at ucw dot cz>, gcc-patches at gcc dot gnu dot org
- Date: Mon, 16 May 2016 12:15:09 +0200
- Subject: Re: Enable inlining into thunks
- Authentication-results: sourceware.org; auth=none
- References: <20160515222210 dot GD33559 at kam dot mff dot cuni dot cz> <573994D6 dot 7040608 at suse dot cz>
> 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" } } */