ipa-fnsummary.c (ipa_call_context): New constructor.
* ipa-fnsummary.c (ipa_call_context): New constructor. (estimate_node_size_and_time): Turn to ... (ipa_call_context::estimate_size_and_time): ... this one. (ipa_call_context::release): New. * ipa-fnsummary.h (ipa_call_context): New class. (estimate_node_size_and_time): Remove. * ipa-inline-analysis.c (do_estimate_edge_time, do_estimate_edge_size, do_estimate_edge_hints): Update. From-SVN: r277755
This commit is contained in:
parent
a9a0fd0e28
commit
1532500ecb
4 changed files with 125 additions and 65 deletions
|
@ -1,3 +1,14 @@
|
|||
2019-11-02 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
* ipa-fnsummary.c (ipa_call_context): New constructor.
|
||||
(estimate_node_size_and_time): Turn to ...
|
||||
(ipa_call_context::estimate_size_and_time): ... this one.
|
||||
(ipa_call_context::release): New.
|
||||
* ipa-fnsummary.h (ipa_call_context): New class.
|
||||
(estimate_node_size_and_time): Remove.
|
||||
* ipa-inline-analysis.c (do_estimate_edge_time, do_estimate_edge_size,
|
||||
do_estimate_edge_hints): Update.
|
||||
|
||||
2019-11-02 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
* config.in: Regenerate.
|
||||
|
|
|
@ -2940,31 +2940,54 @@ estimate_calls_size_and_time (struct cgraph_node *node, int *size,
|
|||
}
|
||||
}
|
||||
|
||||
/* Default constructor for ipa call context.
|
||||
Memory alloction of known_vals, known_contexts
|
||||
and known_aggs vectors is owned by the caller, but can
|
||||
be release by ipa_call_context::release.
|
||||
|
||||
inline_param_summary is owned by the caller. */
|
||||
ipa_call_context::ipa_call_context (cgraph_node *node,
|
||||
clause_t possible_truths,
|
||||
clause_t nonspec_possible_truths,
|
||||
vec<tree> known_vals,
|
||||
vec<ipa_polymorphic_call_context>
|
||||
known_contexts,
|
||||
vec<ipa_agg_jump_function_p> known_aggs,
|
||||
vec<inline_param_summary>
|
||||
inline_param_summary)
|
||||
: m_node (node), m_possible_truths (possible_truths),
|
||||
m_nonspec_possible_truths (nonspec_possible_truths),
|
||||
m_inline_param_summary (inline_param_summary),
|
||||
m_known_vals (known_vals),
|
||||
m_known_contexts (known_contexts),
|
||||
m_known_aggs (known_aggs)
|
||||
{
|
||||
}
|
||||
|
||||
/* Estimate size and time needed to execute NODE assuming
|
||||
POSSIBLE_TRUTHS clause, and KNOWN_VALS, KNOWN_AGGS and KNOWN_CONTEXTS
|
||||
information about NODE's arguments. If non-NULL use also probability
|
||||
information present in INLINE_PARAM_SUMMARY vector.
|
||||
/* Release memory used by known_vals/contexts/aggs vectors. */
|
||||
|
||||
void
|
||||
ipa_call_context::release ()
|
||||
{
|
||||
m_known_vals.release ();
|
||||
m_known_contexts.release ();
|
||||
m_known_aggs.release ();
|
||||
}
|
||||
|
||||
/* Estimate size and time needed to execute call in the given context.
|
||||
Additionally detemine hints determined by the context. Finally compute
|
||||
minimal size needed for the call that is independent on the call context and
|
||||
can be used for fast estimates. Return the values in RET_SIZE,
|
||||
RET_MIN_SIZE, RET_TIME and RET_HINTS. */
|
||||
|
||||
void
|
||||
estimate_node_size_and_time (struct cgraph_node *node,
|
||||
clause_t possible_truths,
|
||||
clause_t nonspec_possible_truths,
|
||||
vec<tree> known_vals,
|
||||
vec<ipa_polymorphic_call_context> known_contexts,
|
||||
vec<ipa_agg_jump_function_p> known_aggs,
|
||||
int *ret_size, int *ret_min_size,
|
||||
sreal *ret_time,
|
||||
sreal *ret_nonspecialized_time,
|
||||
ipa_hints *ret_hints,
|
||||
vec<inline_param_summary>
|
||||
inline_param_summary)
|
||||
ipa_call_context::estimate_size_and_time (int *ret_size,
|
||||
int *ret_min_size,
|
||||
sreal *ret_time,
|
||||
sreal *ret_nonspecialized_time,
|
||||
ipa_hints *ret_hints)
|
||||
{
|
||||
class ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
|
||||
class ipa_fn_summary *info = ipa_fn_summaries->get_create (m_node);
|
||||
size_time_entry *e;
|
||||
int size = 0;
|
||||
sreal time = 0;
|
||||
|
@ -2976,13 +2999,13 @@ estimate_node_size_and_time (struct cgraph_node *node,
|
|||
{
|
||||
bool found = false;
|
||||
fprintf (dump_file, " Estimating body: %s/%i\n"
|
||||
" Known to be false: ", node->name (),
|
||||
node->order);
|
||||
" Known to be false: ", m_node->name (),
|
||||
m_node->order);
|
||||
|
||||
for (i = predicate::not_inlined_condition;
|
||||
i < (predicate::first_dynamic_condition
|
||||
+ (int) vec_safe_length (info->conds)); i++)
|
||||
if (!(possible_truths & (1 << i)))
|
||||
if (!(m_possible_truths & (1 << i)))
|
||||
{
|
||||
if (found)
|
||||
fprintf (dump_file, ", ");
|
||||
|
@ -2991,19 +3014,19 @@ estimate_node_size_and_time (struct cgraph_node *node,
|
|||
}
|
||||
}
|
||||
|
||||
estimate_calls_size_and_time (node, &size, &min_size, &time, &hints, possible_truths,
|
||||
known_vals, known_contexts, known_aggs);
|
||||
estimate_calls_size_and_time (m_node, &size, &min_size, &time, &hints, m_possible_truths,
|
||||
m_known_vals, m_known_contexts, m_known_aggs);
|
||||
sreal nonspecialized_time = time;
|
||||
|
||||
for (i = 0; vec_safe_iterate (info->size_time_table, i, &e); i++)
|
||||
{
|
||||
bool exec = e->exec_predicate.evaluate (nonspec_possible_truths);
|
||||
bool exec = e->exec_predicate.evaluate (m_nonspec_possible_truths);
|
||||
|
||||
/* Because predicates are conservative, it can happen that nonconst is 1
|
||||
but exec is 0. */
|
||||
if (exec)
|
||||
{
|
||||
bool nonconst = e->nonconst_predicate.evaluate (possible_truths);
|
||||
bool nonconst = e->nonconst_predicate.evaluate (m_possible_truths);
|
||||
|
||||
gcc_checking_assert (e->time >= 0);
|
||||
gcc_checking_assert (time >= 0);
|
||||
|
@ -3019,7 +3042,7 @@ estimate_node_size_and_time (struct cgraph_node *node,
|
|||
nonspecialized_time += e->time;
|
||||
if (!nonconst)
|
||||
;
|
||||
else if (!inline_param_summary.exists ())
|
||||
else if (!m_inline_param_summary.exists ())
|
||||
{
|
||||
if (nonconst)
|
||||
time += e->time;
|
||||
|
@ -3027,8 +3050,8 @@ estimate_node_size_and_time (struct cgraph_node *node,
|
|||
else
|
||||
{
|
||||
int prob = e->nonconst_predicate.probability
|
||||
(info->conds, possible_truths,
|
||||
inline_param_summary);
|
||||
(info->conds, m_possible_truths,
|
||||
m_inline_param_summary);
|
||||
gcc_checking_assert (prob >= 0);
|
||||
gcc_checking_assert (prob <= REG_BR_PROB_BASE);
|
||||
time += e->time * prob / REG_BR_PROB_BASE;
|
||||
|
@ -3052,14 +3075,14 @@ estimate_node_size_and_time (struct cgraph_node *node,
|
|||
time = nonspecialized_time;
|
||||
|
||||
if (info->loop_iterations
|
||||
&& !info->loop_iterations->evaluate (possible_truths))
|
||||
&& !info->loop_iterations->evaluate (m_possible_truths))
|
||||
hints |= INLINE_HINT_loop_iterations;
|
||||
if (info->loop_stride
|
||||
&& !info->loop_stride->evaluate (possible_truths))
|
||||
&& !info->loop_stride->evaluate (m_possible_truths))
|
||||
hints |= INLINE_HINT_loop_stride;
|
||||
if (info->scc_no)
|
||||
hints |= INLINE_HINT_in_scc;
|
||||
if (DECL_DECLARED_INLINE_P (node->decl))
|
||||
if (DECL_DECLARED_INLINE_P (m_node->decl))
|
||||
hints |= INLINE_HINT_declared_inline;
|
||||
|
||||
size = RDIV (size, ipa_fn_summary::size_scale);
|
||||
|
@ -3101,10 +3124,11 @@ estimate_ipcp_clone_size_and_time (struct cgraph_node *node,
|
|||
|
||||
evaluate_conditions_for_known_args (node, false, known_vals, known_aggs,
|
||||
&clause, &nonspec_clause);
|
||||
estimate_node_size_and_time (node, clause, nonspec_clause,
|
||||
known_vals, known_contexts,
|
||||
known_aggs, ret_size, NULL, ret_time,
|
||||
ret_nonspec_time, hints, vNULL);
|
||||
ipa_call_context ctx (node, clause, nonspec_clause,
|
||||
known_vals, known_contexts,
|
||||
known_aggs, vNULL);
|
||||
ctx.estimate_size_and_time (ret_size, NULL, ret_time,
|
||||
ret_nonspec_time, hints);
|
||||
}
|
||||
|
||||
/* Return stack frame offset where frame of NODE is supposed to start inside
|
||||
|
|
|
@ -281,6 +281,47 @@ public:
|
|||
ipa_call_summary *dst_data);
|
||||
};
|
||||
|
||||
/* This object describe a context of call. That is a summary of known
|
||||
information about its parameters. Main purpose of this context is
|
||||
to give more realistic esitmations of function runtime, size and
|
||||
inline hints. */
|
||||
class ipa_call_context
|
||||
{
|
||||
public:
|
||||
ipa_call_context (cgraph_node *node,
|
||||
clause_t possible_truths,
|
||||
clause_t nonspec_possible_truths,
|
||||
vec<tree> known_vals,
|
||||
vec<ipa_polymorphic_call_context> known_contexts,
|
||||
vec<ipa_agg_jump_function_p> known_aggs,
|
||||
vec<inline_param_summary> m_inline_param_summary);
|
||||
void estimate_size_and_time (int *ret_size, int *ret_min_size,
|
||||
sreal *ret_time,
|
||||
sreal *ret_nonspecialized_time,
|
||||
ipa_hints *ret_hints);
|
||||
void release ();
|
||||
private:
|
||||
/* Called function. */
|
||||
cgraph_node *m_node;
|
||||
/* Clause describing what predicate conditionals can be satisfied
|
||||
in this context if function is inlined/specialised. */
|
||||
clause_t m_possible_truths;
|
||||
/* Clause describing what predicate conditionals can be satisfied
|
||||
in this context if function is kept offline. */
|
||||
clause_t m_nonspec_possible_truths;
|
||||
/* Inline summary maintains info about change probabilities. */
|
||||
vec<inline_param_summary> m_inline_param_summary;
|
||||
|
||||
/* The following is used only to resolve indirect calls. */
|
||||
|
||||
/* Vector describing known values of parameters. */
|
||||
vec<tree> m_known_vals;
|
||||
/* Vector describing known polymorphic call contexts. */
|
||||
vec<ipa_polymorphic_call_context> m_known_contexts;
|
||||
/* Vector describing known aggregate values. */
|
||||
vec<ipa_agg_jump_function_p> m_known_aggs;
|
||||
};
|
||||
|
||||
extern fast_call_summary <ipa_call_summary *, va_heap> *ipa_call_summaries;
|
||||
|
||||
/* In ipa-fnsummary.c */
|
||||
|
@ -302,25 +343,14 @@ void ipa_update_overall_fn_summary (struct cgraph_node *node);
|
|||
void compute_fn_summary (struct cgraph_node *, bool);
|
||||
|
||||
|
||||
void evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
|
||||
void evaluate_properties_for_edge (struct cgraph_edge *e,
|
||||
bool inline_p,
|
||||
clause_t *clause_ptr,
|
||||
clause_t *nonspec_clause_ptr,
|
||||
vec<tree> *known_vals_ptr,
|
||||
vec<ipa_polymorphic_call_context>
|
||||
*known_contexts_ptr,
|
||||
vec<ipa_agg_jump_function_p> *);
|
||||
void estimate_node_size_and_time (struct cgraph_node *node,
|
||||
clause_t possible_truths,
|
||||
clause_t nonspec_possible_truths,
|
||||
vec<tree> known_vals,
|
||||
vec<ipa_polymorphic_call_context>,
|
||||
vec<ipa_agg_jump_function_p> known_aggs,
|
||||
int *ret_size, int *ret_min_size,
|
||||
sreal *ret_time,
|
||||
sreal *ret_nonspecialized_time,
|
||||
ipa_hints *ret_hints,
|
||||
vec<inline_param_summary>
|
||||
inline_param_summary);
|
||||
|
||||
void ipa_fnsummary_c_finalize (void);
|
||||
HOST_WIDE_INT ipa_get_stack_frame_offset (struct cgraph_node *node);
|
||||
|
|
|
@ -137,9 +137,10 @@ do_estimate_edge_time (struct cgraph_edge *edge)
|
|||
evaluate_properties_for_edge (edge, true,
|
||||
&clause, &nonspec_clause, &known_vals,
|
||||
&known_contexts, &known_aggs);
|
||||
estimate_node_size_and_time (callee, clause, nonspec_clause, known_vals,
|
||||
known_contexts, known_aggs, &size, &min_size,
|
||||
&time, &nonspec_time, &hints, es->param);
|
||||
ipa_call_context ctx (callee, clause, nonspec_clause, known_vals,
|
||||
known_contexts, known_aggs, es->param);
|
||||
ctx.estimate_size_and_time (&size, &min_size,
|
||||
&time, &nonspec_time, &hints);
|
||||
|
||||
/* When we have profile feedback, we can quite safely identify hot
|
||||
edges and for those we disable size limits. Don't do that when
|
||||
|
@ -152,9 +153,7 @@ do_estimate_edge_time (struct cgraph_edge *edge)
|
|||
: edge->caller->count.ipa ())))
|
||||
hints |= INLINE_HINT_known_hot;
|
||||
|
||||
known_vals.release ();
|
||||
known_contexts.release ();
|
||||
known_aggs.release ();
|
||||
ctx.release ();
|
||||
gcc_checking_assert (size >= 0);
|
||||
gcc_checking_assert (time >= 0);
|
||||
|
||||
|
@ -207,12 +206,10 @@ do_estimate_edge_size (struct cgraph_edge *edge)
|
|||
&clause, &nonspec_clause,
|
||||
&known_vals, &known_contexts,
|
||||
&known_aggs);
|
||||
estimate_node_size_and_time (callee, clause, nonspec_clause, known_vals,
|
||||
known_contexts, known_aggs, &size, NULL, NULL,
|
||||
NULL, NULL, vNULL);
|
||||
known_vals.release ();
|
||||
known_contexts.release ();
|
||||
known_aggs.release ();
|
||||
ipa_call_context ctx (callee, clause, nonspec_clause, known_vals,
|
||||
known_contexts, known_aggs, vNULL);
|
||||
ctx.estimate_size_and_time (&size, NULL, NULL, NULL, NULL);
|
||||
ctx.release ();
|
||||
return size;
|
||||
}
|
||||
|
||||
|
@ -248,12 +245,10 @@ do_estimate_edge_hints (struct cgraph_edge *edge)
|
|||
&clause, &nonspec_clause,
|
||||
&known_vals, &known_contexts,
|
||||
&known_aggs);
|
||||
estimate_node_size_and_time (callee, clause, nonspec_clause, known_vals,
|
||||
known_contexts, known_aggs, NULL, NULL,
|
||||
NULL, NULL, &hints, vNULL);
|
||||
known_vals.release ();
|
||||
known_contexts.release ();
|
||||
known_aggs.release ();
|
||||
ipa_call_context ctx (callee, clause, nonspec_clause, known_vals,
|
||||
known_contexts, known_aggs, vNULL);
|
||||
ctx.estimate_size_and_time (NULL, NULL, NULL, NULL, &hints);
|
||||
ctx.release ();
|
||||
hints |= simple_edge_hints (edge);
|
||||
return hints;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue