summaryrefslogtreecommitdiff
path: root/gcc/ipa-polymorphic-call.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2019-01-20 21:17:02 +0100
committerMartin Jambor <jamborm@gcc.gnu.org>2019-01-20 21:17:02 +0100
commitc628d1c325e81467fac06a92c8dfb7768e0cf7ad (patch)
treec6bd7c0f2480cdcaf35aa161824faa675368d629 /gcc/ipa-polymorphic-call.c
parent49686677ed7aa84d05b0c5db8eb28f06ebb5e529 (diff)
Limit AA walking in IPA summary generation
2019-01-20 Martin Jambor <mjambor@suse.cz> PR ipa/87615 * ipa-prop.h (struct ipa_func_body_info): Replaced field aa_walked with aa_walk_budget. * cgraph.h (ipa_polymorphic_call_context::get_dynamic_type): Add aa_walk_budget_p parameter. * ipa-fnsummary.c (unmodified_parm_1): New parameter fbi. Limit AA walk. Updated all callers. (unmodified_parm): New parameter fbi, pass it to unmodified_parm_1. (eliminated_by_inlining_prob): New parameter fbi, pass it on to unmodified_parm. (will_be_nonconstant_expr_predicate): New parameter fbi, removed parameter info. Extract info from fbi. Pass fbi to recursive calls and to unmodified_parm. (phi_result_unknown_predicate): New parameter fbi, removed parameter info, updated call to will_be_nonconstant_expr_predicate. (param_change_prob): New parameter fbi, limit AA walking. (analyze_function_body): Initialize aa_walk_budget in fbi. Update calls to various above functions. * ipa-polymorphic-call.c (get_dynamic_type): Add aa_walk_budget_p parameter. Use it to limit AA walking. * ipa-prop.c (detect_type_change_from_memory_writes): New parameter fbi, limit AA walk. (detect_type_change): New parameter fbi, pass it on to detect_type_change_from_memory_writes. (detect_type_change_ssa): Likewise. (aa_overwalked): Removed. (parm_preserved_before_stmt_p): Assume fbi is never NULL, stream line accordingly, adjust to the neew AA limiting scheme. (parm_ref_data_preserved_p): Likewise. (ipa_compute_jump_functions_for_edge): Adjust call to get_dynamic_type. (ipa_analyze_call_uses): Likewise. (ipa_analyze_virtual_call_uses): Pass fbi to detect_type_change_ssa. (ipa_analyze_node): Initialize aa_walk_budget. (ipcp_transform_function): Likewise. * tree-ssa-sccvn.c (eliminate_dom_walker::eliminate_stmt): Update call to get_dynamic_type. From-SVN: r268107
Diffstat (limited to 'gcc/ipa-polymorphic-call.c')
-rw-r--r--gcc/ipa-polymorphic-call.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c
index b93bf5561ae..75d8ebc1c44 100644
--- a/gcc/ipa-polymorphic-call.c
+++ b/gcc/ipa-polymorphic-call.c
@@ -1554,13 +1554,18 @@ check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
We do not include this analysis in the context analysis itself, because
it needs memory SSA to be fully built and the walk may be expensive.
- So it is not suitable for use withing fold_stmt and similar uses. */
+ So it is not suitable for use withing fold_stmt and similar uses.
+
+ AA_WALK_BUDGET_P, if not NULL, is how statements we should allow
+ walk_aliased_vdefs to examine. The value should be decremented by the
+ number of stetements we examined or set to zero if exhausted. */
bool
ipa_polymorphic_call_context::get_dynamic_type (tree instance,
tree otr_object,
tree otr_type,
- gimple *call)
+ gimple *call,
+ unsigned *aa_walk_budget_p)
{
struct type_change_info tci;
ao_ref ao;
@@ -1723,8 +1728,13 @@ ipa_polymorphic_call_context::get_dynamic_type (tree instance,
tci.speculative = 0;
tci.seen_unanalyzed_store = false;
- walk_aliased_vdefs (&ao, gimple_vuse (stmt), check_stmt_for_type_change,
- &tci, NULL, &function_entry_reached);
+ unsigned aa_walk_budget = 0;
+ if (aa_walk_budget_p)
+ aa_walk_budget = *aa_walk_budget_p + 1;
+
+ int walked
+ = walk_aliased_vdefs (&ao, gimple_vuse (stmt), check_stmt_for_type_change,
+ &tci, NULL, &function_entry_reached, aa_walk_budget);
/* If we did not find any type changing statements, we may still drop
maybe_in_construction flag if the context already have outer type.
@@ -1772,6 +1782,16 @@ ipa_polymorphic_call_context::get_dynamic_type (tree instance,
only if there was dyanmic type store that may affect given variable
(seen_unanalyzed_store) */
+ if (walked < 0)
+ {
+ if (dump_file)
+ fprintf (dump_file, " AA walk budget exhausted.\n");
+ *aa_walk_budget_p = 0;
+ return false;
+ }
+ else if (aa_walk_budget_p)
+ *aa_walk_budget_p -= walked;
+
if (!tci.type_maybe_changed
|| (outer_type
&& !dynamic