diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ipa-modref.c | 50 | ||||
-rw-r--r-- | gcc/ipa-modref.h | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 6 |
3 files changed, 48 insertions, 10 deletions
diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c index fe277d8..3e65159 100644 --- a/gcc/ipa-modref.c +++ b/gcc/ipa-modref.c @@ -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; diff --git a/gcc/ipa-modref.h b/gcc/ipa-modref.h index 6cccdfe..152e715 100644 --- a/gcc/ipa-modref.h +++ b/gcc/ipa-modref.h @@ -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); diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index be4d446..18ff529 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -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; |