diff options
author | Jan Hubicka <jh@suse.cz> | 2013-06-12 11:12:47 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2013-06-12 09:12:47 +0000 |
commit | bbf9ad070dd1acea0c60aa531a738c8fc8d410d5 (patch) | |
tree | f90b96685d9ff8fb7b5722fdf8b1ff094b9c8b96 /gcc | |
parent | a53f90adbffa2ec9fae2b28c7dd33d1b923b5431 (diff) | |
download | gcc-bbf9ad070dd1acea0c60aa531a738c8fc8d410d5.zip gcc-bbf9ad070dd1acea0c60aa531a738c8fc8d410d5.tar.gz gcc-bbf9ad070dd1acea0c60aa531a738c8fc8d410d5.tar.bz2 |
lto-symtab.c (lto_symtab_merge_symbols): Populate symtab hashtable.
* lto-symtab.c (lto_symtab_merge_symbols): Populate symtab hashtable.
* cgraph.h (varpool_create_empty_node): Declare.
* lto-cgraph.c (input_node, input_varpool_node): Forcingly create
duplicated nodes.
* symtab.c (symtab_unregister_node): Be lax about missin entries
in node hash.
(symtab_get_node): Update comment.
* varpool.c (varpool_create_empty_node): Break out from ...
(varpool_node_for_decl): ... here.
* lto-streamer.h (lto_file_decl_data): Add RESOLUTION_MAP.
* lto.c (register_resolution): Take lto_file_data argument.
(lto_register_var_decl_in_symtab,
lto_register_function_decl_in_symtab): Update.
(read_cgraph_and_symbols): Update resolution_map handling.
From-SVN: r199990
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/cgraph.h | 1 | ||||
-rw-r--r-- | gcc/lto-cgraph.c | 18 | ||||
-rw-r--r-- | gcc/lto-streamer.h | 3 | ||||
-rw-r--r-- | gcc/lto-symtab.c | 13 | ||||
-rw-r--r-- | gcc/lto/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/lto/lto.c | 46 | ||||
-rw-r--r-- | gcc/symtab.c | 10 | ||||
-rw-r--r-- | gcc/varpool.c | 16 |
9 files changed, 95 insertions, 32 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0a577c3..16b4ca2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2013-06-12 Jan Hubicka <jh@suse.cz> + + * lto-symtab.c (lto_symtab_merge_symbols): Populate symtab hashtable. + * cgraph.h (varpool_create_empty_node): Declare. + * lto-cgraph.c (input_node, input_varpool_node): Forcingly create + duplicated nodes. + * symtab.c (symtab_unregister_node): Be lax about missin entries + in node hash. + (symtab_get_node): Update comment. + * varpool.c (varpool_create_empty_node): Break out from ... + (varpool_node_for_decl): ... here. + * lto-streamer.h (lto_file_decl_data): Add RESOLUTION_MAP. + 2013-06-12 Eric Botcazou <ebotcazou@adacore.com> * expr.c (expand_expr_real_1) <TARGET_MEM_REF>: Use straight-line flow. diff --git a/gcc/cgraph.h b/gcc/cgraph.h index c67506d..9661427 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -773,6 +773,7 @@ bool cgraph_maybe_hot_edge_p (struct cgraph_edge *e); bool cgraph_optimize_for_size_p (struct cgraph_node *); /* In varpool.c */ +struct varpool_node *varpool_create_empty_node (void); struct varpool_node *varpool_node_for_decl (tree); struct varpool_node *varpool_node_for_asm (tree asmname); void varpool_mark_needed_node (struct varpool_node *); diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index 63a9ddb..e3f8880 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -959,7 +959,14 @@ input_node (struct lto_file_decl_data *file_data, vNULL, false); } else - node = cgraph_get_create_node (fn_decl); + { + /* Declaration of functions can be already merged with a declaration + from other input file. We keep cgraph unmerged until after streaming + of ipa passes is done. Alays forcingly create a fresh node. */ + node = cgraph_create_empty_node (); + node->symbol.decl = fn_decl; + symtab_register_node ((symtab_node)node); + } node->symbol.order = order; if (order >= symtab_order) @@ -1035,7 +1042,14 @@ input_varpool_node (struct lto_file_decl_data *file_data, order = streamer_read_hwi (ib) + order_base; decl_index = streamer_read_uhwi (ib); var_decl = lto_file_decl_data_get_var_decl (file_data, decl_index); - node = varpool_node_for_decl (var_decl); + + /* Declaration of functions can be already merged with a declaration + from other input file. We keep cgraph unmerged until after streaming + of ipa passes is done. Alays forcingly create a fresh node. */ + node = varpool_create_empty_node (); + node->symbol.decl = var_decl; + symtab_register_node ((symtab_node)node); + node->symbol.order = order; if (order >= symtab_order) symtab_order = order + 1; diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index a0eca6d..88985dd 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -569,6 +569,9 @@ struct GTY(()) lto_file_decl_data unsigned max_index; struct gcov_ctr_summary GTY((skip)) profile_info; + + /* Map assigning declarations their resolutions. */ + pointer_map_t * GTY((skip)) resolution_map; }; typedef struct lto_file_decl_data *lto_file_decl_data_ptr; diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c index 5f0b971..a92e14c 100644 --- a/gcc/lto-symtab.c +++ b/gcc/lto-symtab.c @@ -573,16 +573,21 @@ lto_symtab_merge_symbols (void) { symtab_initialize_asm_name_hash (); - /* Do the actual merging. */ + /* Do the actual merging. + At this point we invalidate hash translating decls into symtab nodes + because after removing one of duplicate decls the hash is not correcly + updated to the ohter dupliate. */ FOR_EACH_SYMBOL (node) if (lto_symtab_symbol_p (node) && node->symbol.next_sharing_asm_name && !node->symbol.previous_sharing_asm_name) lto_symtab_merge_symbols_1 (node); - /* Resolve weakref aliases whose target are now in the compilation unit. */ + /* Resolve weakref aliases whose target are now in the compilation unit. + also re-populate the hash translating decls into symtab nodes*/ FOR_EACH_SYMBOL (node) { + cgraph_node *cnode; if (!node->symbol.analyzed && node->symbol.alias_target) { symtab_node tgt = symtab_node_for_asm (node->symbol.alias_target); @@ -591,6 +596,10 @@ lto_symtab_merge_symbols (void) symtab_resolve_alias (node, tgt); } node->symbol.aux = NULL; + if (!(cnode = dyn_cast <cgraph_node> (node)) + || !cnode->clone_of + || cnode->clone_of->symbol.decl != cnode->symbol.decl) + symtab_insert_node_to_hashtable ((symtab_node)node); } } } diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 153f023..216882a 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,10 @@ +2013-06-12 Jan Hubicka <jh@suse.cz> + + * lto.c (register_resolution): Take lto_file_data argument. + (lto_register_var_decl_in_symtab, + lto_register_function_decl_in_symtab): Update. + (read_cgraph_and_symbols): Update resolution_map handling. + 2013-06-11 Jan Hubicka <jh@suse.cz> * lto-partition.c (get_symbol_class): Simplify weakref handling. diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index c90a2d8..a4c5d29 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -1726,18 +1726,16 @@ get_resolution (struct data_in *data_in, unsigned index) return LDPR_UNKNOWN; } -/* Map assigning declarations their resolutions. */ -static pointer_map_t *resolution_map; - /* We need to record resolutions until symbol table is read. */ static void -register_resolution (tree decl, enum ld_plugin_symbol_resolution resolution) +register_resolution (struct lto_file_decl_data *file_data, tree decl, + enum ld_plugin_symbol_resolution resolution) { if (resolution == LDPR_UNKNOWN) return; - if (!resolution_map) - resolution_map = pointer_map_create (); - *pointer_map_insert (resolution_map, decl) = (void *)(size_t)resolution; + if (!file_data->resolution_map) + file_data->resolution_map = pointer_map_create (); + *pointer_map_insert (file_data->resolution_map, decl) = (void *)(size_t)resolution; } /* Register DECL with the global symbol table and change its @@ -1764,7 +1762,7 @@ lto_register_var_decl_in_symtab (struct data_in *data_in, tree decl) unsigned ix; if (!streamer_tree_cache_lookup (data_in->reader_cache, decl, &ix)) gcc_unreachable (); - register_resolution (decl, get_resolution (data_in, ix)); + register_resolution (data_in->file_data, decl, get_resolution (data_in, ix)); } } @@ -1784,7 +1782,7 @@ lto_register_function_decl_in_symtab (struct data_in *data_in, tree decl) unsigned ix; if (!streamer_tree_cache_lookup (data_in->reader_cache, decl, &ix)) gcc_unreachable (); - register_resolution (decl, get_resolution (data_in, ix)); + register_resolution (data_in->file_data, decl, get_resolution (data_in, ix)); } } @@ -2865,6 +2863,8 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames) struct cgraph_node *node; int count = 0; struct lto_file_decl_data **decl_data; + void **res; + symtab_node snode; init_cgraph (); @@ -2971,21 +2971,21 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames) input_symtab (); /* Store resolutions into the symbol table. */ - if (resolution_map) - { - void **res; - symtab_node snode; - FOR_EACH_SYMBOL (snode) - if (symtab_real_symbol_p (snode) - && (res = pointer_map_contains (resolution_map, - snode->symbol.decl))) - snode->symbol.resolution - = (enum ld_plugin_symbol_resolution)(size_t)*res; - - pointer_map_destroy (resolution_map); - resolution_map = NULL; - } + FOR_EACH_SYMBOL (snode) + if (symtab_real_symbol_p (snode) + && snode->symbol.lto_file_data + && snode->symbol.lto_file_data->resolution_map + && (res = pointer_map_contains (snode->symbol.lto_file_data->resolution_map, + snode->symbol.decl))) + snode->symbol.resolution + = (enum ld_plugin_symbol_resolution)(size_t)*res; + for (i = 0; all_file_decl_data[i]; i++) + if (all_file_decl_data[i]->resolution_map) + { + pointer_map_destroy (all_file_decl_data[i]->resolution_map); + all_file_decl_data[i]->resolution_map = NULL; + } timevar_pop (TV_IPA_LTO_CGRAPH_IO); diff --git a/gcc/symtab.c b/gcc/symtab.c index 7a02270..0ce44a9 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -269,7 +269,11 @@ symtab_unregister_node (symtab_node node) node->symbol.previous = NULL; slot = htab_find_slot (symtab_hash, node, NO_INSERT); - if (*slot == node) + + /* During LTO symtab merging we temporarily corrupt decl to symtab node + hash. */ + gcc_assert ((slot && *slot) || in_lto_p); + if (slot && *slot && *slot == node) { symtab_node replacement_node = NULL; if (cgraph_node *cnode = dyn_cast <cgraph_node> (node)) @@ -291,10 +295,14 @@ symtab_get_node (const_tree decl) symtab_node *slot; struct symtab_node_base key; +#ifdef ENABLE_CHECKING + /* Check that we are called for sane type of object - functions + and static or external variables. */ gcc_checking_assert (TREE_CODE (decl) == FUNCTION_DECL || (TREE_CODE (decl) == VAR_DECL && (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || in_lto_p))); +#endif if (!symtab_hash) return NULL; diff --git a/gcc/varpool.c b/gcc/varpool.c index 4b23884..fd193d3 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -36,18 +36,26 @@ along with GCC; see the file COPYING3. If not see #include "tree-flow.h" #include "flags.h" +/* Allocate new callgraph node and insert it into basic data structures. */ + +struct varpool_node * +varpool_create_empty_node (void) +{ + struct varpool_node *node = ggc_alloc_cleared_varpool_node (); + node->symbol.type = SYMTAB_VARIABLE; + return node; +} + /* Return varpool node assigned to DECL. Create new one when needed. */ struct varpool_node * varpool_node_for_decl (tree decl) { struct varpool_node *node = varpool_get_node (decl); - gcc_assert (TREE_CODE (decl) == VAR_DECL - && (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || in_lto_p)); + gcc_checking_assert (TREE_CODE (decl) == VAR_DECL); if (node) return node; - node = ggc_alloc_cleared_varpool_node (); - node->symbol.type = SYMTAB_VARIABLE; + node = varpool_create_empty_node (); node->symbol.decl = decl; symtab_register_node ((symtab_node)node); return node; |