diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2019-11-03 17:37:45 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2019-11-03 16:37:45 +0000 |
commit | ac6f2e594886e2209446114023ecdff96b0bd7c4 (patch) | |
tree | 08ad05645f41cd3331fef1728530f56b00673203 /gcc/ipa-inline-analysis.c | |
parent | 360386c7ef1c3fa30de216b1d68ed6a27296fd80 (diff) | |
download | gcc-ac6f2e594886e2209446114023ecdff96b0bd7c4.zip gcc-ac6f2e594886e2209446114023ecdff96b0bd7c4.tar.gz gcc-ac6f2e594886e2209446114023ecdff96b0bd7c4.tar.bz2 |
ipa-fnsummary.c (ipa_call_context::duplicate_from): New member function.
* ipa-fnsummary.c (ipa_call_context::duplicate_from): New
member function.
(ipa_call_context::release): Add ALL parameter.
(ipa_call_context::equal_to): New member function.
* ipa-fnsummary.h (ipa_call_context): Add empty constructor;
duplicate_form, release, equal_to and exists_p member functoins.
* ipa-inline-analysis.c (node_context_cache_entry): New
class.
(node_context_summary): Likewise.
(node_context_cache, node_context_cache_hit, node_context_cache_miss,
node_context_clear): New static vars.
(initialize_growth_caches): New function.
(free_growth_caches): Also delete node_context_cache; output stats.
(do_estimate_edge_time): Cache contexts.
(reset_node_cache): New function.
* ipa-inline.c (reset_edge_caches): Reset also node cache.
(inline_small_functions): Initialize growth caches.
* ipa-inline.h (reset_node_cache, initialize_growth_caches):
Declare.
* ipa-predicate.h (inline_param_summary::equal_to): New.
* ipa-prop.c (ipa_agg_jf_item::equal_to): New.
* ipa-prop.h (ipa_agg_jf_item): Declare equal_to member function.
(ipa_agg_jump_function): Implement equal_to member function.
From-SVN: r277757
Diffstat (limited to 'gcc/ipa-inline-analysis.c')
-rw-r--r-- | gcc/ipa-inline-analysis.c | 110 |
1 files changed, 105 insertions, 5 deletions
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 5c00c0d..4363105 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -53,6 +53,48 @@ along with GCC; see the file COPYING3. If not see /* Cached node/edge growths. */ call_summary<edge_growth_cache_entry *> *edge_growth_cache = NULL; +/* The context cache remembers estimated time/size and hints for given + ipa_call_context of a call. */ +class node_context_cache_entry +{ +public: + ipa_call_context ctx; + sreal time, nonspec_time; + int size; + ipa_hints hints; + + node_context_cache_entry () + : ctx () + { + } + ~node_context_cache_entry () + { + ctx.release (); + } +}; + +/* At the moment we implement primitive single entry LRU cache. */ +class node_context_summary +{ +public: + node_context_cache_entry entry; + + node_context_summary () + : entry () + { + } + ~node_context_summary () + { + } +}; + +/* Summary holding the context cache. */ +static fast_function_summary <node_context_summary *, va_heap> + *node_context_cache = NULL; +/* Statistics about the context cache effectivity. */ +static long node_context_cache_hit, node_context_cache_miss, + node_context_cache_clear; + /* Give initial reasons why inlining would fail on EDGE. This gets either nullified or usually overwritten by more precise reasons later. */ @@ -77,6 +119,16 @@ initialize_inline_failed (struct cgraph_edge *e) == CIF_FINAL_ERROR); } +/* Allocate edge growth caches. */ + +void +initialize_growth_caches () +{ + edge_growth_cache + = new call_summary<edge_growth_cache_entry *> (symtab, false); + node_context_cache + = new fast_function_summary<node_context_summary *, va_heap> (symtab); +} /* Free growth caches. */ @@ -84,7 +136,17 @@ void free_growth_caches (void) { delete edge_growth_cache; + delete node_context_cache; edge_growth_cache = NULL; + node_context_cache = NULL; + if (dump_file) + fprintf (dump_file, "node context cache: %li hits, %li misses," + " %li initializations\n", + node_context_cache_hit, node_context_cache_miss, + node_context_cache_clear); + node_context_cache_hit = 0; + node_context_cache_miss = 0; + node_context_cache_clear = 0; } /* Return hints derrived from EDGE. */ @@ -129,7 +191,7 @@ do_estimate_edge_time (struct cgraph_edge *edge) vec<ipa_polymorphic_call_context> known_contexts; vec<ipa_agg_jump_function_p> known_aggs; class ipa_call_summary *es = ipa_call_summaries->get (edge); - int min_size; + int min_size = -1; callee = edge->callee->ultimate_alias_target (); @@ -139,8 +201,37 @@ do_estimate_edge_time (struct cgraph_edge *edge) &known_contexts, &known_aggs); ipa_call_context ctx (callee, clause, nonspec_clause, known_vals, known_contexts, known_aggs, es->param); - ctx.estimate_size_and_time (&size, &min_size, - &time, &nonspec_time, &hints); + if (node_context_cache != NULL) + { + node_context_summary *e = node_context_cache->get_create (callee); + if (e->entry.ctx.equal_to (ctx)) + { + node_context_cache_hit++; + size = e->entry.size; + time = e->entry.time; + nonspec_time = e->entry.nonspec_time; + hints = e->entry.hints; + } + else + { + if (e->entry.ctx.exists_p ()) + node_context_cache_miss++; + else + node_context_cache_clear++; + e->entry.ctx.release (true); + e->entry.ctx = ctx; + ctx.estimate_size_and_time (&size, &min_size, + &time, &nonspec_time, &hints); + e->entry.size = size; + e->entry.time = time; + e->entry.nonspec_time = nonspec_time; + e->entry.hints = hints; + e->entry.ctx.duplicate_from (ctx); + } + } + else + ctx.estimate_size_and_time (&size, &min_size, + &time, &nonspec_time, &hints); /* When we have profile feedback, we can quite safely identify hot edges and for those we disable size limits. Don't do that when @@ -160,8 +251,9 @@ do_estimate_edge_time (struct cgraph_edge *edge) /* When caching, update the cache entry. */ if (edge_growth_cache != NULL) { - ipa_fn_summaries->get (edge->callee->function_symbol ())->min_size - = min_size; + if (min_size >= 0) + ipa_fn_summaries->get (edge->callee->function_symbol ())->min_size + = min_size; edge_growth_cache_entry *entry = edge_growth_cache->get_create (edge); entry->time = time; @@ -174,6 +266,14 @@ do_estimate_edge_time (struct cgraph_edge *edge) return time; } +/* Reset cache for NODE. + This must be done each time NODE body is modified. */ +void +reset_node_cache (struct cgraph_node *node) +{ + if (node_context_cache) + node_context_cache->remove (node); +} /* Return estimated callee growth after inlining EDGE. Only to be called via estimate_edge_size. */ |