Strenghten bound for bulitin_constant_p hint.
this patch makes builtin_constant_p hint to combine with other loop hints we already support. gcc/ChangeLog: 2020-10-22 Jan Hubicka <hubicka@ucw.cz> PR ipa/97445 * ipa-inline.c (inline_insns_single): Add hint2 parameter. (inline_insns_auto): Add hint2 parameter. (can_inline_edge_by_limits_p): Update. (want_inline_small_function_p): Update. (wrapper_heuristics_may_apply): Update.
This commit is contained in:
parent
083c17f86d
commit
3fd5876793
@ -398,26 +398,42 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
|
|||||||
return inlinable;
|
return inlinable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return inlining_insns_single limit for function N. If HINT is true
|
/* Return inlining_insns_single limit for function N. If HINT or HINT2 is true
|
||||||
scale up the bound. */
|
scale up the bound. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
inline_insns_single (cgraph_node *n, bool hint)
|
inline_insns_single (cgraph_node *n, bool hint, bool hint2)
|
||||||
{
|
{
|
||||||
if (hint)
|
if (hint && hint2)
|
||||||
|
{
|
||||||
|
int64_t spd = opt_for_fn (n->decl, param_inline_heuristics_hint_percent);
|
||||||
|
spd = spd * spd;
|
||||||
|
if (spd > 1000000)
|
||||||
|
spd = 1000000;
|
||||||
|
return opt_for_fn (n->decl, param_max_inline_insns_single) * spd / 100;
|
||||||
|
}
|
||||||
|
if (hint || hint2)
|
||||||
return opt_for_fn (n->decl, param_max_inline_insns_single)
|
return opt_for_fn (n->decl, param_max_inline_insns_single)
|
||||||
* opt_for_fn (n->decl, param_inline_heuristics_hint_percent) / 100;
|
* opt_for_fn (n->decl, param_inline_heuristics_hint_percent) / 100;
|
||||||
return opt_for_fn (n->decl, param_max_inline_insns_single);
|
return opt_for_fn (n->decl, param_max_inline_insns_single);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return inlining_insns_auto limit for function N. If HINT is true
|
/* Return inlining_insns_auto limit for function N. If HINT or HINT2 is true
|
||||||
scale up the bound. */
|
scale up the bound. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
inline_insns_auto (cgraph_node *n, bool hint)
|
inline_insns_auto (cgraph_node *n, bool hint, bool hint2)
|
||||||
{
|
{
|
||||||
int max_inline_insns_auto = opt_for_fn (n->decl, param_max_inline_insns_auto);
|
int max_inline_insns_auto = opt_for_fn (n->decl, param_max_inline_insns_auto);
|
||||||
if (hint)
|
if (hint && hint2)
|
||||||
|
{
|
||||||
|
int64_t spd = opt_for_fn (n->decl, param_inline_heuristics_hint_percent);
|
||||||
|
spd = spd * spd;
|
||||||
|
if (spd > 1000000)
|
||||||
|
spd = 1000000;
|
||||||
|
return max_inline_insns_auto * spd / 100;
|
||||||
|
}
|
||||||
|
if (hint || hint2)
|
||||||
return max_inline_insns_auto
|
return max_inline_insns_auto
|
||||||
* opt_for_fn (n->decl, param_inline_heuristics_hint_percent) / 100;
|
* opt_for_fn (n->decl, param_inline_heuristics_hint_percent) / 100;
|
||||||
return max_inline_insns_auto;
|
return max_inline_insns_auto;
|
||||||
@ -566,8 +582,8 @@ can_inline_edge_by_limits_p (struct cgraph_edge *e, bool report,
|
|||||||
int growth = estimate_edge_growth (e);
|
int growth = estimate_edge_growth (e);
|
||||||
if (growth > opt_for_fn (caller->decl, param_max_inline_insns_size)
|
if (growth > opt_for_fn (caller->decl, param_max_inline_insns_size)
|
||||||
&& (!DECL_DECLARED_INLINE_P (callee->decl)
|
&& (!DECL_DECLARED_INLINE_P (callee->decl)
|
||||||
&& growth >= MAX (inline_insns_single (caller, false),
|
&& growth >= MAX (inline_insns_single (caller, false, false),
|
||||||
inline_insns_auto (caller, false))))
|
inline_insns_auto (caller, false, false))))
|
||||||
{
|
{
|
||||||
e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
|
e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
|
||||||
inlinable = false;
|
inlinable = false;
|
||||||
@ -806,7 +822,7 @@ inlining_speedup (struct cgraph_edge *edge,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if the speedup for inlining E is bigger than
|
/* Return true if the speedup for inlining E is bigger than
|
||||||
PARAM_MAX_INLINE_MIN_SPEEDUP. */
|
param_inline_min_speedup. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
big_speedup_p (struct cgraph_edge *e)
|
big_speedup_p (struct cgraph_edge *e)
|
||||||
@ -855,7 +871,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
|
|||||||
&& (!e->count.ipa ().initialized_p () || !e->maybe_hot_p ()))
|
&& (!e->count.ipa ().initialized_p () || !e->maybe_hot_p ()))
|
||||||
&& ipa_fn_summaries->get (callee)->min_size
|
&& ipa_fn_summaries->get (callee)->min_size
|
||||||
- ipa_call_summaries->get (e)->call_stmt_size
|
- ipa_call_summaries->get (e)->call_stmt_size
|
||||||
> inline_insns_auto (e->caller, true))
|
> inline_insns_auto (e->caller, true, true))
|
||||||
{
|
{
|
||||||
e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
|
e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
|
||||||
want_inline = false;
|
want_inline = false;
|
||||||
@ -864,7 +880,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
|
|||||||
|| e->count.ipa ().nonzero_p ())
|
|| e->count.ipa ().nonzero_p ())
|
||||||
&& ipa_fn_summaries->get (callee)->min_size
|
&& ipa_fn_summaries->get (callee)->min_size
|
||||||
- ipa_call_summaries->get (e)->call_stmt_size
|
- ipa_call_summaries->get (e)->call_stmt_size
|
||||||
> inline_insns_single (e->caller, true))
|
> inline_insns_single (e->caller, true, true))
|
||||||
{
|
{
|
||||||
e->inline_failed = (DECL_DECLARED_INLINE_P (callee->decl)
|
e->inline_failed = (DECL_DECLARED_INLINE_P (callee->decl)
|
||||||
? CIF_MAX_INLINE_INSNS_SINGLE_LIMIT
|
? CIF_MAX_INLINE_INSNS_SINGLE_LIMIT
|
||||||
@ -875,11 +891,14 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
|
|||||||
{
|
{
|
||||||
int growth = estimate_edge_growth (e);
|
int growth = estimate_edge_growth (e);
|
||||||
ipa_hints hints = estimate_edge_hints (e);
|
ipa_hints hints = estimate_edge_hints (e);
|
||||||
|
/* We have two independent groups of hints. If one matches in each
|
||||||
|
of groups the limits are inreased. If both groups matches, limit
|
||||||
|
is increased even more. */
|
||||||
bool apply_hints = (hints & (INLINE_HINT_indirect_call
|
bool apply_hints = (hints & (INLINE_HINT_indirect_call
|
||||||
| INLINE_HINT_known_hot
|
| INLINE_HINT_known_hot
|
||||||
| INLINE_HINT_loop_iterations
|
| INLINE_HINT_loop_iterations
|
||||||
| INLINE_HINT_loop_stride
|
| INLINE_HINT_loop_stride));
|
||||||
| INLINE_HINT_builtin_constant_p));
|
bool apply_hints2 = (hints & INLINE_HINT_builtin_constant_p);
|
||||||
|
|
||||||
if (growth <= opt_for_fn (to->decl,
|
if (growth <= opt_for_fn (to->decl,
|
||||||
param_max_inline_insns_size))
|
param_max_inline_insns_size))
|
||||||
@ -889,9 +908,11 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
|
|||||||
Avoid computation of big_speedup_p when not necessary to change
|
Avoid computation of big_speedup_p when not necessary to change
|
||||||
outcome of decision. */
|
outcome of decision. */
|
||||||
else if (DECL_DECLARED_INLINE_P (callee->decl)
|
else if (DECL_DECLARED_INLINE_P (callee->decl)
|
||||||
&& growth >= inline_insns_single (e->caller, apply_hints)
|
&& growth >= inline_insns_single (e->caller, apply_hints,
|
||||||
&& (apply_hints
|
apply_hints2)
|
||||||
|| growth >= inline_insns_single (e->caller, true)
|
&& (apply_hints || apply_hints2
|
||||||
|
|| growth >= inline_insns_single (e->caller, true,
|
||||||
|
apply_hints2)
|
||||||
|| !big_speedup_p (e)))
|
|| !big_speedup_p (e)))
|
||||||
{
|
{
|
||||||
e->inline_failed = CIF_MAX_INLINE_INSNS_SINGLE_LIMIT;
|
e->inline_failed = CIF_MAX_INLINE_INSNS_SINGLE_LIMIT;
|
||||||
@ -903,7 +924,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
|
|||||||
param_max_inline_insns_small))
|
param_max_inline_insns_small))
|
||||||
{
|
{
|
||||||
/* growth_positive_p is expensive, always test it last. */
|
/* growth_positive_p is expensive, always test it last. */
|
||||||
if (growth >= inline_insns_single (e->caller, false)
|
if (growth >= inline_insns_single (e->caller, false, false)
|
||||||
|| growth_positive_p (callee, e, growth))
|
|| growth_positive_p (callee, e, growth))
|
||||||
{
|
{
|
||||||
e->inline_failed = CIF_NOT_DECLARED_INLINED;
|
e->inline_failed = CIF_NOT_DECLARED_INLINED;
|
||||||
@ -913,13 +934,15 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
|
|||||||
/* Apply param_max_inline_insns_auto limit for functions not declared
|
/* Apply param_max_inline_insns_auto limit for functions not declared
|
||||||
inline. Bypass the limit when speedup seems big. */
|
inline. Bypass the limit when speedup seems big. */
|
||||||
else if (!DECL_DECLARED_INLINE_P (callee->decl)
|
else if (!DECL_DECLARED_INLINE_P (callee->decl)
|
||||||
&& growth >= inline_insns_auto (e->caller, apply_hints)
|
&& growth >= inline_insns_auto (e->caller, apply_hints,
|
||||||
&& (apply_hints
|
apply_hints2)
|
||||||
|| growth >= inline_insns_auto (e->caller, true)
|
&& (apply_hints || apply_hints2
|
||||||
|
|| growth >= inline_insns_auto (e->caller, true,
|
||||||
|
apply_hints2)
|
||||||
|| !big_speedup_p (e)))
|
|| !big_speedup_p (e)))
|
||||||
{
|
{
|
||||||
/* growth_positive_p is expensive, always test it last. */
|
/* growth_positive_p is expensive, always test it last. */
|
||||||
if (growth >= inline_insns_single (e->caller, false)
|
if (growth >= inline_insns_single (e->caller, false, false)
|
||||||
|| growth_positive_p (callee, e, growth))
|
|| growth_positive_p (callee, e, growth))
|
||||||
{
|
{
|
||||||
e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
|
e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
|
||||||
@ -928,7 +951,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
|
|||||||
}
|
}
|
||||||
/* If call is cold, do not inline when function body would grow. */
|
/* If call is cold, do not inline when function body would grow. */
|
||||||
else if (!e->maybe_hot_p ()
|
else if (!e->maybe_hot_p ()
|
||||||
&& (growth >= inline_insns_single (e->caller, false)
|
&& (growth >= inline_insns_single (e->caller, false, false)
|
||||||
|| growth_positive_p (callee, e, growth)))
|
|| growth_positive_p (callee, e, growth)))
|
||||||
{
|
{
|
||||||
e->inline_failed = CIF_UNLIKELY_CALL;
|
e->inline_failed = CIF_UNLIKELY_CALL;
|
||||||
@ -1112,8 +1135,8 @@ static bool
|
|||||||
wrapper_heuristics_may_apply (struct cgraph_node *where, int size)
|
wrapper_heuristics_may_apply (struct cgraph_node *where, int size)
|
||||||
{
|
{
|
||||||
return size < (DECL_DECLARED_INLINE_P (where->decl)
|
return size < (DECL_DECLARED_INLINE_P (where->decl)
|
||||||
? inline_insns_single (where, false)
|
? inline_insns_single (where, false, false)
|
||||||
: inline_insns_auto (where, false));
|
: inline_insns_auto (where, false, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A cost model driving the inlining heuristics in a way so the edges with
|
/* A cost model driving the inlining heuristics in a way so the edges with
|
||||||
|
Loading…
Reference in New Issue
Block a user