[12/14] Port edge_growth_cache to call_summary.

Message ID aaed46a074ebfd9f13b97529b43ee3c42f3bfbe7.1526551813.git.mliska@suse.cz
State New
Headers show
Series
  • Finish transition of {symbol,call}_summary.
Related show

Commit Message

Martin Liška April 23, 2018, 11:44 a.m.
gcc/ChangeLog:

2018-04-24  Martin Liska  <mliska@suse.cz>

	* ipa-inline-analysis.c (inline_edge_removal_hook): Remove.
	(initialize_growth_caches): Remove.
	(free_growth_caches): Likewise.
	(do_estimate_edge_time): Use edge_growth_cache.
	(do_estimate_edge_size): Likewise.
	(do_estimate_edge_hints): Likewise.
	* ipa-inline.c (reset_edge_caches): Likewise.
	(recursive_inlining): Likewise.
	(inline_small_functions): Likewise.
	* ipa-inline.h (initialize_growth_caches): Remove.
	(estimate_edge_size): Likewise.
	(estimate_edge_time): Likewise.
	(estimate_edge_hints): Likewise.
	(reset_edge_growth_cache): Likewise.
	* symbol-summary.h (call_summary::remove): New method.
---
 gcc/ipa-inline-analysis.c | 57 ++++++++++++-----------------------------------
 gcc/ipa-inline.c          | 31 ++++++++++++++++----------
 gcc/ipa-inline.h          | 44 ++++++++++++++----------------------
 gcc/symbol-summary.h      | 12 ++++++++++
 4 files changed, 62 insertions(+), 82 deletions(-)

Comments

Jan Hubicka June 7, 2018, 12:58 p.m. | #1
> 

> gcc/ChangeLog:

> 

> 2018-04-24  Martin Liska  <mliska@suse.cz>

> 

> 	* ipa-inline-analysis.c (inline_edge_removal_hook): Remove.

> 	(initialize_growth_caches): Remove.

> 	(free_growth_caches): Likewise.

> 	(do_estimate_edge_time): Use edge_growth_cache.

> 	(do_estimate_edge_size): Likewise.

> 	(do_estimate_edge_hints): Likewise.

> 	* ipa-inline.c (reset_edge_caches): Likewise.

> 	(recursive_inlining): Likewise.

> 	(inline_small_functions): Likewise.

> 	* ipa-inline.h (initialize_growth_caches): Remove.

> 	(estimate_edge_size): Likewise.

> 	(estimate_edge_time): Likewise.

> 	(estimate_edge_hints): Likewise.

> 	(reset_edge_growth_cache): Likewise.

> 	* symbol-summary.h (call_summary::remove): New method.


OK. I wonder if you did some performance statistics for WPA times with the
patchset?

Honza

Patch

diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 2e30a6d15ba..9a7267395ea 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -51,9 +51,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "gimplify.h"
 
 /* Cached node/edge growths.  */
-vec<edge_growth_cache_entry> edge_growth_cache;
-static struct cgraph_edge_hook_list *edge_removal_hook_holder;
-
+call_summary<edge_growth_cache_entry *> *edge_growth_cache = NULL;
 
 /* Give initial reasons why inlining would fail on EDGE.  This gets either
    nullified or usually overwritten by more precise reasons later.  */
@@ -80,40 +78,13 @@  initialize_inline_failed (struct cgraph_edge *e)
 }
 
 
-/* Keep edge cache consistent across edge removal.  */
-
-static void
-inline_edge_removal_hook (struct cgraph_edge *edge,
-			  void *data ATTRIBUTE_UNUSED)
-{
-  reset_edge_growth_cache (edge);
-}
-
-
-/* Initialize growth caches.  */
-
-void
-initialize_growth_caches (void)
-{
-  if (!edge_removal_hook_holder)
-    edge_removal_hook_holder =
-      symtab->add_edge_removal_hook (&inline_edge_removal_hook, NULL);
-  if (symtab->edges_max_uid)
-    edge_growth_cache.safe_grow_cleared (symtab->edges_max_uid);
-}
-
-
 /* Free growth caches.  */
 
 void
 free_growth_caches (void)
 {
-  if (edge_removal_hook_holder)
-    {
-      symtab->remove_edge_removal_hook (edge_removal_hook_holder);
-      edge_removal_hook_holder = NULL;
-    }
-  edge_growth_cache.release ();
+  delete edge_growth_cache;
+  edge_growth_cache = NULL;
 }
 
 /* Return hints derrived from EDGE.   */
@@ -188,17 +159,17 @@  do_estimate_edge_time (struct cgraph_edge *edge)
   gcc_checking_assert (time >= 0);
 
   /* When caching, update the cache entry.  */
-  if (edge_growth_cache.exists ())
+  if (edge_growth_cache != NULL)
     {
       ipa_fn_summaries->get_create (edge->callee)->min_size = min_size;
-      if ((int) edge_growth_cache.length () <= edge->uid)
-	edge_growth_cache.safe_grow_cleared (symtab->edges_max_uid);
-      edge_growth_cache[edge->uid].time = time;
-      edge_growth_cache[edge->uid].nonspec_time = nonspec_time;
+      edge_growth_cache_entry *entry
+	= edge_growth_cache->get_create (edge);
+      entry->time = time;
+      entry->nonspec_time = nonspec_time;
 
-      edge_growth_cache[edge->uid].size = size + (size >= 0);
+      entry->size = size + (size >= 0);
       hints |= simple_edge_hints (edge);
-      edge_growth_cache[edge->uid].hints = hints + 1;
+      entry->hints = hints + 1;
     }
   return time;
 }
@@ -219,10 +190,10 @@  do_estimate_edge_size (struct cgraph_edge *edge)
 
   /* When we do caching, use do_estimate_edge_time to populate the entry.  */
 
-  if (edge_growth_cache.exists ())
+  if (edge_growth_cache != NULL)
     {
       do_estimate_edge_time (edge);
-      size = edge_growth_cache[edge->uid].size;
+      size = edge_growth_cache->get (edge)->size;
       gcc_checking_assert (size);
       return size - (size > 0);
     }
@@ -260,10 +231,10 @@  do_estimate_edge_hints (struct cgraph_edge *edge)
 
   /* When we do caching, use do_estimate_edge_time to populate the entry.  */
 
-  if (edge_growth_cache.exists ())
+  if (edge_growth_cache != NULL)
     {
       do_estimate_edge_time (edge);
-      hints = edge_growth_cache[edge->uid].hints;
+      hints = edge_growth_cache->get (edge)->hints;
       gcc_checking_assert (hints);
       return hints - 1;
     }
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 12f5ebfd582..97164716af8 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -1287,9 +1287,10 @@  reset_edge_caches (struct cgraph_node *node)
   if (where->global.inlined_to)
     where = where->global.inlined_to;
 
-  for (edge = where->callers; edge; edge = edge->next_caller)
-    if (edge->inline_failed)
-      reset_edge_growth_cache (edge);
+  if (edge_growth_cache != NULL)
+    for (edge = where->callers; edge; edge = edge->next_caller)
+      if (edge->inline_failed)
+	edge_growth_cache->remove (edge);
 
   FOR_EACH_ALIAS (where, ref)
     reset_edge_caches (dyn_cast <cgraph_node *> (ref->referring));
@@ -1302,8 +1303,8 @@  reset_edge_caches (struct cgraph_node *node)
       e = e->callee->callees;
     else
       {
-	if (e->inline_failed)
-	  reset_edge_growth_cache (e);
+	if (edge_growth_cache != NULL && e->inline_failed)
+	  edge_growth_cache->remove (e);
 	if (e->next_callee)
 	  e = e->next_callee;
 	else
@@ -1496,13 +1497,15 @@  recursive_inlining (struct cgraph_edge *edge,
       if (master_clone)
 	{
 	  curr->redirect_callee (master_clone);
-	  reset_edge_growth_cache (curr);
+	  if (edge_growth_cache != NULL)
+	    edge_growth_cache->remove (curr);
 	}
 
       if (estimate_size_after_inlining (node, curr) > limit)
 	{
 	  curr->redirect_callee (dest);
-	  reset_edge_growth_cache (curr);
+	  if (edge_growth_cache != NULL)
+	    edge_growth_cache->remove (curr);
 	  break;
 	}
 
@@ -1516,7 +1519,8 @@  recursive_inlining (struct cgraph_edge *edge,
       if (!want_inline_self_recursive_call_p (curr, node, false, depth))
 	{
 	  curr->redirect_callee (dest);
-	  reset_edge_growth_cache (curr);
+	  if (edge_growth_cache != NULL)
+	    edge_growth_cache->remove (curr);
 	  continue;
 	}
 
@@ -1541,7 +1545,8 @@  recursive_inlining (struct cgraph_edge *edge,
 	    if (!e->inline_failed)
 	      clone_inlined_nodes (e, true, false, NULL);
 	  curr->redirect_callee (master_clone);
-          reset_edge_growth_cache (curr);
+	  if (edge_growth_cache != NULL)
+	    edge_growth_cache->remove (curr);
 	}
 
       inline_call (curr, false, new_edges, &overall_size, true);
@@ -1798,7 +1803,8 @@  inline_small_functions (void)
 	  max_count = max_count.max (edge->count.ipa ());
       }
   ipa_free_postorder_info ();
-  initialize_growth_caches ();
+  edge_growth_cache
+    = new call_summary<edge_growth_cache_entry *> (symtab, false);
 
   if (dump_file)
     fprintf (dump_file,
@@ -1892,7 +1898,8 @@  inline_small_functions (void)
 	  sreal old_time_est = estimate_edge_time (edge);
 	  int old_hints_est = estimate_edge_hints (edge);
 
-	  reset_edge_growth_cache (edge);
+	  if (edge_growth_cache != NULL)
+	    edge_growth_cache->remove (edge);
 	  gcc_assert (old_size_est == estimate_edge_size (edge));
 	  gcc_assert (old_time_est == estimate_edge_time (edge));
 	  /* FIXME:
@@ -1906,7 +1913,7 @@  inline_small_functions (void)
 	     for given invocation but that will be better done once whole
 	     code is converted to sreals.  Disable for now and revert to "wrong"
 	     value so enable/disable checking paths agree.  */
-	  edge_growth_cache[edge->uid].hints = old_hints_est + 1;
+	  edge_growth_cache->get (edge)->hints = old_hints_est + 1;
 
 	  /* When updating the edge costs, we only decrease badness in the keys.
 	     Increases of badness are handled lazilly; when we see key with out
diff --git a/gcc/ipa-inline.h b/gcc/ipa-inline.h
index 06bd38e551e..15825bca820 100644
--- a/gcc/ipa-inline.h
+++ b/gcc/ipa-inline.h
@@ -38,7 +38,7 @@  struct edge_growth_cache_entry
       hints (hints) {}
 };
 
-extern vec<edge_growth_cache_entry> edge_growth_cache;
+extern call_summary<edge_growth_cache_entry *> *edge_growth_cache;
 
 /* In ipa-inline-analysis.c  */
 int estimate_size_after_inlining (struct cgraph_node *, struct cgraph_edge *);
@@ -47,7 +47,6 @@  bool growth_likely_positive (struct cgraph_node *, int);
 int do_estimate_edge_size (struct cgraph_edge *edge);
 sreal do_estimate_edge_time (struct cgraph_edge *edge);
 ipa_hints do_estimate_edge_hints (struct cgraph_edge *edge);
-void initialize_growth_caches (void);
 void free_growth_caches (void);
 
 /* In ipa-inline.c  */
@@ -69,11 +68,12 @@  extern int nfunctions_inlined;
 static inline int
 estimate_edge_size (struct cgraph_edge *edge)
 {
-  int ret;
-  if ((int)edge_growth_cache.length () <= edge->uid
-      || !(ret = edge_growth_cache[edge->uid].size))
+  edge_growth_cache_entry *entry;
+  if (edge_growth_cache == NULL
+      || (entry = edge_growth_cache->get (edge)) == NULL
+      || entry->size == 0)
     return do_estimate_edge_size (edge);
-  return ret - (ret > 0);
+  return entry->size - (entry->size > 0);
 }
 
 /* Return estimated callee growth after inlining EDGE.  */
@@ -92,13 +92,14 @@  estimate_edge_growth (struct cgraph_edge *edge)
 static inline sreal
 estimate_edge_time (struct cgraph_edge *edge, sreal *nonspec_time = NULL)
 {
-  sreal ret;
-  if ((int)edge_growth_cache.length () <= edge->uid
-      || !edge_growth_cache[edge->uid].size)
+  edge_growth_cache_entry *entry;
+  if (edge_growth_cache == NULL
+      || (entry = edge_growth_cache->get (edge)) == NULL
+      || entry->time == 0)
     return do_estimate_edge_time (edge);
   if (nonspec_time)
-    *nonspec_time = edge_growth_cache[edge->uid].nonspec_time;
-  return edge_growth_cache[edge->uid].time;
+    *nonspec_time = edge_growth_cache->get (edge)->nonspec_time;
+  return entry->time;
 }
 
 
@@ -108,23 +109,12 @@  estimate_edge_time (struct cgraph_edge *edge, sreal *nonspec_time = NULL)
 static inline ipa_hints
 estimate_edge_hints (struct cgraph_edge *edge)
 {
-  ipa_hints ret;
-  if ((int)edge_growth_cache.length () <= edge->uid
-      || !(ret = edge_growth_cache[edge->uid].hints))
+  edge_growth_cache_entry *entry;
+  if (edge_growth_cache == NULL
+      || (entry = edge_growth_cache->get (edge)) == NULL
+      || entry->hints == 0)
     return do_estimate_edge_hints (edge);
-  return ret - 1;
-}
-
-/* Reset cached value for EDGE.  */
-
-static inline void
-reset_edge_growth_cache (struct cgraph_edge *edge)
-{
-  if ((int)edge_growth_cache.length () > edge->uid)
-    {
-      struct edge_growth_cache_entry zero (0, 0, 0, 0);
-      edge_growth_cache[edge->uid] = zero;
-    }
+  return entry->hints - 1;
 }
 
 #endif /* GCC_IPA_INLINE_H */
diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h
index 4896c97a1cd..12e50201125 100644
--- a/gcc/symbol-summary.h
+++ b/gcc/symbol-summary.h
@@ -384,6 +384,18 @@  public:
     return get (hashable_uid (edge), false);
   }
 
+  /* Remove edge from summary.  */
+  void remove (cgraph_edge *edge)
+  {
+    int uid = hashable_uid (edge);
+    T **v = m_map.get (uid);
+    if (v)
+      {
+	m_map.remove (uid);
+	release (*v);
+      }
+  }
+
   /* Return number of elements handled by data structure.  */
   size_t elements ()
   {