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.  */
 

Reply via email to