OSDN Git Service

2009-10-22 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 22 Oct 2009 15:38:23 +0000 (15:38 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 22 Oct 2009 15:38:23 +0000 (15:38 +0000)
* lto-streamer.h (lto_symtab_merge_cgraph_nodes): Declare.
* lto-symtab.c (struct lto_symtab_entry_def): Add node member.
(lto_symtab_merge): Do not merge cgraph nodes here.
(lto_symtab_resolve_can_prevail_p): Simplify.
(lto_symtab_resolve_symbols): Store cgraph node.
(lto_symtab_merge_decls_1): Simplify.  Do not drop non-prevailing
functions from the symtab.
(lto_symtab_merge_cgraph_nodes_1): New function.
(lto_symtab_merge_cgraph_nodes): Likewise.

lto/
* lto.c (lto_fixup_jump_functions): Remove.
(lto_fixup_decls): Do not fixup jump functions.
(read_cgraph_and_symbols): Schedule cgraph merging after
summary reading.  Schedule type and decl fixup before
summary reading.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@153460 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/lto-streamer.h
gcc/lto-symtab.c
gcc/lto/ChangeLog
gcc/lto/lto.c

index 6d68948..24928d2 100644 (file)
@@ -1,5 +1,17 @@
 2009-10-22  Richard Guenther  <rguenther@suse.de>
 
+       * lto-streamer.h (lto_symtab_merge_cgraph_nodes): Declare.
+       * lto-symtab.c (struct lto_symtab_entry_def): Add node member.
+       (lto_symtab_merge): Do not merge cgraph nodes here.
+       (lto_symtab_resolve_can_prevail_p): Simplify.
+       (lto_symtab_resolve_symbols): Store cgraph node.
+       (lto_symtab_merge_decls_1): Simplify.  Do not drop non-prevailing
+       functions from the symtab.
+       (lto_symtab_merge_cgraph_nodes_1): New function.
+       (lto_symtab_merge_cgraph_nodes): Likewise.
+
+2009-10-22  Richard Guenther  <rguenther@suse.de>
+
        PR lto/41791
        * lto-streamer-out.c (lto_output_location): Stream the
        system header flag.
index 4b8b845..de1ee08 100644 (file)
@@ -845,6 +845,7 @@ void input_cgraph (void);
 extern void lto_symtab_register_decl (tree, ld_plugin_symbol_resolution_t,
                                      struct lto_file_decl_data *);
 extern void lto_symtab_merge_decls (void);
+extern void lto_symtab_merge_cgraph_nodes (void);
 extern tree lto_symtab_prevailing_decl (tree decl);
 extern enum ld_plugin_symbol_resolution lto_symtab_get_resolution (tree decl);
 
index d292a57..642b623 100644 (file)
@@ -41,6 +41,9 @@ struct GTY(()) lto_symtab_entry_def
   tree id;
   /* The symbol table entry, a DECL.  */
   tree decl;
+  /* The cgraph node if decl is a function decl.  Filled in during the
+     merging process.  */
+  struct cgraph_node *node;
   /* LTO file-data and symbol resolution for this decl.  */
   struct lto_file_decl_data * GTY((skip (""))) file_data;
   enum ld_plugin_symbol_resolution resolution;
@@ -232,18 +235,12 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
   tree prevailing_decl = prevailing->decl;
   tree decl = entry->decl;
   tree prevailing_type, type;
-  struct cgraph_node *node;
 
   /* Merge decl state in both directions, we may still end up using
      the new decl.  */
   TREE_ADDRESSABLE (prevailing_decl) |= TREE_ADDRESSABLE (decl);
   TREE_ADDRESSABLE (decl) |= TREE_ADDRESSABLE (prevailing_decl);
 
-  /* Replace a cgraph node of entry with the prevailing one.  */
-  if (TREE_CODE (decl) == FUNCTION_DECL
-      && (node = cgraph_get_node (decl)) != NULL)
-    lto_cgraph_replace_node (node, cgraph_get_node (prevailing_decl));
-
   /* The linker may ask us to combine two incompatible symbols.
      Detect this case and notify the caller of required diagnostics.  */
 
@@ -355,15 +352,12 @@ lto_symtab_resolve_replaceable_p (lto_symtab_entry_t e)
 static bool
 lto_symtab_resolve_can_prevail_p (lto_symtab_entry_t e)
 {
-  struct cgraph_node *node;
-
   if (!TREE_STATIC (e->decl))
     return false;
 
   /* For functions we need a non-discarded body.  */
   if (TREE_CODE (e->decl) == FUNCTION_DECL)
-    return ((node = cgraph_get_node (e->decl))
-           && node->analyzed);
+    return (e->node && e->node->analyzed);
 
   /* A variable should have a size.  */
   else if (TREE_CODE (e->decl) == VAR_DECL)
@@ -393,6 +387,9 @@ lto_symtab_resolve_symbols (void **slot)
      diagnose ODR violations.  */
   for (; e; e = e->next)
     {
+      if (TREE_CODE (e->decl) == FUNCTION_DECL)
+       e->node = cgraph_get_node (e->decl);
+
       if (!lto_symtab_resolve_can_prevail_p (e))
        {
          e->resolution = LDPR_RESOLVED_IR;
@@ -531,7 +528,7 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
       prevailing = (lto_symtab_entry_t) *slot;
       /* For functions choose one with a cgraph node.  */
       if (TREE_CODE (prevailing->decl) == FUNCTION_DECL)
-       while (!cgraph_get_node (prevailing->decl)
+       while (!prevailing->node
               && prevailing->next)
          prevailing = prevailing->next;
       /* We do not stream varpool nodes, so the first decl has to
@@ -600,7 +597,8 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
   lto_symtab_merge_decls_2 (slot);
 
   /* Drop all but the prevailing decl from the symtab.  */
-  prevailing->next = NULL;
+  if (TREE_CODE (prevailing->decl) != FUNCTION_DECL)
+    prevailing->next = NULL;
 
   return 1;
 }
@@ -614,6 +612,40 @@ lto_symtab_merge_decls (void)
   htab_traverse (lto_symtab_identifiers, lto_symtab_merge_decls_1, NULL);
 }
 
+/* Helper to process the decl chain for the symbol table entry *SLOT.  */
+
+static int
+lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED)
+{
+  lto_symtab_entry_t e, prevailing = (lto_symtab_entry_t) *slot;
+
+  if (!prevailing->next)
+    return 1;
+
+  gcc_assert (TREE_CODE (prevailing->decl) == FUNCTION_DECL);
+
+  /* Replace the cgraph node of each entry with the prevailing one.  */
+  for (e = prevailing->next; e; e = e->next)
+    {
+      if (e->node != NULL)
+       lto_cgraph_replace_node (e->node, prevailing->node);
+    }
+
+  /* Drop all but the prevailing decl from the symtab.  */
+  prevailing->next = NULL;
+
+  return 1;
+}
+
+/* Merge cgraph nodes according to the symbol merging done by
+   lto_symtab_merge_decls.  */
+
+void
+lto_symtab_merge_cgraph_nodes (void)
+{
+  lto_symtab_maybe_init_hash_table ();
+  htab_traverse (lto_symtab_identifiers, lto_symtab_merge_cgraph_nodes_1, NULL);
+}
 
 /* Given the decl DECL, return the prevailing decl with the same name. */
 
index dd0ff8e..d6c3325 100644 (file)
@@ -1,5 +1,13 @@
 2009-10-22  Richard Guenther  <rguenther@suse.de>
 
+       * lto.c (lto_fixup_jump_functions): Remove.
+       (lto_fixup_decls): Do not fixup jump functions.
+       (read_cgraph_and_symbols): Schedule cgraph merging after
+       summary reading.  Schedule type and decl fixup before
+       summary reading.
+
+2009-10-22  Richard Guenther  <rguenther@suse.de>
+
        * lto.c (lto_fixup_data_t): Remove free_list member.
        (lto_fixup_tree): Do not insert into free_list.
        (free_decl): Remove.
index 79af51f..54fde65 100644 (file)
@@ -1635,53 +1635,6 @@ lto_fixup_state_aux (void **slot, void *aux)
   return 1;
 }
 
-/* Fixup pointers in jump functions.
-   TODO: We need some generic solution that will allow tree pointers in
-   function summaries.  */
-static void
-lto_fixup_jump_functions (lto_fixup_data_t * data)
-{
-  struct cgraph_node *node;
-  struct cgraph_edge *cs;
-
-  for (node = cgraph_nodes; node; node = node->next)
-    {
-      if (!node->analyzed)
-       continue;
-      for (cs = node->callees; cs; cs = cs->next_callee)
-       {
-         int i;
-         struct ipa_edge_args *args = IPA_EDGE_REF (cs);
-         for (i = 0; i < ipa_get_cs_argument_count (args); i++)
-           {
-             struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
-             switch (jf->type)
-               {
-               case IPA_JF_UNKNOWN:
-                 break;
-               case IPA_JF_CONST:
-                 walk_tree (&jf->value.constant, lto_fixup_tree, data, NULL);
-                 break;
-               case IPA_JF_PASS_THROUGH:
-                 walk_tree (&jf->value.pass_through.operand, lto_fixup_tree,
-                            data, NULL);
-                 break;
-               case IPA_JF_ANCESTOR:
-                 walk_tree (&jf->value.ancestor.type, lto_fixup_tree, data,
-                            NULL);
-                 break;
-               case IPA_JF_CONST_MEMBER_PTR:
-                 walk_tree (&jf->value.member_cst.pfn, lto_fixup_tree, data,
-                            NULL);
-                 walk_tree (&jf->value.member_cst.delta, lto_fixup_tree,
-                            data, NULL);
-                 break;
-               }
-           }
-       }
-    }
-}
-
 /* Fix the decls from all FILES. Replaces each decl with the corresponding
    prevailing one.  */
 
@@ -1710,8 +1663,6 @@ lto_fixup_decls (struct lto_file_decl_data **files)
       if (decl != saved_decl)
        VEC_replace (tree, lto_global_var_decls, i, decl);
     }
-  if (ipa_edge_args_vector)
-    lto_fixup_jump_functions (&data);
 
   pointer_set_destroy (seen);
 }
@@ -1851,11 +1802,18 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
   /* Read the callgraph.  */
   input_cgraph ();
 
+  /* Merge global decls.  */
+  lto_symtab_merge_decls ();
+
+  /* Fixup all decls and types and free the type hash tables.  */
+  lto_fixup_decls (all_file_decl_data);
+  free_gimple_type_tables ();
+
   /* Read the IPA summary data.  */
   ipa_read_summaries ();
 
-  /* Merge global decls.  */
-  lto_symtab_merge_decls ();
+  /* Finally merge the cgraph according to the decl merging decisions.  */
+  lto_symtab_merge_cgraph_nodes ();
 
   /* Mark cgraph nodes needed in the merged cgraph
      This normally happens in whole-program pass, but for
@@ -1872,12 +1830,6 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
 
   timevar_push (TV_IPA_LTO_DECL_IO);
 
-  /* Fixup all decls and types.  */
-  lto_fixup_decls (all_file_decl_data);
-
-  /* Free the type hash tables.  */
-  free_gimple_type_tables ();
-
   /* FIXME lto. This loop needs to be changed to use the pass manager to
      call the ipa passes directly.  */
   if (!errorcount)