mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-29 22:15:03 +08:00
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
This commit is contained in:
parent
a53f90adbf
commit
bbf9ad070d
@ -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.
|
||||
|
@ -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 *);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
10
gcc/symtab.c
10
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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user