diff options
author | jamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-11-14 20:03:19 +0000 |
---|---|---|
committer | jamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-11-14 20:03:19 +0000 |
commit | 245ab191eaef919a787c44b8e9ec808e552e821c (patch) | |
tree | abc9c56fc79fdcc18ce1542f7710341d6d75f88d /gcc/ipa-inline-analysis.c | |
parent | 9bfdb7bcca4eecc4ed5c55c1c943f07e82fb642d (diff) |
2014-11-14 Martin Jambor <mjambor@suse.cz>
* ipa-prop.h (ipa_get_jf_pass_through_type_preserved): use
agg_preserved flag instead.
(ipa_get_jf_ancestor_type_preserved): Likewise.
(ipa_node_params): Rename known_vals to known_csts, update all users.
New field known_contexts.
(ipa_get_indirect_edge_target): Update prototype.
(ipcp_poly_ctx_values_pool): Declare.
(ipa_context_from_jfunc): Likewise.
* ipa-inline.h (estimate_ipcp_clone_size_and_time): Updated prototype.
* cgraph.h (ipa_polymorphic_call_context): New method equal_to. New
parameter newline of method dump.
* ipa-cp.c (ctxlat): New field.
(ipcp_values_pool): Renamed to ipcp_cst_values_pool, updated all users.
(ipcp_poly_ctx_values_pool):New variable.
(ipa_get_poly_ctx_lat): New function.
(print_ipcp_constant_value): New overloaded function for contexts.
(print_all_lattices): Also print contexts.
(ipa_topo_info): New field contexts;
(set_all_contains_variable): Also set the flag in the context lattice.
(initialize_node_lattices): Likewise for flag bottom.
(ipa_get_jf_ancestor_result): Removed BINFO handling.
(ipa_value_from_jfunc): Likewise.
(ipa_context_from_jfunc): New function.
(values_equal_for_ipcp_p): New overloaded function for contexts.
(allocate_and_init_ipcp_value): Construct the value.
(allocate_and_init_ipcp_value): New overloaded function for contexts.
(propagate_scalar_accross_jump_function): Removed handling of
KNOWN_TYPE jump functions.
(propagate_context_accross_jump_function): New function.
(propagate_constants_accross_call): Also propagate contexts.
(ipa_get_indirect_edge_target_1): Work on contexts rather than BINFOs.
(ipa_get_indirect_edge_target): Likewise.
(devirtualization_time_bonus): Likewise.
(gather_context_independent_values): Create and populate known_contexts
vector rather than known_binfos.
(perform_estimation_of_a_value): Work on contexts rather than BINFOs.
(estimate_local_effects): Likewise.
(add_all_node_vals_to_toposort): Also add contexts to teir topological
sort.
(ipcp_propagate_stage): Also propagate effects of contexts.
(ipcp_discover_new_direct_edges): Receive and pass known_contexts to
ipa_get_indirect_edge_target_1.
(cgraph_edge_brings_value_p): New overloaded function for contexts.
(create_specialized_node): Work on contexts rather than BINFOs.
(find_more_contexts_for_caller_subset): New function.
(known_contexts_useful_p): New function.
(copy_useful_known_contexts): Likewise.
(modify_known_vectors_with_val): Likewise.
(ipcp_val_in_agg_replacements_p): Renamed to
ipcp_val_agg_replacement_ok_p, return true for all offset indicating
non-aggregate.
(ipcp_val_agg_replacement_ok_p): New overloaded function for contexts.
(decide_about_value): Work on contexts rather than BINFOs.
(decide_whether_version_node): Likewise.
(ipcp_driver): Initialize the new alloc pool.
* ipa-prop.c (ipa_print_node_jump_functions_for_edge): Prettify
printing of edge contexts.
(ipa_set_ancestor_jf): Replace assert with conditional setting of
type_preserved to false.
(update_jump_functions_after_inlining): Use access function instead of
reading agg_preserved directly. Store combined context in the ancestor
case.
(try_make_edge_direct_virtual_call): Work on contexts rather than
BINFOs.
(update_indirect_edges_after_inlining): Get context from
ipa_context_from_jfunc.
(ipa_free_node_params_substructures): Free also known_contexts.
(ipa_free_all_structures_after_ipa_cp): Free the new alloc pool.
(ipa_free_all_structures_after_iinln): Likewise.
* ipa-inline-analysis.c (evaluate_properties_for_edge): Work on
contexts rather than BINFOs.
(estimate_edge_devirt_benefit): Likewise.
(estimate_edge_size_and_time): Likewise.
(estimate_calls_size_and_time): Likewise.
(estimate_node_size_and_time): Likewise.
(estimate_ipcp_clone_size_and_time): Likewise.
(do_estimate_edge_time): Likewise.
(do_estimate_edge_size): Likewise.
(do_estimate_edge_hints): Likewise.
* ipa-polymorphic-call.c (ipa_polymorphic_call_context::dump): New
parameter newline, ouput newline only when it is set.
(ipa_polymorphic_call_context::equal_to): New method.
testsuite/
* g++.dg/ipa/devirt-11.C: Dont't run ipa-cp, remove times constraint
from the dump scan.
* g++.dg/ipa/devirt-21.C: Xfail.
* g++.dg/ipa/devirt-24.C: Likewise.
* g++.dg/ipa/devirt-10.C: Removed times constraint from the dump scan.
* g++.dg/ipa/devirt-41.C: Updated the dump scan.
* g++.dg/ipa/devirt-44.C: Likewise.
* g++.dg/ipa/devirt-43.C: Xfail.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217587 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-inline-analysis.c')
-rw-r--r-- | gcc/ipa-inline-analysis.c | 89 |
1 files changed, 46 insertions, 43 deletions
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 0373b108699..69e06123fee 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -895,7 +895,8 @@ static void evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p, clause_t *clause_ptr, vec<tree> *known_vals_ptr, - vec<tree> *known_binfos_ptr, + vec<ipa_polymorphic_call_context> + *known_contexts_ptr, vec<ipa_agg_jump_function_p> *known_aggs_ptr) { struct cgraph_node *callee = e->callee->ultimate_alias_target (); @@ -907,12 +908,12 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p, *clause_ptr = inline_p ? 0 : 1 << predicate_not_inlined_condition; if (known_vals_ptr) known_vals_ptr->create (0); - if (known_binfos_ptr) - known_binfos_ptr->create (0); + if (known_contexts_ptr) + known_contexts_ptr->create (0); if (ipa_node_params_vector.exists () && !e->call_stmt_cannot_inline_p - && ((clause_ptr && info->conds) || known_vals_ptr || known_binfos_ptr)) + && ((clause_ptr && info->conds) || known_vals_ptr || known_contexts_ptr)) { struct ipa_node_params *parms_info; struct ipa_edge_args *args = IPA_EDGE_REF (e); @@ -928,8 +929,8 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p, known_vals.safe_grow_cleared (count); if (count && (info->conds || known_aggs_ptr)) known_aggs.safe_grow_cleared (count); - if (count && known_binfos_ptr) - known_binfos_ptr->safe_grow_cleared (count); + if (count && known_contexts_ptr) + known_contexts_ptr->safe_grow_cleared (count); for (i = 0; i < count; i++) { @@ -937,14 +938,16 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p, tree cst = ipa_value_from_jfunc (parms_info, jf); if (cst) { - if (known_vals.exists () && TREE_CODE (cst) != TREE_BINFO) + gcc_checking_assert (TREE_CODE (cst) != TREE_BINFO); + if (known_vals.exists ()) known_vals[i] = cst; - else if (known_binfos_ptr != NULL - && TREE_CODE (cst) == TREE_BINFO) - (*known_binfos_ptr)[i] = cst; } else if (inline_p && !es->param[i].change_prob) known_vals[i] = error_mark_node; + + if (known_contexts_ptr) + (*known_contexts_ptr)[i] = ipa_context_from_jfunc (parms_info, e, + i, jf); /* TODO: When IPA-CP starts propagating and merging aggregate jump functions, use its knowledge of the caller too, just like the scalar case above. */ @@ -2969,14 +2972,14 @@ make_pass_inline_parameters (gcc::context *ctxt) } -/* Estimate benefit devirtualizing indirect edge IE, provided KNOWN_VALS and - KNOWN_BINFOS. */ +/* Estimate benefit devirtualizing indirect edge IE, provided KNOWN_VALS, + KNOWN_CONTEXTS and KNOWN_AGGS. */ static bool estimate_edge_devirt_benefit (struct cgraph_edge *ie, int *size, int *time, vec<tree> known_vals, - vec<tree> known_binfos, + vec<ipa_polymorphic_call_context> known_contexts, vec<ipa_agg_jump_function_p> known_aggs) { tree target; @@ -2984,12 +2987,12 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie, struct inline_summary *isummary; enum availability avail; - if (!known_vals.exists () && !known_binfos.exists ()) + if (!known_vals.exists () && !known_contexts.exists ()) return false; if (!flag_indirect_inlining) return false; - target = ipa_get_indirect_edge_target (ie, known_vals, known_binfos, + target = ipa_get_indirect_edge_target (ie, known_vals, known_contexts, known_aggs); if (!target) return false; @@ -3013,7 +3016,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie, /* Increase SIZE, MIN_SIZE (if non-NULL) and TIME for size and time needed to handle edge E with probability PROB. Set HINTS if edge may be devirtualized. - KNOWN_VALS, KNOWN_AGGS and KNOWN_BINFOS describe context of the call + KNOWN_VALS, KNOWN_AGGS and KNOWN_CONTEXTS describe context of the call site. */ static inline void @@ -3021,7 +3024,7 @@ estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *min_size, int *time, int prob, vec<tree> known_vals, - vec<tree> known_binfos, + vec<ipa_polymorphic_call_context> known_contexts, vec<ipa_agg_jump_function_p> known_aggs, inline_hints *hints) { @@ -3031,7 +3034,7 @@ estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *min_size, int cur_size; if (!e->callee && estimate_edge_devirt_benefit (e, &call_size, &call_time, - known_vals, known_binfos, known_aggs) + known_vals, known_contexts, known_aggs) && hints && e->maybe_hot_p ()) *hints |= INLINE_HINT_indirect_call; cur_size = call_size * INLINE_SIZE_SCALE; @@ -3047,9 +3050,8 @@ estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *min_size, /* Increase SIZE, MIN_SIZE and TIME for size and time needed to handle all - calls in NODE. - POSSIBLE_TRUTHS, KNOWN_VALS, KNOWN_AGGS and KNOWN_BINFOS describe context of - the call site. */ + calls in NODE. POSSIBLE_TRUTHS, KNOWN_VALS, KNOWN_AGGS and KNOWN_CONTEXTS + describe context of the call site. */ static void estimate_calls_size_and_time (struct cgraph_node *node, int *size, @@ -3057,7 +3059,7 @@ estimate_calls_size_and_time (struct cgraph_node *node, int *size, inline_hints *hints, clause_t possible_truths, vec<tree> known_vals, - vec<tree> known_binfos, + vec<ipa_polymorphic_call_context> known_contexts, vec<ipa_agg_jump_function_p> known_aggs) { struct cgraph_edge *e; @@ -3074,14 +3076,14 @@ estimate_calls_size_and_time (struct cgraph_node *node, int *size, estimate_edge_size_and_time (e, size, es->predicate ? NULL : min_size, time, REG_BR_PROB_BASE, - known_vals, known_binfos, + known_vals, known_contexts, known_aggs, hints); } else estimate_calls_size_and_time (e->callee, size, min_size, time, hints, possible_truths, - known_vals, known_binfos, + known_vals, known_contexts, known_aggs); } } @@ -3093,14 +3095,14 @@ estimate_calls_size_and_time (struct cgraph_node *node, int *size, estimate_edge_size_and_time (e, size, es->predicate ? NULL : min_size, time, REG_BR_PROB_BASE, - known_vals, known_binfos, known_aggs, + known_vals, known_contexts, known_aggs, hints); } } /* Estimate size and time needed to execute NODE assuming - POSSIBLE_TRUTHS clause, and KNOWN_VALS, KNOWN_AGGS and KNOWN_BINFOS + 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. Additionally detemine hints determined by the context. Finally compute @@ -3112,7 +3114,7 @@ static void estimate_node_size_and_time (struct cgraph_node *node, clause_t possible_truths, vec<tree> known_vals, - vec<tree> known_binfos, + vec<ipa_polymorphic_call_context> known_contexts, vec<ipa_agg_jump_function_p> known_aggs, int *ret_size, int *ret_min_size, int *ret_time, inline_hints *ret_hints, @@ -3189,7 +3191,7 @@ estimate_node_size_and_time (struct cgraph_node *node, hints |= INLINE_HINT_declared_inline; estimate_calls_size_and_time (node, &size, &min_size, &time, &hints, possible_truths, - known_vals, known_binfos, known_aggs); + known_vals, known_contexts, known_aggs); gcc_checking_assert (size >= 0); gcc_checking_assert (time >= 0); time = RDIV (time, INLINE_TIME_SCALE); @@ -3212,13 +3214,14 @@ estimate_node_size_and_time (struct cgraph_node *node, /* 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_BINFOS are vectors of assumed known constant values + KNOWN_VALS and KNOWN_CONTEXTS are vectors of assumed known constant values and types for parameters. */ void estimate_ipcp_clone_size_and_time (struct cgraph_node *node, vec<tree> known_vals, - vec<tree> known_binfos, + vec<ipa_polymorphic_call_context> + known_contexts, vec<ipa_agg_jump_function_p> known_aggs, int *ret_size, int *ret_time, inline_hints *hints) @@ -3227,7 +3230,7 @@ estimate_ipcp_clone_size_and_time (struct cgraph_node *node, clause = evaluate_conditions_for_known_args (node, false, known_vals, known_aggs); - estimate_node_size_and_time (node, clause, known_vals, known_binfos, + estimate_node_size_and_time (node, clause, known_vals, known_contexts, known_aggs, ret_size, NULL, ret_time, hints, vNULL); } @@ -3672,7 +3675,7 @@ do_estimate_edge_time (struct cgraph_edge *edge) struct cgraph_node *callee; clause_t clause; vec<tree> known_vals; - vec<tree> known_binfos; + vec<ipa_polymorphic_call_context> known_contexts; vec<ipa_agg_jump_function_p> known_aggs; struct inline_edge_summary *es = inline_edge_summary (edge); int min_size; @@ -3681,9 +3684,9 @@ do_estimate_edge_time (struct cgraph_edge *edge) gcc_checking_assert (edge->inline_failed); evaluate_properties_for_edge (edge, true, - &clause, &known_vals, &known_binfos, + &clause, &known_vals, &known_contexts, &known_aggs); - estimate_node_size_and_time (callee, clause, known_vals, known_binfos, + estimate_node_size_and_time (callee, clause, known_vals, known_contexts, known_aggs, &size, &min_size, &time, &hints, es->param); /* When we have profile feedback, we can quite safely identify hot @@ -3697,7 +3700,7 @@ do_estimate_edge_time (struct cgraph_edge *edge) hints |= INLINE_HINT_known_hot; known_vals.release (); - known_binfos.release (); + known_contexts.release (); known_aggs.release (); gcc_checking_assert (size >= 0); gcc_checking_assert (time >= 0); @@ -3728,7 +3731,7 @@ do_estimate_edge_size (struct cgraph_edge *edge) struct cgraph_node *callee; clause_t clause; vec<tree> known_vals; - vec<tree> known_binfos; + vec<ipa_polymorphic_call_context> known_contexts; vec<ipa_agg_jump_function_p> known_aggs; /* When we do caching, use do_estimate_edge_time to populate the entry. */ @@ -3746,12 +3749,12 @@ do_estimate_edge_size (struct cgraph_edge *edge) /* 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, &known_vals, &known_binfos, + &clause, &known_vals, &known_contexts, &known_aggs); - estimate_node_size_and_time (callee, clause, known_vals, known_binfos, + estimate_node_size_and_time (callee, clause, known_vals, known_contexts, known_aggs, &size, NULL, NULL, NULL, vNULL); known_vals.release (); - known_binfos.release (); + known_contexts.release (); known_aggs.release (); return size; } @@ -3767,7 +3770,7 @@ do_estimate_edge_hints (struct cgraph_edge *edge) struct cgraph_node *callee; clause_t clause; vec<tree> known_vals; - vec<tree> known_binfos; + vec<ipa_polymorphic_call_context> known_contexts; vec<ipa_agg_jump_function_p> known_aggs; /* When we do caching, use do_estimate_edge_time to populate the entry. */ @@ -3785,12 +3788,12 @@ do_estimate_edge_hints (struct cgraph_edge *edge) /* 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, &known_vals, &known_binfos, + &clause, &known_vals, &known_contexts, &known_aggs); - estimate_node_size_and_time (callee, clause, known_vals, known_binfos, + estimate_node_size_and_time (callee, clause, known_vals, known_contexts, known_aggs, NULL, NULL, NULL, &hints, vNULL); known_vals.release (); - known_binfos.release (); + known_contexts.release (); known_aggs.release (); hints |= simple_edge_hints (edge); return hints; |