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...@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.

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);

Reply via email to