This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Avoid quadratic behaviour in early inlining
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 21 Nov 2019 09:19:03 +0100
- Subject: Avoid quadratic behaviour in early inlining
Hi,
because early inliner is not producing call summaries, we do not want to
estimate calls to very large function when we already know that inlning
is going to fail.
Bootstrapped/regtested x86_64-linux.
* ipa-inline.c (want_early_inline_function_p): Do not estimate
edge growth when callee function is very large.
* ipa-inline.h (estimate_min_edge_growth): New.
Index: ipa-inline.c
===================================================================
--- ipa-inline.c (revision 278540)
+++ ipa-inline.c (working copy)
@@ -672,14 +672,29 @@ want_early_inline_function_p (struct cgr
}
else
{
- int growth = estimate_edge_growth (e);
+ /* First take care of very large functions. */
+ int min_growth = estimate_min_edge_growth (e), growth = 0;
int n;
int early_inlining_insns = opt_for_fn (e->caller->decl, optimize) >= 3
? param_early_inlining_insns
: param_early_inlining_insns_o2;
+ if (min_growth > early_inlining_insns)
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
+ " will not early inline: %C->%C, "
+ "call is cold and code would grow "
+ "at least by %i\n",
+ e->caller, callee,
+ min_growth);
+ want_inline = false;
+ }
+ else
+ growth = estimate_edge_growth (e);
+
- if (growth <= param_max_inline_insns_size)
+ if (!want_inline || growth <= param_max_inline_insns_size)
;
else if (!e->maybe_hot_p ())
{
Index: ipa-inline.h
===================================================================
--- ipa-inline.h (revision 278540)
+++ ipa-inline.h (working copy)
@@ -79,6 +79,16 @@ estimate_edge_size (struct cgraph_edge *
return entry->size - (entry->size > 0);
}
+/* Return lower bound on estimated callee growth after inlining EDGE. */
+
+static inline int
+estimate_min_edge_growth (struct cgraph_edge *edge)
+{
+ ipa_call_summary *s = ipa_call_summaries->get (edge);
+ struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
+ return (ipa_fn_summaries->get (callee)->min_size - s->call_stmt_size);
+}
+
/* Return estimated callee growth after inlining EDGE. */
static inline int