Commit 2925cad2 by Jan Hubicka Committed by Jan Hubicka

params.def (PARAM_INLINE_HEURISTICS_HINT_PERCENT, [...]): New.


	* params.def (PARAM_INLINE_HEURISTICS_HINT_PERCENT,
	PARAM_INLINE_HEURISTICS_HINT_PERCENT_O2): New.
	* doc/invoke.texi (inline-heuristics-hint-percent,
	inline-heuristics-hint-percent-O2): Document.
	* tree-inline.c (inline_insns_single, inline_insns_auto): Add new
	hint attribute.
	(can_inline_edge_by_limits_p): Use it.

From-SVN: r276516
parent ebf8247e
2019-10-03 Jan Hubicka <hubicka@ucw.cz>
* params.def (PARAM_INLINE_HEURISTICS_HINT_PERCENT,
PARAM_INLINE_HEURISTICS_HINT_PERCENT_O2): New.
* doc/invoke.texi (inline-heuristics-hint-percent,
inline-heuristics-hint-percent-O2): Document.
* tree-inline.c (inline_insns_single, inline_insns_auto): Add new
hint attribute.
(can_inline_edge_by_limits_p): Use it.
2019-10-03 Richard Sandiford <richard.sandiford@arm.com>
* config/arm/arm.c (arm_print_value): Use real_to_decimal
......
......@@ -11215,6 +11215,18 @@ function prologue and epilogue.
Extra time accounted by inliner for function overhead such as time needed to
execute function prologue and epilogue
@item inline-heuristics-hint-percent
@item inline-heuristics-hint-percent-O2
The scale (in percents) applied to @option{inline-insns-single},
@option{inline-insns-single-O2}, @option{inline-insns-auto},
@option{inline-insns-auto-O2} when inline heuristics hints that inlining is
very profitable (will enable later optimizations).
For functions compiled with optimization levels
@option{-O3} and @option{-Ofast} parameter
@option{inline-heuristics-hint-percent} is applied. In other cases
@option{inline-heuristics-hint-percent-O2} is applied.
@item uninlined-thunk-insns
@item uninlined-thunk-time
Same as @option{--param uninlined-function-insns} and
......@@ -390,26 +390,48 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
return inlinable;
}
/* Return inlining_insns_single limit for function N */
/* Return inlining_insns_single limit for function N. If HINT is true
scale up the bound. */
static int
inline_insns_single (cgraph_node *n)
inline_insns_single (cgraph_node *n, bool hint)
{
if (opt_for_fn (n->decl, optimize >= 3))
return PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SINGLE);
{
if (hint)
return PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SINGLE)
* PARAM_VALUE (PARAM_INLINE_HEURISTICS_HINT_PERCENT) / 100;
return PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SINGLE);
}
else
return PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SINGLE_O2);
{
if (hint)
return PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SINGLE_O2)
* PARAM_VALUE (PARAM_INLINE_HEURISTICS_HINT_PERCENT_O2) / 100;
return PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SINGLE_O2);
}
}
/* Return inlining_insns_auto limit for function N */
/* Return inlining_insns_auto limit for function N. If HINT is true
scale up the bound. */
static int
inline_insns_auto (cgraph_node *n)
inline_insns_auto (cgraph_node *n, bool hint)
{
if (opt_for_fn (n->decl, optimize >= 3))
return PARAM_VALUE (PARAM_MAX_INLINE_INSNS_AUTO);
{
if (hint)
return PARAM_VALUE (PARAM_MAX_INLINE_INSNS_AUTO)
* PARAM_VALUE (PARAM_INLINE_HEURISTICS_HINT_PERCENT) / 100;
return PARAM_VALUE (PARAM_MAX_INLINE_INSNS_AUTO);
}
else
return PARAM_VALUE (PARAM_MAX_INLINE_INSNS_AUTO_O2);
{
if (hint)
return PARAM_VALUE (PARAM_MAX_INLINE_INSNS_AUTO_O2)
* PARAM_VALUE (PARAM_INLINE_HEURISTICS_HINT_PERCENT_O2) / 100;
return PARAM_VALUE (PARAM_MAX_INLINE_INSNS_AUTO_O2);
}
}
/* Decide if we can inline the edge and possibly update
......@@ -554,8 +576,8 @@ can_inline_edge_by_limits_p (struct cgraph_edge *e, bool report,
int growth = estimate_edge_growth (e);
if (growth > PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SIZE)
&& (!DECL_DECLARED_INLINE_P (callee->decl)
&& growth >= MAX (inline_insns_single (caller),
inline_insns_auto (caller))))
&& growth >= MAX (inline_insns_single (caller, false),
inline_insns_auto (caller, false))))
{
e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
inlinable = false;
......@@ -801,15 +823,12 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
want_inline = false;
}
/* Do fast and conservative check if the function can be good
inline candidate. At the moment we allow inline hints to
promote non-inline functions to inline and we increase
MAX_INLINE_INSNS_SINGLE 16-fold for inline functions. */
inline candidate. */
else if ((!DECL_DECLARED_INLINE_P (callee->decl)
&& (!e->count.ipa ().initialized_p () || !e->maybe_hot_p ()))
&& ipa_fn_summaries->get (callee)->min_size
- ipa_call_summaries->get (e)->call_stmt_size
> MAX (inline_insns_single (e->caller),
inline_insns_auto (e->caller)))
> inline_insns_auto (e->caller, true))
{
if (opt_for_fn (e->caller->decl, optimize) >= 3)
e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
......@@ -821,7 +840,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
|| e->count.ipa ().nonzero_p ())
&& ipa_fn_summaries->get (callee)->min_size
- ipa_call_summaries->get (e)->call_stmt_size
> 16 * inline_insns_single (e->caller))
> inline_insns_single (e->caller, true))
{
if (opt_for_fn (e->caller->decl, optimize) >= 3)
e->inline_failed = (DECL_DECLARED_INLINE_P (callee->decl)
......@@ -837,20 +856,22 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
{
int growth = estimate_edge_growth (e);
ipa_hints hints = estimate_edge_hints (e);
int big_speedup = -1; /* compute this lazily */
bool apply_hints = (hints & (INLINE_HINT_indirect_call
| INLINE_HINT_known_hot
| INLINE_HINT_loop_iterations
| INLINE_HINT_loop_stride));
if (growth <= PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SIZE))
;
/* Apply MAX_INLINE_INSNS_SINGLE limit. Do not do so when
hints suggests that inlining given function is very profitable. */
hints suggests that inlining given function is very profitable.
Avoid computation of big_speedup_p when not necessary to change
outcome of decision. */
else if (DECL_DECLARED_INLINE_P (callee->decl)
&& growth >= inline_insns_single (e->caller)
&& (growth >= inline_insns_single (e->caller) * 16
|| (!(hints & (INLINE_HINT_indirect_call
| INLINE_HINT_known_hot
| INLINE_HINT_loop_iterations
| INLINE_HINT_loop_stride))
&& !(big_speedup = big_speedup_p (e)))))
&& growth >= inline_insns_single (e->caller, apply_hints)
&& (apply_hints
|| growth >= inline_insns_single (e->caller, true)
|| !big_speedup_p (e)))
{
if (opt_for_fn (e->caller->decl, optimize) >= 3)
e->inline_failed = CIF_MAX_INLINE_INSNS_SINGLE_LIMIT;
......@@ -863,28 +884,23 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
&& growth >= PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SMALL))
{
/* growth_likely_positive is expensive, always test it last. */
if (growth >= inline_insns_single (e->caller)
if (growth >= inline_insns_single (e->caller, false)
|| growth_likely_positive (callee, growth))
{
e->inline_failed = CIF_NOT_DECLARED_INLINED;
want_inline = false;
}
}
/* Apply MAX_INLINE_INSNS_AUTO limit for functions not declared inline
Upgrade it to MAX_INLINE_INSNS_SINGLE when hints suggests that
inlining given function is very profitable. */
/* Apply MAX_INLINE_INSNS_AUTO limit for functions not declared inline.
Bypass the limit when speedup seems big. */
else if (!DECL_DECLARED_INLINE_P (callee->decl)
&& !(hints & INLINE_HINT_known_hot)
&& growth >= ((hints & (INLINE_HINT_indirect_call
| INLINE_HINT_loop_iterations
| INLINE_HINT_loop_stride))
? MAX (inline_insns_auto (e->caller),
inline_insns_single (e->caller))
: inline_insns_auto (e->caller))
&& !(big_speedup == -1 ? big_speedup_p (e) : big_speedup))
&& growth >= inline_insns_auto (e->caller, apply_hints)
&& (apply_hints
|| growth >= inline_insns_auto (e->caller, true)
|| !big_speedup_p (e)))
{
/* growth_likely_positive is expensive, always test it last. */
if (growth >= inline_insns_single (e->caller)
if (growth >= inline_insns_single (e->caller, false)
|| growth_likely_positive (callee, growth))
{
if (opt_for_fn (e->caller->decl, optimize) >= 3)
......@@ -896,7 +912,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
}
/* If call is cold, do not inline when function body would grow. */
else if (!e->maybe_hot_p ()
&& (growth >= inline_insns_single (e->caller)
&& (growth >= inline_insns_single (e->caller, false)
|| growth_likely_positive (callee, growth)))
{
e->inline_failed = CIF_UNLIKELY_CALL;
......@@ -1200,12 +1216,13 @@ edge_badness (struct cgraph_edge *edge, bool dump)
int caller_growth = caller_info->growth;
/* Only apply the penalty when caller looks like inline candidate,
and it is not called once and. */
and it is not called once. */
if (!caller_info->single_caller && overall_growth < caller_growth
&& caller_info->inlinable
&& caller_info->size
< (DECL_DECLARED_INLINE_P (caller->decl)
? inline_insns_single (caller) : inline_insns_auto (caller)))
? inline_insns_single (caller, false)
: inline_insns_auto (caller, false)))
{
if (dump)
fprintf (dump_file,
......
......@@ -102,6 +102,16 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS_SMALL,
"The maximum number of instructions when automatically inlining small functions.",
0, 0, 0)
DEFPARAM (PARAM_INLINE_HEURISTICS_HINT_PERCENT,
"inline-heuristics-hint-percent",
"The scale (in percents) applied to inline-insns-single and auto limits when heuristics hints that inlining is very profitable with -O3 and -Ofast.",
1600, 100, 1000000)
DEFPARAM (PARAM_INLINE_HEURISTICS_HINT_PERCENT_O2,
"inline-heuristics-hint-percent-O2",
"The scale (in percents) applied to inline-insns-single and auto limits when heuristics hints that inlining is very profitable.",
200, 100, 1000000)
DEFPARAM (PARAM_MAX_INLINE_INSNS_SIZE,
"max-inline-insns-size",
"The maximum number of instructions when inlining for size.",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment