This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR 64481 (bootstrap miscompare)


Hi,
in December I conditoinally disabled expensive sanity checking in inliner.
This triggeres bootstrap miscompare because caches are getting out of sync.
This patch fixes the problem found by sanity check - the node growth cache
was removed from use in badness calculation by Richard a while ago, but the
cache itself remained while the updating logic was dropped.  This of course
leads to somewhat randomish results.

The other problem fixed is that in some cases we forget to walk through aliases
to get into the callee.

Bootstrapped/regtested x86_64-linux, comitted.
	PR ipa/64481
	* ipa-inline-analysis.c (node_growth_cache): Remove.
	(initialize_growth_caches): Do not initialize it.
	(free_growth_caches): Do not free it.
	(do_estimate_growth): Rename to ...
	(estimate_growth): ... this one; drop growth cache code.
	(growth_likely_positive): Always go the heuristics way.
	* ipa-inline.c (can_inline_edge_p): Walk through aliases.
	(reset_edge_caches): Do not reset node growth.
	(heap_edge_removal_hook): Do not maintain cache.
	(inline_small_functions): Likewise; strenghten sanity check.
	(ipa_inline): Do not maintain caches.
	* ipa-inline.h (node_growth_cache): Remove.
	(do_estimate_growth): Remove to ...
	(estimate_growth): this one; remove inline version.
	(reset_node_growth_cache): Remove.
Index: ipa-inline-analysis.c
===================================================================
--- ipa-inline-analysis.c	(revision 219571)
+++ ipa-inline-analysis.c	(working copy)
@@ -167,7 +167,6 @@ function_summary <inline_summary *> *inl
 vec<inline_edge_summary_t> inline_edge_summary_vec;
 
 /* Cached node/edge growths.  */
-vec<int> node_growth_cache;
 vec<edge_growth_cache_entry> edge_growth_cache;
 
 /* Edge predicates goes here.  */
@@ -1341,8 +1340,6 @@ initialize_growth_caches (void)
 {
   if (symtab->edges_max_uid)
     edge_growth_cache.safe_grow_cleared (symtab->edges_max_uid);
-  if (symtab->cgraph_max_uid)
-    node_growth_cache.safe_grow_cleared (symtab->cgraph_max_uid);
 }
 
 
@@ -1352,7 +1349,6 @@ void
 free_growth_caches (void)
 {
   edge_growth_cache.release ();
-  node_growth_cache.release ();
 }
 
 
@@ -3931,7 +3927,7 @@ do_estimate_growth_1 (struct cgraph_node
 /* Estimate the growth caused by inlining NODE into all callees.  */
 
 int
-do_estimate_growth (struct cgraph_node *node)
+estimate_growth (struct cgraph_node *node)
 {
   struct growth_data d = { node, 0, false };
   struct inline_summary *info = inline_summaries->get (node);
@@ -3960,12 +3956,6 @@ do_estimate_growth (struct cgraph_node *
 		     + 50) / 100;
     }
 
-  if (node_growth_cache.exists ())
-    {
-      if ((int) node_growth_cache.length () <= node->uid)
-	node_growth_cache.safe_grow_cleared (symtab->cgraph_max_uid);
-      node_growth_cache[node->uid] = d.growth + (d.growth >= 0);
-    }
   return d.growth;
 }
 
@@ -3979,7 +3969,6 @@ bool
 growth_likely_positive (struct cgraph_node *node, int edge_growth ATTRIBUTE_UNUSED)
 {
   int max_callers;
-  int ret;
   struct cgraph_edge *e;
   gcc_checking_assert (edge_growth > 0);
 
@@ -3999,10 +3988,6 @@ growth_likely_positive (struct cgraph_no
       || !node->can_remove_if_no_direct_calls_p ())
     return true;
 
-  /* If there is cached value, just go ahead.  */
-  if ((int)node_growth_cache.length () > node->uid
-      && (ret = node_growth_cache[node->uid]))
-    return ret > 0;
   if (!node->will_be_removed_from_program_if_no_direct_calls_p ()
       && (!DECL_COMDAT (node->decl)
 	  || !node->can_remove_if_no_direct_calls_p ()))
Index: ipa-inline.c
===================================================================
--- ipa-inline.c	(revision 219571)
+++ ipa-inline.c	(working copy)
@@ -388,11 +388,11 @@ can_inline_edge_p (struct cgraph_edge *e
   else if (caller_tree != callee_tree)
     {
       if (((opt_for_fn (e->caller->decl, optimize)
-	    > opt_for_fn (e->callee->decl, optimize))
+	    > opt_for_fn (callee->decl, optimize))
 	    || (opt_for_fn (e->caller->decl, optimize_size)
-		!= opt_for_fn (e->callee->decl, optimize_size)))
+		!= opt_for_fn (callee->decl, optimize_size)))
 	  /* gcc.dg/pr43564.c.  Look at forced inline even in -O0.  */
-	  && !DECL_DISREGARD_INLINE_LIMITS (e->callee->decl))
+	  && !DECL_DISREGARD_INLINE_LIMITS (callee->decl))
 	{
 	  e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
 	  inlinable = false;
@@ -1095,9 +1095,6 @@ reset_edge_caches (struct cgraph_node *n
   if (where->global.inlined_to)
     where = where->global.inlined_to;
 
-  /* WHERE body size has changed, the cached growth is invalid.  */
-  reset_node_growth_cache (where);
-
   for (edge = where->callers; edge; edge = edge->next_caller)
     if (edge->inline_failed)
       reset_edge_growth_cache (edge);
@@ -1428,8 +1425,6 @@ add_new_edges_to_heap (edge_heap_t *heap
 static void
 heap_edge_removal_hook (struct cgraph_edge *e, void *data)
 {
-  if (e->callee)
-    reset_node_growth_cache (e->callee);
   if (e->aux)
     {
       ((edge_heap_t *)data)->delete_node ((edge_heap_node_t *)e->aux);
@@ -1622,7 +1617,6 @@ inline_small_functions (void)
 	  struct cgraph_node *where = node->global.inlined_to
 				      ? node->global.inlined_to : node;
 	  inline_update_overall_summary (where);
-          reset_node_growth_cache (where);
 	  reset_edge_caches (where);
           update_caller_keys (&edge_heap, where,
 			      updated_nodes, NULL);
@@ -1653,8 +1647,15 @@ inline_small_functions (void)
 #ifdef ENABLE_CHECKING
       /* Be sure that caches are maintained consistent.  */
       sreal cached_badness = edge_badness (edge, false);
+ 
+      int old_size_est = estimate_edge_size (edge);
+      int old_time_est = estimate_edge_time (edge);
+      int old_hints_est = estimate_edge_hints (edge);
+
       reset_edge_growth_cache (edge);
-      reset_node_growth_cache (edge->callee);
+      gcc_assert (old_size_est == estimate_edge_size (edge));
+      gcc_assert (old_time_est == estimate_edge_time (edge));
+      gcc_assert (old_hints_est == estimate_edge_hints (edge));
 
       /* When updating the edge costs, we only decrease badness in the keys.
 	 Increases of badness are handled lazilly; when we see key with out
@@ -1785,8 +1786,7 @@ inline_small_functions (void)
 	  inline_call (edge, true, &new_indirect_edges, &overall_size, true);
 	  add_new_edges_to_heap (&edge_heap, new_indirect_edges);
 
-	  reset_edge_caches (edge->callee);
-          reset_node_growth_cache (callee);
+	  reset_edge_caches (edge->callee->function_symbol ());
 
 	  update_callee_keys (&edge_heap, where, updated_nodes);
 	}
@@ -2218,7 +2218,6 @@ ipa_inline (void)
 	    {
 	      struct cgraph_node *where = node->global.inlined_to
 					  ? node->global.inlined_to : node;
-              reset_node_growth_cache (where);
 	      reset_edge_caches (where);
 	      inline_update_overall_summary (where);
 	    }
Index: ipa-inline.h
===================================================================
--- ipa-inline.h	(revision 219571)
+++ ipa-inline.h	(working copy)
@@ -224,7 +224,6 @@ struct edge_growth_cache_entry
   inline_hints hints;
 };
 
-extern vec<int> node_growth_cache;
 extern vec<edge_growth_cache_entry> edge_growth_cache;
 
 /* In ipa-inline-analysis.c  */
@@ -245,7 +244,7 @@ void estimate_ipcp_clone_size_and_time (
 					vec<ipa_polymorphic_call_context>,
 					vec<ipa_agg_jump_function_p>,
 					int *, int *, inline_hints *);
-int do_estimate_growth (struct cgraph_node *);
+int estimate_growth (struct cgraph_node *);
 bool growth_likely_positive (struct cgraph_node *, int);
 void inline_merge_summary (struct cgraph_edge *edge);
 void inline_update_overall_summary (struct cgraph_node *node);
@@ -274,21 +273,6 @@ inline_edge_summary (struct cgraph_edge
   return &inline_edge_summary_vec[edge->uid];
 }
 
-/* Return estimated unit growth after inlning all calls to NODE.
-   Quick accesors to the inline growth caches.  
-   For convenience we keep zero 0 as unknown.  Because growth
-   can be both positive and negative, we simply increase positive
-   growths by 1. */
-static inline int
-estimate_growth (struct cgraph_node *node)
-{
-  int ret;
-  if ((int)node_growth_cache.length () <= node->uid
-      || !(ret = node_growth_cache[node->uid]))
-    return do_estimate_growth (node);
-  return ret - (ret > 0);
-}
-
 
 /* Return estimated size of the inline sequence of EDGE.  */
 
@@ -342,16 +326,6 @@ estimate_edge_hints (struct cgraph_edge
   return ret - 1;
 }
 
-
-/* Reset cached value for NODE.  */
-
-static inline void
-reset_node_growth_cache (struct cgraph_node *node)
-{
-  if ((int)node_growth_cache.length () > node->uid)
-    node_growth_cache[node->uid] = 0;
-}
-
 /* Reset cached value for EDGE.  */
 
 static inline void


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]