On Fri, Jul 6, 2012 at 9:08 PM, H.J. Lu <hongjiu...@intel.com> wrote: > 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);
PING. -- H.J.