@@ -3391,8 +3391,9 @@ perform_estimation_of_a_value (cgraph_node *node, ipa_call_arg_values *avals,
sreal time, base_time;
ipa_hints hints;
- estimate_ipcp_clone_size_and_time (node, avals, &size, &time,
- &base_time, &hints);
+ ipa_call_context ctx = ipa_call_context::for_cloned_node (node, avals);
+ ctx.estimate_size_and_time (&size, NULL, &time, &base_time, &hints);
+
base_time -= time;
if (base_time > 65535)
base_time = 65535;
@@ -3469,8 +3470,9 @@ estimate_local_effects (struct cgraph_node *node)
init_caller_stats (&stats);
node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
false);
- estimate_ipcp_clone_size_and_time (node, &avals, &size, &time,
- &base_time, &hints);
+ ipa_call_context ctx = ipa_call_context::for_cloned_node (node, &avals);
+ ctx.estimate_size_and_time (&size, NULL, &time, &base_time, &hints);
+
time -= devirt_bonus;
time -= hint_time_bonus (node, hints);
time -= removable_params_cost;
@@ -539,7 +539,7 @@ fre_will_run_p (struct cgraph_node *node)
except for m_known_contexts which will only be calculated if
COMPUTE_CONTEXTS is true. */
-void
+static void
evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
clause_t *clause_ptr,
clause_t *nonspec_clause_ptr,
@@ -3423,27 +3423,40 @@ ipa_call_context::estimate_size_and_time (int *ret_size,
return;
}
+/* Construct and create a context object representing the context of E, if it
+ were inlined. INLINE_PARAM_SUMMARY must be an existing summary with change
+ probabilities of individual parameters. ARG_VALUES will be computed, this is
+ but this structure will be used to hold the result throughout the life of
+ the result context. */
-/* Estimate size and time needed to execute callee of EDGE assuming that
- parameters known to be constant at caller of EDGE are propagated.
- KNOWN_VALS and KNOWN_CONTEXTS are vectors of assumed known constant values
- and types for parameters. */
+ipa_call_context
+ipa_call_context
+::for_inlined_edge (cgraph_edge *e,
+ vec<inline_param_summary> inline_param_summary,
+ ipa_call_arg_values *arg_values)
+{
+ clause_t clause, nonspec_clause;
+ evaluate_properties_for_edge (e, true, &clause, &nonspec_clause,
+ arg_values, true);
+ return ipa_call_context (e->callee->ultimate_alias_target (),
+ clause, nonspec_clause, inline_param_summary,
+ arg_values);
+}
-void
-estimate_ipcp_clone_size_and_time (struct cgraph_node *node,
- ipa_call_arg_values *avals,
- int *ret_size, sreal *ret_time,
- sreal *ret_nonspec_time,
- ipa_hints *hints)
+/* Construct and create a context object representing calls to a presumed
+ specialized clone of NODE if information about arguments in ARG_VALUES as
+ passed to this function are true. The resulting context will point to
+ ARG_VALUES throughout its lifetime. */
+
+ipa_call_context
+ipa_call_context::for_cloned_node (cgraph_node *node,
+ ipa_call_arg_values *arg_values)
{
clause_t clause, nonspec_clause;
- evaluate_conditions_for_known_args (node, false, avals, &clause,
+ evaluate_conditions_for_known_args (node, false, arg_values, &clause,
&nonspec_clause);
- ipa_call_context ctx (node, clause, nonspec_clause,
- vNULL, avals);
- ctx.estimate_size_and_time (ret_size, NULL, ret_time,
- ret_nonspec_time, hints);
+ return ipa_call_context (node, clause, nonspec_clause, vNULL, arg_values);
}
/* Return stack frame offset where frame of NODE is supposed to start inside
@@ -296,6 +296,13 @@ class ipa_node_context_cache_entry;
class ipa_call_context
{
public:
+ static ipa_call_context for_inlined_edge (cgraph_edge *e,
+ vec<inline_param_summary>
+ inline_param_summary,
+ ipa_call_arg_values *arg_values);
+ static ipa_call_context for_cloned_node (cgraph_node *node,
+ ipa_call_arg_values *arg_values);
+
ipa_call_context (cgraph_node *node,
clause_t possible_truths,
clause_t nonspec_possible_truths,
@@ -342,22 +349,10 @@ void ipa_dump_hints (FILE *f, ipa_hints);
void ipa_free_fn_summary (void);
void ipa_free_size_summary (void);
void inline_analyze_function (struct cgraph_node *node);
-void estimate_ipcp_clone_size_and_time (struct cgraph_node *,
- ipa_call_arg_values *,
- int *, sreal *, sreal *,
- ipa_hints *);
void ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge);
void ipa_update_overall_fn_summary (struct cgraph_node *node, bool reset = true);
void compute_fn_summary (struct cgraph_node *, bool);
-
-void evaluate_properties_for_edge (struct cgraph_edge *e,
- bool inline_p,
- clause_t *clause_ptr,
- clause_t *nonspec_clause_ptr,
- ipa_call_arg_values *avals,
- bool compute_contexts);
-
void ipa_fnsummary_c_finalize (void);
HOST_WIDE_INT ipa_get_stack_frame_offset (struct cgraph_node *node);
void ipa_remove_from_growth_caches (struct cgraph_edge *edge);
@@ -405,7 +405,6 @@ do_estimate_edge_time (struct cgraph_edge *edge, sreal *ret_nonspec_time)
int size;
ipa_hints hints;
struct cgraph_node *callee;
- clause_t clause, nonspec_clause;
ipa_call_arg_values avals;
class ipa_call_summary *es = ipa_call_summaries->get (edge);
int min_size = -1;
@@ -413,9 +412,8 @@ do_estimate_edge_time (struct cgraph_edge *edge, sreal *ret_nonspec_time)
callee = edge->callee->ultimate_alias_target ();
gcc_checking_assert (edge->inline_failed);
- evaluate_properties_for_edge (edge, true, &clause, &nonspec_clause,
- &avals, true);
- ipa_call_context ctx (callee, clause, nonspec_clause, es->param, &avals);
+ ipa_call_context ctx = ipa_call_context::for_inlined_edge (edge, es->param,
+ &avals);
if (node_context_cache != NULL)
{
node_context_summary *e = node_context_cache->get (callee);
@@ -527,8 +525,6 @@ int
do_estimate_edge_size (struct cgraph_edge *edge)
{
int size;
- struct cgraph_node *callee;
- clause_t clause, nonspec_clause;
ipa_call_arg_values avals;
/* When we do caching, use do_estimate_edge_time to populate the entry. */
@@ -541,13 +537,10 @@ do_estimate_edge_size (struct cgraph_edge *edge)
return size - (size > 0);
}
- callee = edge->callee->ultimate_alias_target ();
-
/* Early inliner runs without caching, go ahead and do the dirty work. */
gcc_checking_assert (edge->inline_failed);
- evaluate_properties_for_edge (edge, true, &clause, &nonspec_clause, &avals,
- true);
- ipa_call_context ctx (callee, clause, nonspec_clause, vNULL, &avals);
+ ipa_call_context ctx = ipa_call_context::for_inlined_edge (edge, vNULL,
+ &avals);
ctx.estimate_size_and_time (&size, NULL, NULL, NULL, NULL);
return size;
}
@@ -560,8 +553,6 @@ ipa_hints
do_estimate_edge_hints (struct cgraph_edge *edge)
{
ipa_hints hints;
- struct cgraph_node *callee;
- clause_t clause, nonspec_clause;
ipa_call_arg_values avals;
/* When we do caching, use do_estimate_edge_time to populate the entry. */
@@ -574,13 +565,10 @@ do_estimate_edge_hints (struct cgraph_edge *edge)
return hints - 1;
}
- callee = edge->callee->ultimate_alias_target ();
-
/* Early inliner runs without caching, go ahead and do the dirty work. */
gcc_checking_assert (edge->inline_failed);
- evaluate_properties_for_edge (edge, true, &clause, &nonspec_clause, &avals,
- true);
- ipa_call_context ctx (callee, clause, nonspec_clause, vNULL, &avals);
+ ipa_call_context ctx = ipa_call_context::for_inlined_edge (edge, vNULL,
+ &avals);
ctx.estimate_size_and_time (NULL, NULL, NULL, NULL, &hints);
hints |= simple_edge_hints (edge);
return hints;