mirror of
https://gcc.gnu.org/git/gcc.git
synced 2025-01-01 16:34:06 +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>
|
2013-06-12 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
* expr.c (expand_expr_real_1) <TARGET_MEM_REF>: Use straight-line flow.
|
* 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 *);
|
bool cgraph_optimize_for_size_p (struct cgraph_node *);
|
||||||
|
|
||||||
/* In varpool.c */
|
/* 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_decl (tree);
|
||||||
struct varpool_node *varpool_node_for_asm (tree asmname);
|
struct varpool_node *varpool_node_for_asm (tree asmname);
|
||||||
void varpool_mark_needed_node (struct varpool_node *);
|
void varpool_mark_needed_node (struct varpool_node *);
|
||||||
|
@ -959,7 +959,14 @@ input_node (struct lto_file_decl_data *file_data,
|
|||||||
vNULL, false);
|
vNULL, false);
|
||||||
}
|
}
|
||||||
else
|
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;
|
node->symbol.order = order;
|
||||||
if (order >= symtab_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;
|
order = streamer_read_hwi (ib) + order_base;
|
||||||
decl_index = streamer_read_uhwi (ib);
|
decl_index = streamer_read_uhwi (ib);
|
||||||
var_decl = lto_file_decl_data_get_var_decl (file_data, decl_index);
|
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;
|
node->symbol.order = order;
|
||||||
if (order >= symtab_order)
|
if (order >= symtab_order)
|
||||||
symtab_order = order + 1;
|
symtab_order = order + 1;
|
||||||
|
@ -569,6 +569,9 @@ struct GTY(()) lto_file_decl_data
|
|||||||
unsigned max_index;
|
unsigned max_index;
|
||||||
|
|
||||||
struct gcov_ctr_summary GTY((skip)) profile_info;
|
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;
|
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 ();
|
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)
|
FOR_EACH_SYMBOL (node)
|
||||||
if (lto_symtab_symbol_p (node)
|
if (lto_symtab_symbol_p (node)
|
||||||
&& node->symbol.next_sharing_asm_name
|
&& node->symbol.next_sharing_asm_name
|
||||||
&& !node->symbol.previous_sharing_asm_name)
|
&& !node->symbol.previous_sharing_asm_name)
|
||||||
lto_symtab_merge_symbols_1 (node);
|
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)
|
FOR_EACH_SYMBOL (node)
|
||||||
{
|
{
|
||||||
|
cgraph_node *cnode;
|
||||||
if (!node->symbol.analyzed && node->symbol.alias_target)
|
if (!node->symbol.analyzed && node->symbol.alias_target)
|
||||||
{
|
{
|
||||||
symtab_node tgt = symtab_node_for_asm (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);
|
symtab_resolve_alias (node, tgt);
|
||||||
}
|
}
|
||||||
node->symbol.aux = NULL;
|
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>
|
2013-06-11 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
* lto-partition.c (get_symbol_class): Simplify weakref handling.
|
* 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;
|
return LDPR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Map assigning declarations their resolutions. */
|
|
||||||
static pointer_map_t *resolution_map;
|
|
||||||
|
|
||||||
/* We need to record resolutions until symbol table is read. */
|
/* We need to record resolutions until symbol table is read. */
|
||||||
static void
|
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)
|
if (resolution == LDPR_UNKNOWN)
|
||||||
return;
|
return;
|
||||||
if (!resolution_map)
|
if (!file_data->resolution_map)
|
||||||
resolution_map = pointer_map_create ();
|
file_data->resolution_map = pointer_map_create ();
|
||||||
*pointer_map_insert (resolution_map, decl) = (void *)(size_t)resolution;
|
*pointer_map_insert (file_data->resolution_map, decl) = (void *)(size_t)resolution;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register DECL with the global symbol table and change its
|
/* 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;
|
unsigned ix;
|
||||||
if (!streamer_tree_cache_lookup (data_in->reader_cache, decl, &ix))
|
if (!streamer_tree_cache_lookup (data_in->reader_cache, decl, &ix))
|
||||||
gcc_unreachable ();
|
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;
|
unsigned ix;
|
||||||
if (!streamer_tree_cache_lookup (data_in->reader_cache, decl, &ix))
|
if (!streamer_tree_cache_lookup (data_in->reader_cache, decl, &ix))
|
||||||
gcc_unreachable ();
|
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;
|
struct cgraph_node *node;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
struct lto_file_decl_data **decl_data;
|
struct lto_file_decl_data **decl_data;
|
||||||
|
void **res;
|
||||||
|
symtab_node snode;
|
||||||
|
|
||||||
init_cgraph ();
|
init_cgraph ();
|
||||||
|
|
||||||
@ -2971,21 +2971,21 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
|
|||||||
input_symtab ();
|
input_symtab ();
|
||||||
|
|
||||||
/* Store resolutions into the symbol table. */
|
/* Store resolutions into the symbol table. */
|
||||||
if (resolution_map)
|
|
||||||
{
|
|
||||||
void **res;
|
|
||||||
symtab_node snode;
|
|
||||||
|
|
||||||
FOR_EACH_SYMBOL (snode)
|
FOR_EACH_SYMBOL (snode)
|
||||||
if (symtab_real_symbol_p (snode)
|
if (symtab_real_symbol_p (snode)
|
||||||
&& (res = pointer_map_contains (resolution_map,
|
&& snode->symbol.lto_file_data
|
||||||
snode->symbol.decl)))
|
&& snode->symbol.lto_file_data->resolution_map
|
||||||
snode->symbol.resolution
|
&& (res = pointer_map_contains (snode->symbol.lto_file_data->resolution_map,
|
||||||
= (enum ld_plugin_symbol_resolution)(size_t)*res;
|
snode->symbol.decl)))
|
||||||
|
snode->symbol.resolution
|
||||||
pointer_map_destroy (resolution_map);
|
= (enum ld_plugin_symbol_resolution)(size_t)*res;
|
||||||
resolution_map = NULL;
|
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);
|
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;
|
node->symbol.previous = NULL;
|
||||||
|
|
||||||
slot = htab_find_slot (symtab_hash, node, NO_INSERT);
|
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;
|
symtab_node replacement_node = NULL;
|
||||||
if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
|
if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
|
||||||
@ -291,10 +295,14 @@ symtab_get_node (const_tree decl)
|
|||||||
symtab_node *slot;
|
symtab_node *slot;
|
||||||
struct symtab_node_base key;
|
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
|
gcc_checking_assert (TREE_CODE (decl) == FUNCTION_DECL
|
||||||
|| (TREE_CODE (decl) == VAR_DECL
|
|| (TREE_CODE (decl) == VAR_DECL
|
||||||
&& (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
|
&& (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
|
||||||
|| in_lto_p)));
|
|| in_lto_p)));
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!symtab_hash)
|
if (!symtab_hash)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -36,18 +36,26 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
#include "tree-flow.h"
|
#include "tree-flow.h"
|
||||||
#include "flags.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. */
|
/* Return varpool node assigned to DECL. Create new one when needed. */
|
||||||
struct varpool_node *
|
struct varpool_node *
|
||||||
varpool_node_for_decl (tree decl)
|
varpool_node_for_decl (tree decl)
|
||||||
{
|
{
|
||||||
struct varpool_node *node = varpool_get_node (decl);
|
struct varpool_node *node = varpool_get_node (decl);
|
||||||
gcc_assert (TREE_CODE (decl) == VAR_DECL
|
gcc_checking_assert (TREE_CODE (decl) == VAR_DECL);
|
||||||
&& (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || in_lto_p));
|
|
||||||
if (node)
|
if (node)
|
||||||
return node;
|
return node;
|
||||||
|
|
||||||
node = ggc_alloc_cleared_varpool_node ();
|
node = varpool_create_empty_node ();
|
||||||
node->symbol.type = SYMTAB_VARIABLE;
|
|
||||||
node->symbol.decl = decl;
|
node->symbol.decl = decl;
|
||||||
symtab_register_node ((symtab_node)node);
|
symtab_register_node ((symtab_node)node);
|
||||||
return node;
|
return node;
|
||||||
|
Loading…
Reference in New Issue
Block a user