This patch refactors LIPO fixup related code to move it into a standalone function. This makes sure that symtab_remove_unreachable_nodes is called right after the fixup so that there is not dangling cgraph nodes any time.
Bootstrapped and regression test on-going. OK for google-4_8? Thanks, Dehao
Index: gcc/tree-profile.c =================================================================== --- gcc/tree-profile.c (revision 208818) +++ gcc/tree-profile.c (working copy) @@ -1119,18 +1119,12 @@ tree_profiling (void) cgraphunit.c:ipa_passes(). */ gcc_assert (cgraph_state == CGRAPH_STATE_IPA_SSA); + init_node_map (); + /* After value profile transformation, artificial edges (that keep function body from being deleted) won't be needed. */ + lipo_link_and_fixup (); - cgraph_pre_profiling_inlining_done = true; - cgraph_process_module_scope_statics (); - /* Now perform link to allow cross module inlining. */ - cgraph_do_link (); - varpool_do_link (); - cgraph_unify_type_alias_sets (); - - init_node_map(); - FOR_EACH_DEFINED_FUNCTION (node) { if (!gimple_has_body_p (node->symbol.decl)) @@ -1142,23 +1136,6 @@ tree_profiling (void) push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); - if (L_IPO_COMP_MODE) - { - basic_block bb; - FOR_EACH_BB (bb) - { - gimple_stmt_iterator gsi; - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple stmt = gsi_stmt (gsi); - if (is_gimple_call (stmt)) - lipo_fixup_cgraph_edge_call_target (stmt); - } - } - update_ssa (TODO_update_ssa); - } - - /* Local pure-const may imply need to fixup the cfg. */ if (execute_fixup_cfg () & TODO_cleanup_cfg) cleanup_tree_cfg (); Index: gcc/l-ipo.h =================================================================== --- gcc/l-ipo.h (revision 208818) +++ gcc/l-ipo.h (working copy) @@ -60,7 +60,7 @@ void add_decl_to_current_module_scope (tree decl, int lipo_cmp_type (tree t1, tree t2); tree get_type_or_decl_name (tree); int equivalent_struct_types_for_tbaa (const_tree t1, const_tree t2); -void lipo_fixup_cgraph_edge_call_target (gimple); +void lipo_link_and_fixup (void); extern void copy_defined_module_set (tree, tree); extern bool is_parsing_done_p (void); extern const char* get_module_name (unsigned int); Index: gcc/auto-profile.c =================================================================== --- gcc/auto-profile.c (revision 208818) +++ gcc/auto-profile.c (working copy) @@ -1535,14 +1535,8 @@ auto_profile (void) init_node_map (); profile_info = autofdo::afdo_profile_info; + lipo_link_and_fixup (); - cgraph_pre_profiling_inlining_done = true; - cgraph_process_module_scope_statics (); - /* Now perform link to allow cross module inlining. */ - cgraph_do_link (); - varpool_do_link (); - cgraph_unify_type_alias_sets (); - FOR_EACH_FUNCTION (node) { if (!gimple_has_body_p (node->symbol.decl)) @@ -1554,35 +1548,6 @@ auto_profile (void) push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); - if (L_IPO_COMP_MODE) - { - basic_block bb; - FOR_EACH_BB (bb) - { - gimple_stmt_iterator gsi; - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple stmt = gsi_stmt (gsi); - if (is_gimple_call (stmt)) - lipo_fixup_cgraph_edge_call_target (stmt); - } - } - } - rebuild_cgraph_edges (); - pop_cfun (); - } - - FOR_EACH_FUNCTION (node) - { - if (!gimple_has_body_p (node->symbol.decl)) - continue; - - /* Don't profile functions produced for builtin stuff. */ - if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION) - continue; - - push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); - /* First do indirect call promotion and early inline to make the IR match the profiled binary before actual annotation. Index: gcc/cgraphbuild.c =================================================================== --- gcc/cgraphbuild.c (revision 208818) +++ gcc/cgraphbuild.c (working copy) @@ -599,7 +599,7 @@ record_references_in_initializer (tree decl, bool needs to be set to the resolved node so that ipa-inline sees the definitions. */ #include "gimple-pretty-print.h" -void +static void lipo_fixup_cgraph_edge_call_target (gimple stmt) { tree decl; @@ -625,6 +625,52 @@ lipo_fixup_cgraph_edge_call_target (gimple stmt) } } +void +lipo_link_and_fixup () +{ + struct cgraph_node *node; + + cgraph_pre_profiling_inlining_done = true; + cgraph_process_module_scope_statics (); + /* Now perform link to allow cross module inlining. */ + cgraph_do_link (); + varpool_do_link (); + cgraph_unify_type_alias_sets (); + + FOR_EACH_DEFINED_FUNCTION (node) + { + if (!gimple_has_body_p (node->symbol.decl)) + continue; + + /* Don't profile functions produced for builtin stuff. */ + if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION) + continue; + + push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); + + if (L_IPO_COMP_MODE) + { + basic_block bb; + FOR_EACH_BB (bb) + { + gimple_stmt_iterator gsi; + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple stmt = gsi_stmt (gsi); + if (is_gimple_call (stmt)) + lipo_fixup_cgraph_edge_call_target (stmt); + } + } + update_ssa (TODO_update_ssa); + } + rebuild_cgraph_edges (); + pop_cfun (); + } + + symtab_remove_unreachable_nodes (true, dump_file); +} + + /* Rebuild cgraph edges for current function node. This needs to be run after passes that don't update the cgraph. */