Patchwork PR middle-end/53321: [4.8 Regression] LTO bootstrap failed with bootstrap-profiled

login
register
mail settings
Submitter H.J. Lu
Date July 7, 2012, 4:08 a.m.
Message ID <20120707040814.GA23165@intel.com>
Download mbox | patch
Permalink /patch/169554/
State New
Headers show

Comments

H.J. Lu - July 7, 2012, 4:08 a.m.
Hi,

After inlining, IPA calls tree_profiling which rebuilds edges:

#2  0x0000000000683ccd in rebuild_cgraph_edges ()
    at /export/gnu/import/git/gcc/gcc/cgraphbuild.c:433
#3  0x0000000000c02de6 in tree_profiling ()
    at /export/gnu/import/git/gcc/gcc/tree-profile.c:564
#4  0x0000000000a1be4f in execute_one_pass (pass=0x1908520)
    at /export/gnu/import/git/gcc/gcc/passes.c:2165
#5  0x0000000000a1cb0c in execute_ipa_pass_list (pass=0x1908520)
    at /export/gnu/import/git/gcc/gcc/passes.c:2532
#6  0x000000000068b874 in ipa_passes ()
    at /export/gnu/import/git/gcc/gcc/cgraphunit.c:1844

  basic_block bb; 
  struct cgraph_node *node = cgraph_get_node (current_function_decl);
  gimple_stmt_iterator gsi;

  cgraph_node_remove_callees (node);
  ipa_remove_all_references (&node->symbol.ref_list);

  node->count = ENTRY_BLOCK_PTR->count;

and creates new edges.  After that, all things went downhill

#0  internal_error (
    gmsgid=0x158c110 "vector %s %s domain error, in %s at %s:%u")
    at /export/gnu/import/git/gcc/gcc/diagnostic.c:955
#1  0x000000000124f707 in vec_assert_fail (op=0x12fc800 "index", 
    struct_name=0x12fc7e0 "VEC(inline_edge_summary_t,base)", 
    file=0x12fc808 "/export/gnu/import/git/gcc/gcc/ipa-inline.h",
line=200, 
    function=0x12fd380 "inline_edge_summary")
    at /export/gnu/import/git/gcc/gcc/vec.c:527
#2  0x000000000067c685 in VEC_inline_edge_summary_t_base_index (
    vec_=0x1aea360, ix_=6, 
    file_=0x12fc808 "/export/gnu/import/git/gcc/gcc/ipa-inline.h",
line_=200, 
    function_=0x12fd380 "inline_edge_summary")
    at /export/gnu/import/git/gcc/gcc/ipa-inline.h:145
#3  0x000000000067c6cd in inline_edge_summary (edge=0x7ffff1ab67b8)
    at /export/gnu/import/git/gcc/gcc/ipa-inline.h:199

since inline summary becomes stale after gimple_gen_ic_func_profiler
generates profiling function calls.  If we don't call
cgraph_propagate_frequency call when something was changed, LTO will
generate corrupted output, which leads to

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53865

This patch clears stale inline summary after gimple_gen_ic_func_profiler
generates profiling function calls.   It fixes both PR 53321 and PR 53865.
OK to install?

Thanks.


H.J.
----
2012-07-06  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/53321
	PR middle-end/53865
	* Makefile.in (tree-profile.o): Depend on ipa-inline.h.

	* ipa.c (symtab_remove_unreachable_nodes): Restore
	cgraph_propagate_frequency call when something was changed.

	* tree-profile.c: Include "ipa-inline.h".
	(gimple_gen_ic_func_profiler): Return bool.
	(tree_profiling): Call inline_free_summary to clear stale inline
	summary if gimple_gen_ic_func_profiler returns true.

	* value-prof.h (gimple_gen_ic_func_profiler): Change return
	type to bool.
Jan Hubicka - July 31, 2012, 12:39 p.m.
> Hi,
> 
> 2012-07-06  H.J. Lu  <hongjiu.lu@intel.com>
> 
> 	PR middle-end/53321
> 	PR middle-end/53865
> 	* Makefile.in (tree-profile.o): Depend on ipa-inline.h.
> 
> 	* ipa.c (symtab_remove_unreachable_nodes): Restore
> 	cgraph_propagate_frequency call when something was changed.
> 
> 	* tree-profile.c: Include "ipa-inline.h".
> 	(gimple_gen_ic_func_profiler): Return bool.
> 	(tree_profiling): Call inline_free_summary to clear stale inline
> 	summary if gimple_gen_ic_func_profiler returns true.
> 
> 	* value-prof.h (gimple_gen_ic_func_profiler): Change return
> 	type to bool.

Hi,
My local tree is profedbootstrapping since I had local patch to
prevent recomputation it before ipa_profile pass, but I agree it is better
to not have stale inline summaries around.

> +  /* Clear stale inline summary.  */
> +  if (gen_ic_func_profiler)
> +    inline_free_summary ();

The inline summary is completely dead here. It is computed for purposes of
early inlining and the real inliner will trash it and recompute soon.
(because the one computer by real inliner is more detailed).

matrix_reorg, emutls and tm passes will also suffer from the problem of
invalidating the inling summary. It is better to free it early this.

Can you simply add a micro pass just after pass_early_local_passes calliing
inline_free_summary unconditionally?

Path is preapproved (or I will make it tomorrow unless you beat me).

Thank you!
Honza

Patch

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 33775ac..9f6c7e5 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3060,7 +3060,8 @@  mcf.o : mcf.c profile.h $(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h \
    $(BASIC_BLOCK_H) langhooks.h $(GCOV_IO_H) $(TREE_H) 
 tree-profile.o : tree-profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TM_H) $(TARGET_H) $(TREE_H) $(FLAGS_H) $(FUNCTION_H) \
-   $(BASIC_BLOCK_H) $(DIAGNOSTIC_CORE_H) $(COVERAGE_H) $(TREE_H) value-prof.h $(TREE_DUMP_H) \
+   $(BASIC_BLOCK_H) $(DIAGNOSTIC_CORE_H) $(COVERAGE_H) $(TREE_H) \
+   value-prof.h $(TREE_DUMP_H) ipa-inline.h \
    $(TREE_PASS_H) $(TREE_FLOW_H) $(TIMEVAR_H) gt-tree-profile.h $(CGRAPH_H)
 value-prof.o : value-prof.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(BASIC_BLOCK_H) hard-reg-set.h profile.h value-prof.h $(EXPR_H) $(FLAGS_H) \
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 09351a7..f5cce1b 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -449,6 +449,11 @@  symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
   verify_symtab ();
 #endif
 
+  /* If we removed something, perhaps profile could be improved.  */
+  if (changed && optimize && inline_edge_summary_vec)
+    FOR_EACH_DEFINED_FUNCTION (node)
+      cgraph_propagate_frequency (node);
+
   return changed;
 }
 
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index dfd0ef0..b90ab92 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -42,6 +42,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "timevar.h"
 #include "value-prof.h"
 #include "cgraph.h"
+#include "ipa-inline.h"
 #include "profile.h"
 #include "target.h"
 
@@ -357,7 +358,7 @@  gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
    beginning of every possible called function.
   */
 
-void
+bool
 gimple_gen_ic_func_profiler (void)
 {
   struct cgraph_node * c_node = cgraph_get_node (current_function_decl);
@@ -366,7 +367,7 @@  gimple_gen_ic_func_profiler (void)
   tree tree_uid, cur_func, counter_ptr, ptr_var, void0;
 
   if (cgraph_only_called_directly_p (c_node))
-    return;
+    return false;
 
   gimple_init_edge_profiler ();
 
@@ -394,6 +395,7 @@  gimple_gen_ic_func_profiler (void)
   void0 = build_int_cst (build_pointer_type (void_type_node), 0);
   stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
   gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
+  return true;
 }
 
 /* Output instructions as GIMPLE trees for code to find the most common value
@@ -462,6 +464,7 @@  static unsigned int
 tree_profiling (void)
 {
   struct cgraph_node *node;
+  bool gen_ic_func_profiler;
 
   /* Don't profile functions produced at destruction time, particularly
      the gcov datastructure initializer.  Don't profile if it has been
@@ -472,6 +475,8 @@  tree_profiling (void)
 
   init_node_map();
 
+  gen_ic_func_profiler = false;
+
   FOR_EACH_DEFINED_FUNCTION (node)
     {
       if (!gimple_has_body_p (node->symbol.decl))
@@ -495,7 +500,7 @@  tree_profiling (void)
 
       if (! flag_branch_probabilities
 	  && flag_profile_values)
-	gimple_gen_ic_func_profiler ();
+	gen_ic_func_profiler |= gimple_gen_ic_func_profiler ();
 
       if (flag_branch_probabilities
 	  && flag_profile_values
@@ -567,6 +572,10 @@  tree_profiling (void)
       pop_cfun ();
     }
 
+  /* Clear stale inline summary.  */
+  if (gen_ic_func_profiler)
+    inline_free_summary ();
+
   del_node_map();
   return 0;
 }
diff --git a/gcc/value-prof.h b/gcc/value-prof.h
index b7215b8..b083c29 100644
--- a/gcc/value-prof.h
+++ b/gcc/value-prof.h
@@ -96,7 +96,7 @@  extern void gimple_gen_interval_profiler (histogram_value, unsigned, unsigned);
 extern void gimple_gen_pow2_profiler (histogram_value, unsigned, unsigned);
 extern void gimple_gen_one_value_profiler (histogram_value, unsigned, unsigned);
 extern void gimple_gen_ic_profiler (histogram_value, unsigned, unsigned);
-extern void gimple_gen_ic_func_profiler (void);
+extern bool gimple_gen_ic_func_profiler (void);
 extern void gimple_gen_const_delta_profiler (histogram_value,
 					     unsigned, unsigned);
 extern void gimple_gen_average_profiler (histogram_value, unsigned, unsigned);