From 1e8fbfd0876c5bac8430158f8d026059c3a0d435 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Thu, 22 Oct 2009 15:38:23 +0000 Subject: 2009-10-22 Richard Guenther * 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: https://gcc.gnu.org/svn/gcc/trunk@153460 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 12 ++++++++++ gcc/lto-streamer.h | 1 + gcc/lto-symtab.c | 56 +++++++++++++++++++++++++++++++++++---------- gcc/lto/ChangeLog | 8 +++++++ gcc/lto/lto.c | 66 ++++++++---------------------------------------------- 5 files changed, 74 insertions(+), 69 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6d689482df4..24928d2e011 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2009-10-22 Richard Guenther + + * 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 PR lto/41791 diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index 4b8b845dfe8..de1ee080b84 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -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); diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c index d292a571e87..642b6235d90 100644 --- a/gcc/lto-symtab.c +++ b/gcc/lto-symtab.c @@ -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. */ diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index dd0ff8ec195..d6c3325846d 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,11 @@ +2009-10-22 Richard Guenther + + * 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 * lto.c (lto_fixup_data_t): Remove free_list member. diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 79af51f3478..54fde65c69a 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -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) -- cgit v1.2.3