Minor modref optimization and statistics fix
this patch fixes bug in tracking memory stats and also I have noticed that while the pass takes care to stop traking things when things are obviously out of hand it still keeps summaries that have no useful info for loads or stores and also many summaries are just copying const/pure attributes. This patch thus also adds logic to detect if summary is useful and drop it early otherwise. This reduces number of queries to the oracle and saves memory/lto streaming. For cc1plus LTO build (configured with --disable-plugin --enable-checking=release --with-build-config=lto) I now get: Alias oracle query stats: refs_may_alias_p: 62488734 disambiguations, 72660949 queries ref_maybe_used_by_call_p: 128863 disambiguations, 63393551 queries call_may_clobber_ref_p: 16013 disambiguations, 21776 queries nonoverlapping_component_refs_p: 0 disambiguations, 37628 queries nonoverlapping_refs_since_match_p: 19397 disambiguations, 55370 must overlaps, 75516 queries aliasing_component_refs_p: 54741 disambiguations, 752198 queries TBAA oracle: 21632692 disambiguations 52565147 queries 15656420 are in alias set 0 10108172 queries asked about the same object 124 queries asked about the same alias set 0 access volatile 3640460 are dependent in the DAG 1527279 are aritificially in conflict with void * Modref stats: modref use: 5712 disambiguations, 31221 queries modref clobber: 684316 disambiguations, 1010000 queries 1779717 tbaa queries (1.762096 per modref query) PTA query stats: pt_solution_includes: 947334 disambiguations, 13601373 queries pt_solutions_intersect: 1011662 disambiguations, 13139565 queries The number of queries should change, but the number of disambiguations should not. However comparing with stats here https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554309.html I see about 50% drop in clobber disambiguations. There is however same drop in other alias oracle stats. I suppose someting changed in meanwhile on mainline because I was basing that on older tree. I tried to proofread changes between mainline and branch and they seem all quite obvious. This is consistent with what I get on tramp3d: Alias oracle query stats: refs_may_alias_p: 2051320 disambiguations, 2312132 queries ref_maybe_used_by_call_p: 7058 disambiguations, 2088222 queries call_may_clobber_ref_p: 232 disambiguations, 232 queries nonoverlapping_component_refs_p: 0 disambiguations, 4339 queries nonoverlapping_refs_since_match_p: 329 disambiguations, 10200 must overlaps, 10616 queries aliasing_component_refs_p: 857 disambiguations, 34639 queries TBAA oracle: 886768 disambiguations 1670635 queries 131572 are in alias set 0 461689 queries asked about the same object 0 queries asked about the same alias set 0 access volatile 190291 are dependent in the DAG 315 are aritificially in conflict with void * Modref stats: modref use: 430 disambiguations, 1885 queries modref clobber: 9657 disambiguations, 16076 queries 19027 tbaa queries (1.183566 per modref query) PTA query stats: pt_solution_includes: 311756 disambiguations, 524179 queries pt_solutions_intersect: 129689 disambiguations, 415878 queries In both cases the number of disambiguations should be same (queries are not comparable). Bootstrapped/regtested x86_64-linux, comitted. gcc/ChangeLog: 2020-09-23 Jan Hubicka <hubicka@ucw.cz> * ipa-modref.c (modref_summary::lto_useful_p): New member function. (modref_summary::useful_p): New member function. (analyze_function): Drop useless summaries. (modref_write): Skip useless summaries. (pass_ipa_modref::execute): Drop useless summaries. * ipa-modref.h (struct GTY): Declare useful_p and lto_useful_p. * tree-ssa-alias.c (dump_alias_stats): Fix. (modref_may_conflict): Fix stats.
This commit is contained in:
parent
bc909324bd
commit
67c935c823
3 changed files with 48 additions and 10 deletions
|
@ -106,6 +106,36 @@ modref_summary::~modref_summary ()
|
|||
ggc_delete (stores_lto);
|
||||
}
|
||||
|
||||
/* Return true if lto summary is potentially useful for optimization. */
|
||||
|
||||
bool
|
||||
modref_summary::lto_useful_p (int ecf_flags)
|
||||
{
|
||||
if (ecf_flags & (ECF_CONST | ECF_NOVOPS))
|
||||
return false;
|
||||
if (loads_lto && !loads_lto->every_base)
|
||||
return true;
|
||||
if (ecf_flags & ECF_PURE)
|
||||
return false;
|
||||
return stores_lto && !stores_lto->every_base;
|
||||
}
|
||||
|
||||
/* Return true if summary is potentially useful for optimization. */
|
||||
|
||||
bool
|
||||
modref_summary::useful_p (int ecf_flags)
|
||||
{
|
||||
if (ecf_flags & (ECF_CONST | ECF_NOVOPS))
|
||||
return false;
|
||||
if (lto_useful_p (ecf_flags))
|
||||
return true;
|
||||
if (loads && !loads->every_base)
|
||||
return true;
|
||||
if (ecf_flags & ECF_PURE)
|
||||
return false;
|
||||
return stores && !loads->every_base;
|
||||
}
|
||||
|
||||
/* Dump records TT to OUT. */
|
||||
|
||||
static void
|
||||
|
@ -588,8 +618,10 @@ static void
|
|||
analyze_function (function *f, bool ipa)
|
||||
{
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "modref analyzing '%s' (ipa=%i)...\n",
|
||||
function_name (f), ipa);
|
||||
fprintf (dump_file, "modref analyzing '%s' (ipa=%i)%s%s\n",
|
||||
function_name (f), ipa,
|
||||
TREE_READONLY (current_function_decl) ? " (const)" : "",
|
||||
DECL_PURE_P (current_function_decl) ? " (pure)" : "");
|
||||
|
||||
/* Don't analyze this function if it's compiled with -fno-strict-aliasing. */
|
||||
if (!flag_ipa_modref)
|
||||
|
@ -646,6 +678,7 @@ analyze_function (function *f, bool ipa)
|
|||
param_modref_max_refs);
|
||||
}
|
||||
summary->finished = false;
|
||||
int ecf_flags = flags_from_decl_or_type (current_function_decl);
|
||||
|
||||
/* Analyze each statement in each basic block of the function. If the
|
||||
statement cannot be analyzed (for any reason), the entire function cannot
|
||||
|
@ -656,7 +689,8 @@ analyze_function (function *f, bool ipa)
|
|||
gimple_stmt_iterator si;
|
||||
for (si = gsi_after_labels (bb); !gsi_end_p (si); gsi_next (&si))
|
||||
{
|
||||
if (!analyze_stmt (summary, gsi_stmt (si), ipa))
|
||||
if (!analyze_stmt (summary, gsi_stmt (si), ipa)
|
||||
|| !summary->useful_p (ecf_flags))
|
||||
{
|
||||
cgraph_node *fnode = cgraph_node::get (current_function_decl);
|
||||
summaries->remove (fnode);
|
||||
|
@ -927,9 +961,11 @@ modref_write ()
|
|||
{
|
||||
symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
|
||||
cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
|
||||
modref_summary *r;
|
||||
|
||||
if (cnode && cnode->definition && !cnode->alias
|
||||
&& summaries->get (cnode))
|
||||
&& (r = summaries->get (cnode))
|
||||
&& r->lto_useful_p (flags_from_decl_or_type (cnode->decl)))
|
||||
count++;
|
||||
}
|
||||
streamer_write_uhwi (ob, count);
|
||||
|
@ -944,7 +980,7 @@ modref_write ()
|
|||
|
||||
modref_summary *r = summaries->get (cnode);
|
||||
|
||||
if (!r)
|
||||
if (!r || !r->lto_useful_p (flags_from_decl_or_type (cnode->decl)))
|
||||
continue;
|
||||
|
||||
streamer_write_uhwi (ob, lto_symtab_encoder_encode (encoder, cnode));
|
||||
|
@ -1233,7 +1269,7 @@ unsigned int pass_ipa_modref::execute (function *)
|
|||
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " Call to %s\n",
|
||||
cur->dump_name ());
|
||||
callee_edge->callee->dump_name ());
|
||||
|
||||
/* We can not safely optimize based on summary of callee if it
|
||||
does not always bind to current def: it is possible that
|
||||
|
@ -1278,7 +1314,7 @@ unsigned int pass_ipa_modref::execute (function *)
|
|||
its_hopeless = true;
|
||||
if (dump_file && avail <= AVAIL_INTERPOSABLE)
|
||||
fprintf (dump_file, " Call target interposable"
|
||||
"or not available\n");
|
||||
" or not available\n");
|
||||
else if (dump_file)
|
||||
fprintf (dump_file, " No call target summary\n");
|
||||
break;
|
||||
|
|
|
@ -41,6 +41,8 @@ struct GTY(()) modref_summary
|
|||
modref_summary ();
|
||||
~modref_summary ();
|
||||
void dump (FILE *);
|
||||
bool useful_p (int ecf_flags);
|
||||
bool lto_useful_p (int ecf_flags);
|
||||
};
|
||||
|
||||
modref_summary *get_modref_function_summary (cgraph_node *func);
|
||||
|
|
|
@ -170,7 +170,7 @@ dump_alias_stats (FILE *s)
|
|||
fprintf (s, " modref clobber: "
|
||||
HOST_WIDE_INT_PRINT_DEC" disambiguations, "
|
||||
HOST_WIDE_INT_PRINT_DEC" queries\n "
|
||||
HOST_WIDE_INT_PRINT_DEC" tbaa querries (%f per modref querry)\n",
|
||||
HOST_WIDE_INT_PRINT_DEC" tbaa queries (%f per modref query)\n",
|
||||
alias_stats.modref_clobber_no_alias,
|
||||
alias_stats.modref_clobber_no_alias
|
||||
+ alias_stats.modref_clobber_may_alias,
|
||||
|
@ -2448,9 +2448,9 @@ modref_may_conflict (modref_tree <alias_set_type> *tt, ao_ref *ref, bool tbaa_p)
|
|||
|
||||
if (tbaa_p && flag_strict_aliasing)
|
||||
{
|
||||
alias_stats.modref_tests++;
|
||||
if (!alias_sets_conflict_p (base_set, base_node->base))
|
||||
continue;
|
||||
alias_stats.modref_tests++;
|
||||
num_tests++;
|
||||
}
|
||||
else
|
||||
|
@ -2465,9 +2465,9 @@ modref_may_conflict (modref_tree <alias_set_type> *tt, ao_ref *ref, bool tbaa_p)
|
|||
return true;
|
||||
if (!flag_strict_aliasing)
|
||||
return true;
|
||||
alias_stats.modref_tests++;
|
||||
if (alias_sets_conflict_p (ref_set, ref_node->ref))
|
||||
return true;
|
||||
alias_stats.modref_tests++;
|
||||
num_tests++;
|
||||
if (num_tests >= max_tests)
|
||||
return true;
|
||||
|
|
Loading…
Add table
Reference in a new issue