aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-inline-analysis.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2019-11-03 17:37:45 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2019-11-03 16:37:45 +0000
commitac6f2e594886e2209446114023ecdff96b0bd7c4 (patch)
tree08ad05645f41cd3331fef1728530f56b00673203 /gcc/ipa-inline-analysis.c
parent360386c7ef1c3fa30de216b1d68ed6a27296fd80 (diff)
downloadgcc-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.c110
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. */