* 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
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.
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);
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;
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. */
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)
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;
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
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;
}
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. */
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.
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. */
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);
}
/* 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
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)