middle-end/38474 - fix alias walk budget accounting in IPA analysis

The walk_aliased_vdef calls do not update the walking budget until
it is hit by a single call (and then in one case it resumes with
no limit at all).  The following rectifies this in multiple places.
It also makes the updates more consistend and fixes
determine_known_aggregate_parts to account its own alias queries.

2021-02-12  Richard Biener  <rguenther@suse.de>

	PR middle-end/38474
	* ipa-fnsummary.c (unmodified_parm_1): Only walk when
	fbi->aa_walk_budget is bigger than zero.  Update
	fbi->aa_walk_budget.
	(param_change_prob): Likewise.
	* ipa-prop.c (detect_type_change_from_memory_writes):
	Properly account walk_aliased_vdefs.
	(parm_preserved_before_stmt_p): Canonicalize updates.
	(parm_ref_data_preserved_p): Likewise.
	(parm_ref_data_pass_through_p): Likewise.
	(determine_known_aggregate_parts): Account own alias queries.
This commit is contained in:
Richard Biener 2021-02-12 11:13:36 +01:00
parent bc6087c575
commit 6cc886bf42
2 changed files with 28 additions and 14 deletions

View File

@ -1197,7 +1197,8 @@ unmodified_parm_1 (ipa_func_body_info *fbi, gimple *stmt, tree op,
return SSA_NAME_VAR (op);
}
/* Non-SSA parm reference? */
if (TREE_CODE (op) == PARM_DECL)
if (TREE_CODE (op) == PARM_DECL
&& fbi->aa_walk_budget > 0)
{
bool modified = false;
@ -1205,12 +1206,13 @@ unmodified_parm_1 (ipa_func_body_info *fbi, gimple *stmt, tree op,
ao_ref_init (&refd, op);
int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt),
mark_modified, &modified, NULL, NULL,
fbi->aa_walk_budget + 1);
fbi->aa_walk_budget);
if (walked < 0)
{
fbi->aa_walk_budget = 0;
return NULL_TREE;
}
fbi->aa_walk_budget -= walked;
if (!modified)
{
if (size_p)
@ -2240,7 +2242,7 @@ param_change_prob (ipa_func_body_info *fbi, gimple *stmt, int i)
if (init != error_mark_node)
return 0;
if (!bb->count.nonzero_p ())
if (!bb->count.nonzero_p () || fbi->aa_walk_budget == 0)
return REG_BR_PROB_BASE;
if (dump_file)
{
@ -2255,8 +2257,12 @@ param_change_prob (ipa_func_body_info *fbi, gimple *stmt, int i)
int walked
= walk_aliased_vdefs (&refd, gimple_vuse (stmt), record_modified, &info,
NULL, NULL, fbi->aa_walk_budget);
if (walked > 0)
fbi->aa_walk_budget -= walked;
if (walked < 0 || bitmap_bit_p (info.bb_set, bb->index))
{
if (walked < 0)
fbi->aa_walk_budget = 0;
if (dump_file)
{
if (walked < 0)

View File

@ -803,6 +803,9 @@ detect_type_change_from_memory_writes (ipa_func_body_info *fbi, tree arg,
|| !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))))
return true;
if (fbi->aa_walk_budget == 0)
return false;
ao_ref_init (&ao, arg);
ao.base = base;
ao.offset = offset;
@ -815,7 +818,11 @@ detect_type_change_from_memory_writes (ipa_func_body_info *fbi, tree arg,
int walked
= walk_aliased_vdefs (&ao, gimple_vuse (call), check_stmt_for_type_change,
&tci, NULL, NULL, fbi->aa_walk_budget + 1);
&tci, NULL, NULL, fbi->aa_walk_budget);
if (walked >= 0)
fbi->aa_walk_budget -= walked;
else
fbi->aa_walk_budget = 0;
if (walked >= 0 && !tci.type_maybe_changed)
return false;
@ -948,21 +955,20 @@ parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int index,
gcc_checking_assert (fbi);
paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
if (paa->parm_modified)
if (paa->parm_modified || fbi->aa_walk_budget == 0)
return false;
gcc_checking_assert (gimple_vuse (stmt) != NULL_TREE);
ao_ref_init (&refd, parm_load);
int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
&modified, NULL, NULL,
fbi->aa_walk_budget + 1);
fbi->aa_walk_budget);
if (walked < 0)
{
modified = true;
if (fbi)
fbi->aa_walk_budget = 0;
fbi->aa_walk_budget = 0;
}
else if (fbi)
else
fbi->aa_walk_budget -= walked;
if (paa && modified)
paa->parm_modified = true;
@ -1010,14 +1016,14 @@ parm_ref_data_preserved_p (struct ipa_func_body_info *fbi,
gcc_checking_assert (fbi);
paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
if (paa->ref_modified)
if (paa->ref_modified || fbi->aa_walk_budget == 0)
return false;
gcc_checking_assert (gimple_vuse (stmt));
ao_ref_init (&refd, ref);
int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
&modified, NULL, NULL,
fbi->aa_walk_budget + 1);
fbi->aa_walk_budget);
if (walked < 0)
{
modified = true;
@ -1051,13 +1057,13 @@ parm_ref_data_pass_through_p (struct ipa_func_body_info *fbi, int index,
struct ipa_param_aa_status *paa = parm_bb_aa_status_for_bb (fbi,
gimple_bb (call),
index);
if (paa->pt_modified)
if (paa->pt_modified || fbi->aa_walk_budget == 0)
return false;
ao_ref_init_from_ptr_and_size (&refd, parm, NULL_TREE);
int walked = walk_aliased_vdefs (&refd, gimple_vuse (call), mark_modified,
&modified, NULL, NULL,
fbi->aa_walk_budget + 1);
fbi->aa_walk_budget);
if (walked < 0)
{
fbi->aa_walk_budget = 0;
@ -2040,7 +2046,8 @@ determine_known_aggregate_parts (struct ipa_func_body_info *fbi,
of the aggregate is affected by definition of the virtual operand, it
builds a sorted linked list of ipa_agg_jf_list describing that. */
for (tree dom_vuse = gimple_vuse (call); dom_vuse;)
for (tree dom_vuse = gimple_vuse (call);
dom_vuse && fbi->aa_walk_budget > 0;)
{
gimple *stmt = SSA_NAME_DEF_STMT (dom_vuse);
@ -2052,6 +2059,7 @@ determine_known_aggregate_parts (struct ipa_func_body_info *fbi,
continue;
}
fbi->aa_walk_budget--;
if (stmt_may_clobber_ref_p_1 (stmt, &r))
{
struct ipa_known_agg_contents_list *content