tree-core.h (tree_decl_with_vis): Replace comdat_group by symtab_node pointer.

* tree-core.h (tree_decl_with_vis): Replace comdat_group by
	symtab_node pointer.
	* tree.c (copy_node_stat): Be sure tonot copy
	symtab_node pointer.
	(find_decls_types_r): Do not walk COMDAT_GROUP.
	* tree.h (DECL_COMDAT_GROUP): Revamp to use decl_comdat_group.
	* varasm.c (make_decl_one_only): Use set_comdat_group;
	create node if needed.
	* ipa-inline-transform.c (save_inline_function_body): Update
	way we decl->symtab mapping.
	* symtab.c (symtab_hash, hash_node, eq_node
	symtab_insert_node_to_hashtable): Remove.
	(symtab_register_node): Update.
	(symtab_unregister_node): Update.
	(symtab_get_node): Reimplement as inline function.
	(symtab_add_to_same_comdat_group): Update.
	(symtab_dissolve_same_comdat_group_list): Update.
	(dump_symtab_base): Update.
	(verify_symtab_base): Update.
	(symtab_make_decl_local): Update.
	(fixup_same_cpp_alias_visibility): Update.
	(symtab_nonoverwritable_alias): Update.
	* cgraphclones.c (set_new_clone_decl_and_node_flags): Update.
	* ipa.c (update_visibility_by_resolution_info): UPdate.
	* bb-reorder.c: Include cgraph.h
	* lto-streamer-out.c (DFS_write_tree_body, hash_tree): Do not deal
	with comdat groups.
	* ipa-comdats.c (set_comdat_group, ipa_comdats): Update.
	* cgraph.c (cgraph_get_create_node): Update.
	* cgraph.h (struct symtab_node): Add get_comdat_group, set_comdat_group
	and comdat_group_.
	(symtab_get_node): Make inline.
	(symtab_insert_node_to_hashtable): Remove.
	(symtab_can_be_discarded): Update.
	(decl_comdat_group): New function.
	* tree-streamer-in.c (lto_input_ts_decl_with_vis_tree_pointers): Update.
	* lto-cgraph.c (lto_output_node, lto_output_varpool_node): Stream out
	comdat group name.
	(read_comdat_group): New function.
	(input_node, input_varpool_node): Use it.
	* trans-mem.c (ipa_tm_create_version_alias): Update code creating
	comdat groups.
	* mips.c (mips_start_unique_function): Likewise.
	(ix86_code_end): Likewise.
	(rs6000_code_end): Likweise.
	* tree-streamer-out.c (DECL_COMDAT_GROUP): Do not stream
	comdat group.

	* lto-symtab.c (lto_symtab_merge_symbols): Update code setting
	symtab pointer.
	* lto.c (compare_tree_sccs_1): Do not compare comdat groups.

	* optmize.c (maybe_thunk_body): Use set_comdat_group.
	(maybe_clone_body): Likewise.
	* decl.c (duplicate_decls): Update code duplicating comdat group;
	do not copy symtab pointer; before freeing newdecl remove it
	from symtab.
	* decl2.c (constrain_visibility): Use set_comdat_group.

	* c-decl.c (merge_decls): Preserve symtab node pointers.
	(duplicate_decls): Free new decl.

From-SVN: r210901
This commit is contained in:
Jan Hubicka 2014-05-25 00:00:14 +02:00 committed by Jan Hubicka
parent f3de79d43a
commit aede2c10ca
31 changed files with 352 additions and 177 deletions

View File

@ -1,3 +1,53 @@
2014-05-23 Jan Hubicka <hubicka@ucw.cz>
* tree-core.h (tree_decl_with_vis): Replace comdat_group by
symtab_node pointer.
* tree.c (copy_node_stat): Be sure tonot copy
symtab_node pointer.
(find_decls_types_r): Do not walk COMDAT_GROUP.
* tree.h (DECL_COMDAT_GROUP): Revamp to use decl_comdat_group.
* varasm.c (make_decl_one_only): Use set_comdat_group;
create node if needed.
* ipa-inline-transform.c (save_inline_function_body): Update
way we decl->symtab mapping.
* symtab.c (symtab_hash, hash_node, eq_node
symtab_insert_node_to_hashtable): Remove.
(symtab_register_node): Update.
(symtab_unregister_node): Update.
(symtab_get_node): Reimplement as inline function.
(symtab_add_to_same_comdat_group): Update.
(symtab_dissolve_same_comdat_group_list): Update.
(dump_symtab_base): Update.
(verify_symtab_base): Update.
(symtab_make_decl_local): Update.
(fixup_same_cpp_alias_visibility): Update.
(symtab_nonoverwritable_alias): Update.
* cgraphclones.c (set_new_clone_decl_and_node_flags): Update.
* ipa.c (update_visibility_by_resolution_info): UPdate.
* bb-reorder.c: Include cgraph.h
* lto-streamer-out.c (DFS_write_tree_body, hash_tree): Do not deal
with comdat groups.
* ipa-comdats.c (set_comdat_group, ipa_comdats): Update.
* cgraph.c (cgraph_get_create_node): Update.
* cgraph.h (struct symtab_node): Add get_comdat_group, set_comdat_group
and comdat_group_.
(symtab_get_node): Make inline.
(symtab_insert_node_to_hashtable): Remove.
(symtab_can_be_discarded): Update.
(decl_comdat_group): New function.
* tree-streamer-in.c (lto_input_ts_decl_with_vis_tree_pointers): Update.
* lto-cgraph.c (lto_output_node, lto_output_varpool_node): Stream out
comdat group name.
(read_comdat_group): New function.
(input_node, input_varpool_node): Use it.
* trans-mem.c (ipa_tm_create_version_alias): Update code creating
comdat groups.
* mips.c (mips_start_unique_function): Likewise.
(ix86_code_end): Likewise.
(rs6000_code_end): Likweise.
* tree-streamer-out.c (DECL_COMDAT_GROUP): Do not stream
comdat group.
2014-05-23 Jan Hubicka <hubicka@ucw.cz>
* gengtype-state.c (fatal_reading_state): Bring offline.

View File

@ -99,6 +99,7 @@
#include "tree-pass.h"
#include "df.h"
#include "bb-reorder.h"
#include "cgraph.h"
#include "except.h"
/* The number of rounds. In most cases there will only be 4 rounds, but

View File

@ -1,3 +1,8 @@
2014-05-23 Jan Hubicka <hubicka@ucw.cz>
* c-decl.c (merge_decls): Preserve symtab node pointers.
(duplicate_decls): Free new decl.
2014-05-23 Thomas Schwinge <thomas@codesourcery.com>
* c-typeck.c (c_finish_omp_clauses): Remove duplicated variable

View File

@ -2507,8 +2507,18 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
switch (TREE_CODE (olddecl))
{
case FUNCTION_DECL:
case FIELD_DECL:
case VAR_DECL:
{
struct symtab_node *snode = olddecl->decl_with_vis.symtab_node;
memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
(char *) newdecl + sizeof (struct tree_decl_common),
tree_code_size (TREE_CODE (olddecl)) - sizeof (struct tree_decl_common));
olddecl->decl_with_vis.symtab_node = snode;
break;
}
case FIELD_DECL:
case PARM_DECL:
case LABEL_DECL:
case RESULT_DECL:
@ -2561,6 +2571,9 @@ duplicate_decls (tree newdecl, tree olddecl)
}
merge_decls (newdecl, olddecl, newtype, oldtype);
/* The NEWDECL will no longer be needed. */
ggc_free (newdecl);
return true;
}

View File

@ -565,7 +565,7 @@ cgraph_get_create_node (tree decl)
first_clone->clone_of = node;
node->clones = first_clone;
symtab_prevail_in_asm_name_hash (node);
symtab_insert_node_to_hashtable (node);
node->decl->decl_with_vis.symtab_node = node;
if (dump_file)
fprintf (dump_file, "Introduced new external node "
"(%s/%i) and turned into root of the clone tree.\n",
@ -2267,6 +2267,7 @@ cgraph_make_node_local_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
node->externally_visible = false;
node->forced_by_abi = false;
node->local.local = true;
node->set_comdat_group (NULL);
node->unique_name = (node->resolution == LDPR_PREVAILING_DEF_IRONLY
|| node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP);
node->resolution = LDPR_PREVAILING_DEF_IRONLY;

View File

@ -141,6 +141,18 @@ public:
/* Circular list of nodes in the same comdat group if non-NULL. */
symtab_node *same_comdat_group;
/* Return comdat group. */
tree get_comdat_group ()
{
return comdat_group_;
}
/* Set comdat group. */
void set_comdat_group (tree group)
{
comdat_group_ = group;
}
/* Vectors of referring and referenced entities. */
struct ipa_ref_list ref_list;
@ -153,6 +165,9 @@ public:
struct lto_file_decl_data * lto_file_data;
PTR GTY ((skip)) aux;
/* Comdat group the symbol is in. Can be private if GGC allowed that. */
tree comdat_group_;
};
enum availability
@ -727,9 +742,7 @@ void symtab_register_node (symtab_node *);
void symtab_unregister_node (symtab_node *);
void symtab_remove_from_same_comdat_group (symtab_node *);
void symtab_remove_node (symtab_node *);
symtab_node *symtab_get_node (const_tree);
symtab_node *symtab_node_for_asm (const_tree asmname);
void symtab_insert_node_to_hashtable (symtab_node *);
void symtab_add_to_same_comdat_group (symtab_node *, symtab_node *);
void symtab_dissolve_same_comdat_group_list (symtab_node *node);
void dump_symtab (FILE *);
@ -989,6 +1002,28 @@ void varpool_remove_initializer (varpool_node *);
/* In cgraph.c */
extern void change_decl_assembler_name (tree, tree);
/* Return symbol table node associated with DECL, if any,
and NULL otherwise. */
static inline symtab_node *
symtab_get_node (const_tree decl)
{
#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)));
/* Check that the mapping is sane - perhaps this check can go away,
but at the moment frontends tends to corrupt the mapping by calling
memcpy/memset on the tree nodes. */
gcc_checking_assert (!decl->decl_with_vis.symtab_node
|| decl->decl_with_vis.symtab_node->decl == decl);
#endif
return decl->decl_with_vis.symtab_node;
}
/* Return callgraph node for given symbol and check it is a function. */
static inline struct cgraph_node *
cgraph (symtab_node *node)
@ -1548,7 +1583,7 @@ static inline bool
symtab_can_be_discarded (symtab_node *node)
{
return (DECL_EXTERNAL (node->decl)
|| (DECL_ONE_ONLY (node->decl)
|| (node->get_comdat_group ()
&& node->resolution != LDPR_PREVAILING_DEF
&& node->resolution != LDPR_PREVAILING_DEF_IRONLY
&& node->resolution != LDPR_PREVAILING_DEF_IRONLY_EXP));
@ -1580,6 +1615,16 @@ symtab_in_same_comdat_p (symtab_node *one, symtab_node *two)
two = cn->global.inlined_to;
}
return DECL_COMDAT_GROUP (one->decl) == DECL_COMDAT_GROUP (two->decl);
return one->get_comdat_group () == two->get_comdat_group ();
}
/* Return comdat group of DECL. */
static inline tree
decl_comdat_group (tree node)
{
struct symtab_node *snode = symtab_get_node (node);
if (!snode)
return NULL;
return snode->get_comdat_group ();
}
#endif /* GCC_CGRAPH_H */

View File

@ -283,7 +283,6 @@ static void
set_new_clone_decl_and_node_flags (cgraph_node *new_node)
{
DECL_EXTERNAL (new_node->decl) = 0;
DECL_COMDAT_GROUP (new_node->decl) = 0;
TREE_PUBLIC (new_node->decl) = 0;
DECL_COMDAT (new_node->decl) = 0;
DECL_WEAK (new_node->decl) = 0;
@ -558,7 +557,7 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
that is not weak also.
??? We cannot use COMDAT linkage because there is no
ABI support for this. */
if (DECL_COMDAT_GROUP (old_decl))
if (old_node->get_comdat_group ())
DECL_SECTION_NAME (new_node->decl) = NULL;
set_new_clone_decl_and_node_flags (new_node);
new_node->clone.tree_map = tree_map;

View File

@ -499,7 +499,7 @@ cgraph_add_new_function (tree fndecl, bool lowered)
break;
case CGRAPH_STATE_CONSTRUCTION:
/* Just enqueue function to be processed at nearest occurrence. */
node = cgraph_create_node (fndecl);
node = cgraph_get_create_node (fndecl);
if (lowered)
node->lowered = true;
if (!cgraph_new_nodes)

View File

@ -9183,7 +9183,7 @@ ix86_code_end (void)
#endif
if (USE_HIDDEN_LINKONCE)
{
DECL_COMDAT_GROUP (decl) = DECL_ASSEMBLER_NAME (decl);
cgraph_create_node (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
targetm.asm_out.unique_section (decl, 0);
switch_to_section (get_named_section (decl, NULL, 0));

View File

@ -6275,7 +6275,7 @@ mips_start_unique_function (const char *name)
TREE_PUBLIC (decl) = 1;
TREE_STATIC (decl) = 1;
DECL_COMDAT_GROUP (decl) = DECL_ASSEMBLER_NAME (decl);
cgraph_create_node (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
targetm.asm_out.unique_section (decl, 0);
switch_to_section (get_named_section (decl, NULL, 0));

View File

@ -32331,7 +32331,7 @@ rs6000_code_end (void)
#if RS6000_WEAK
if (USE_HIDDEN_LINKONCE)
{
DECL_COMDAT_GROUP (decl) = DECL_ASSEMBLER_NAME (decl);
cgraph_create_node (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
targetm.asm_out.unique_section (decl, 0);
switch_to_section (get_named_section (decl, NULL, 0));
DECL_WEAK (decl) = 1;

View File

@ -1,3 +1,12 @@
2014-05-23 Jan Hubicka <hubicka@ucw.cz>
* optmize.c (maybe_thunk_body): Use set_comdat_group.
(maybe_clone_body): Likewise.
* decl.c (duplicate_decls): Update code duplicating comdat group;
do not copy symtab pointer; before freeing newdecl remove it
from symtab.
* decl2.c (constrain_visibility): Use set_comdat_group.
2014-05-23 Jan Hubicka <hubicka@ucw.cz>
* rtti.c: Include tm_p.h

View File

@ -2065,8 +2065,17 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
/* Merge the storage class information. */
merge_weak (newdecl, olddecl);
if (DECL_ONE_ONLY (olddecl))
DECL_COMDAT_GROUP (newdecl) = DECL_COMDAT_GROUP (olddecl);
if ((TREE_CODE (olddecl) == FUNCTION_DECL || TREE_CODE (olddecl) == VAR_DECL)
&& (DECL_EXTERNAL (olddecl) || TREE_PUBLIC (olddecl) || TREE_STATIC (olddecl))
&& DECL_ONE_ONLY (olddecl))
{
struct symtab_node *symbol;
if (TREE_CODE (olddecl) == FUNCTION_DECL)
symbol = cgraph_get_create_node (newdecl);
else
symbol = varpool_node_for_decl (newdecl);
symbol->set_comdat_group (symtab_get_node (olddecl)->get_comdat_group ());
}
DECL_DEFER_OUTPUT (newdecl) |= DECL_DEFER_OUTPUT (olddecl);
TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
@ -2376,6 +2385,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
int function_size;
struct symtab_node *snode = symtab_get_node (olddecl);
function_size = sizeof (struct tree_decl_common);
@ -2386,6 +2396,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
(char *) newdecl + sizeof (struct tree_decl_common),
sizeof (struct tree_function_decl) - sizeof (struct tree_decl_common));
/* Preserve symtab node mapping. */
olddecl->decl_with_vis.symtab_node = snode;
if (new_template_info)
/* If newdecl is a template instantiation, it is possible that
the following sequence of events has occurred:
@ -2415,6 +2429,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
else
{
size_t size = tree_code_size (TREE_CODE (olddecl));
memcpy ((char *) olddecl + sizeof (struct tree_common),
(char *) newdecl + sizeof (struct tree_common),
sizeof (struct tree_decl_common) - sizeof (struct tree_common));
@ -2428,10 +2443,17 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
case TYPE_DECL:
case CONST_DECL:
{
struct symtab_node *snode = NULL;
if (TREE_CODE (olddecl) == VAR_DECL
&& (TREE_STATIC (olddecl) || TREE_PUBLIC (olddecl) || DECL_EXTERNAL (olddecl)))
snode = symtab_get_node (olddecl);
memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
(char *) newdecl + sizeof (struct tree_decl_common),
size - sizeof (struct tree_decl_common)
+ TREE_CODE_LENGTH (TREE_CODE (newdecl)) * sizeof (char *));
if (TREE_CODE (olddecl) == VAR_DECL)
olddecl->decl_with_vis.symtab_node = snode;
}
break;
default:
@ -2466,7 +2488,21 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
/* The NEWDECL will no longer be needed. Because every out-of-class
declaration of a member results in a call to duplicate_decls,
freeing these nodes represents in a significant savings. */
freeing these nodes represents in a significant savings.
Before releasing the node, be sore to remove function from symbol
table that might have been inserted there to record comdat group.
Be sure to however do not free DECL_STRUCT_FUNCTION becuase this
structure is shared in between newdecl and oldecl. */
if (TREE_CODE (newdecl) == FUNCTION_DECL)
DECL_STRUCT_FUNCTION (newdecl) = NULL;
if (TREE_CODE (newdecl) == FUNCTION_DECL
|| TREE_CODE (newdecl) == VAR_DECL)
{
struct symtab_node *snode = symtab_get_node (newdecl);
if (snode)
symtab_remove_node (snode);
}
ggc_free (newdecl);
return olddecl;

View File

@ -2093,7 +2093,14 @@ constrain_visibility (tree decl, int visibility, bool tmpl)
TREE_PUBLIC (decl) = 0;
DECL_WEAK (decl) = 0;
DECL_COMMON (decl) = 0;
DECL_COMDAT_GROUP (decl) = NULL_TREE;
if (TREE_CODE (decl) == FUNCTION_DECL
|| TREE_CODE (decl) == VAR_DECL)
{
struct symtab_node *snode = symtab_get_node (decl);
if (snode)
snode->set_comdat_group (NULL);
}
DECL_INTERFACE_KNOWN (decl) = 1;
if (DECL_LANG_SPECIFIC (decl))
DECL_NOT_REALLY_EXTERN (decl) = 1;

View File

@ -285,7 +285,7 @@ maybe_thunk_body (tree fn, bool force)
else if (HAVE_COMDAT_GROUP)
{
tree comdat_group = cdtor_comdat_group (fns[1], fns[0]);
DECL_COMDAT_GROUP (fns[0]) = comdat_group;
cgraph_get_create_node (fns[0])->set_comdat_group (comdat_group);
symtab_add_to_same_comdat_group (cgraph_get_create_node (fns[1]),
cgraph_get_create_node (fns[0]));
symtab_add_to_same_comdat_group (symtab_get_node (fn),
@ -473,7 +473,7 @@ maybe_clone_body (tree fn)
name of fn was corrupted by write_mangled_name by adding *INTERNAL*
to it. By doing so, it also corrupted the comdat group. */
if (DECL_ONE_ONLY (fn))
DECL_COMDAT_GROUP (clone) = cxx_comdat_group (clone);
cgraph_get_create_node (clone)->set_comdat_group (cxx_comdat_group (clone));
DECL_SECTION_NAME (clone) = DECL_SECTION_NAME (fn);
DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
@ -550,7 +550,7 @@ maybe_clone_body (tree fn)
into the same, *[CD]5* comdat group instead of
*[CD][12]*. */
comdat_group = cdtor_comdat_group (fns[1], fns[0]);
DECL_COMDAT_GROUP (fns[0]) = comdat_group;
cgraph_get_create_node (fns[0])->set_comdat_group (comdat_group);
symtab_add_to_same_comdat_group (symtab_get_node (clone),
symtab_get_node (fns[0]));
}

View File

@ -202,8 +202,8 @@ set_comdat_group (symtab_node *symbol,
{
symtab_node *head = (symtab_node *)head_p;
gcc_assert (!DECL_COMDAT_GROUP (symbol->decl));
DECL_COMDAT_GROUP (symbol->decl) = DECL_COMDAT_GROUP (head->decl);
gcc_assert (!symbol->get_comdat_group ());
symbol->set_comdat_group (head->get_comdat_group ());
symtab_add_to_same_comdat_group (symbol, head);
return false;
}
@ -218,6 +218,7 @@ ipa_comdats (void)
symtab_node *symbol;
bool comdat_group_seen = false;
symtab_node *first = (symtab_node *) (void *) 1;
tree group;
/* Start the dataflow by assigning comdat group to symbols that are in comdat
groups already. All other externally visible symbols must stay, we use
@ -226,10 +227,10 @@ ipa_comdats (void)
FOR_EACH_DEFINED_SYMBOL (symbol)
if (!symtab_real_symbol_p (symbol))
;
else if (DECL_COMDAT_GROUP (symbol->decl))
else if ((group = symbol->get_comdat_group ()) != NULL)
{
*map.insert (symbol) = DECL_COMDAT_GROUP (symbol->decl);
*comdat_head_map.insert (DECL_COMDAT_GROUP (symbol->decl)) = symbol;
*map.insert (symbol) = group;
*comdat_head_map.insert (group) = symbol;
comdat_group_seen = true;
/* Mark the symbol so we won't waste time visiting it for dataflow. */
@ -313,7 +314,7 @@ ipa_comdats (void)
FOR_EACH_DEFINED_SYMBOL (symbol)
{
symbol->aux = NULL;
if (!DECL_COMDAT_GROUP (symbol->decl)
if (!symbol->get_comdat_group ()
&& !symbol->alias
&& symtab_real_symbol_p (symbol))
{

View File

@ -341,7 +341,7 @@ save_inline_function_body (struct cgraph_node *node)
/* first_clone will be turned into real function. */
first_clone = node->clones;
first_clone->decl = copy_node (node->decl);
symtab_insert_node_to_hashtable (first_clone);
first_clone->decl->decl_with_vis.symtab_node = first_clone;
gcc_assert (first_clone == cgraph_get_node (first_clone->decl));
/* Now reshape the clone tree, so all other clones descends from

View File

@ -1021,13 +1021,13 @@ update_visibility_by_resolution_info (symtab_node * node)
for (symtab_node *next = node->same_comdat_group;
next != node; next = next->same_comdat_group)
{
DECL_COMDAT_GROUP (next->decl) = NULL;
next->set_comdat_group (NULL);
DECL_WEAK (next->decl) = false;
if (next->externally_visible
&& !define)
DECL_EXTERNAL (next->decl) = true;
}
DECL_COMDAT_GROUP (node->decl) = NULL;
node->set_comdat_group (NULL);
DECL_WEAK (node->decl) = false;
if (!define)
DECL_EXTERNAL (node->decl) = true;
@ -1135,11 +1135,12 @@ function_and_variable_visibility (bool whole_program)
next != node;
next = next->same_comdat_group)
{
next->set_comdat_group (NULL);
symtab_make_decl_local (next->decl);
next->unique_name = ((next->resolution == LDPR_PREVAILING_DEF_IRONLY
|| next->unique_name
|| next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
&& TREE_PUBLIC (next->decl));
&& TREE_PUBLIC (next->decl));
}
/* cgraph_externally_visible_p has already checked all other nodes
in the group and they will all be made local. We need to
@ -1147,6 +1148,8 @@ function_and_variable_visibility (bool whole_program)
segfault though. */
symtab_dissolve_same_comdat_group_list (node);
}
if (TREE_PUBLIC (node->decl))
node->set_comdat_group (NULL);
symtab_make_decl_local (node->decl);
}
@ -1163,8 +1166,7 @@ function_and_variable_visibility (bool whole_program)
{
gcc_checking_assert (DECL_COMDAT (node->decl)
== DECL_COMDAT (decl_node->decl));
gcc_checking_assert (DECL_COMDAT_GROUP (node->decl)
== DECL_COMDAT_GROUP (decl_node->decl));
gcc_checking_assert (symtab_in_same_comdat_p (node, decl_node));
gcc_checking_assert (node->same_comdat_group);
}
node->forced_by_abi = decl_node->forced_by_abi;
@ -1254,9 +1256,28 @@ function_and_variable_visibility (bool whole_program)
vnode->unique_name = ((vnode->resolution == LDPR_PREVAILING_DEF_IRONLY
|| vnode->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
&& TREE_PUBLIC (vnode->decl));
if (vnode->same_comdat_group && TREE_PUBLIC (vnode->decl))
{
symtab_node *next = vnode;
/* Set all members of comdat group local. */
if (vnode->same_comdat_group)
for (next = vnode->same_comdat_group;
next != vnode;
next = next->same_comdat_group)
{
next->set_comdat_group (NULL);
symtab_make_decl_local (next->decl);
next->unique_name = ((next->resolution == LDPR_PREVAILING_DEF_IRONLY
|| next->unique_name
|| next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
&& TREE_PUBLIC (next->decl));
}
symtab_dissolve_same_comdat_group_list (vnode);
}
if (TREE_PUBLIC (vnode->decl))
vnode->set_comdat_group (NULL);
symtab_make_decl_local (vnode->decl);
if (vnode->same_comdat_group)
symtab_dissolve_same_comdat_group_list (vnode);
vnode->resolution = LDPR_PREVAILING_DEF_IRONLY;
}
update_visibility_by_resolution_info (vnode);

View File

@ -395,6 +395,8 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
ipa_opt_pass_d *pass;
int i;
bool alias_p;
const char *comdat;
tree group;
boundary_p = !lto_symtab_encoder_in_partition_p (encoder, node);
@ -478,15 +480,24 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
streamer_write_hwi_stream (ob->main_stream, ref);
}
if (node->same_comdat_group && !boundary_p)
{
ref = lto_symtab_encoder_lookup (encoder,
node->same_comdat_group);
gcc_assert (ref != LCC_NOT_FOUND);
}
group = node->get_comdat_group ();
if (group)
comdat = IDENTIFIER_POINTER (group);
else
ref = LCC_NOT_FOUND;
streamer_write_hwi_stream (ob->main_stream, ref);
comdat = "";
lto_output_data_stream (ob->main_stream, comdat, strlen (comdat) + 1);
if (group)
{
if (node->same_comdat_group && !boundary_p)
{
ref = lto_symtab_encoder_lookup (encoder,
node->same_comdat_group);
gcc_assert (ref != LCC_NOT_FOUND);
}
else
ref = LCC_NOT_FOUND;
streamer_write_hwi_stream (ob->main_stream, ref);
}
streamer_write_hwi_stream (ob->main_stream, node->tp_first_run);
@ -551,6 +562,8 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node,
struct bitpack_d bp;
int ref;
bool alias_p;
const char *comdat;
tree group;
streamer_write_enum (ob->main_stream, LTO_symtab_tags, LTO_symtab_last_tag,
LTO_symtab_variable);
@ -587,15 +600,24 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node,
/* in_other_partition. */
}
streamer_write_bitpack (&bp);
if (node->same_comdat_group && !boundary_p)
{
ref = lto_symtab_encoder_lookup (encoder,
node->same_comdat_group);
gcc_assert (ref != LCC_NOT_FOUND);
}
group = node->get_comdat_group ();
if (group)
comdat = IDENTIFIER_POINTER (group);
else
ref = LCC_NOT_FOUND;
streamer_write_hwi_stream (ob->main_stream, ref);
comdat = "";
lto_output_data_stream (ob->main_stream, comdat, strlen (comdat) + 1);
if (group)
{
if (node->same_comdat_group && !boundary_p)
{
ref = lto_symtab_encoder_lookup (encoder,
node->same_comdat_group);
gcc_assert (ref != LCC_NOT_FOUND);
}
else
ref = LCC_NOT_FOUND;
streamer_write_hwi_stream (ob->main_stream, ref);
}
streamer_write_enum (ob->main_stream, ld_plugin_symbol_resolution,
LDPR_NUM_KNOWN, node->resolution);
}
@ -946,6 +968,26 @@ output_symtab (void)
output_refs (encoder);
}
/* Return COMDAT_GROUP encoded in IB as a plain string. */
static tree
read_comdat_group (struct lto_input_block *ib)
{
unsigned int len = strnlen (ib->data + ib->p, ib->len - ib->p - 1);
tree group;
if (ib->data[ib->p + len])
lto_section_overrun (ib);
if (!len)
{
ib->p++;
return NULL;
}
group = get_identifier (ib->data + ib->p);
ib->p += len + 1;
return group;
}
/* Overwrite the information in NODE based on FILE_DATA, TAG, FLAGS,
STACK_SIZE, SELF_TIME and SELF_SIZE. This is called either to initialize
NODE or to replace the values in it, for instance because the first
@ -1034,6 +1076,7 @@ input_node (struct lto_file_decl_data *file_data,
int clone_ref;
int order;
int i, count;
tree group;
order = streamer_read_hwi (ib) + order_base;
clone_ref = streamer_read_hwi (ib);
@ -1079,7 +1122,9 @@ input_node (struct lto_file_decl_data *file_data,
if (tag == LTO_symtab_analyzed_node)
ref = streamer_read_hwi (ib);
ref2 = streamer_read_hwi (ib);
group = read_comdat_group (ib);
if (group)
ref2 = streamer_read_hwi (ib);
/* Make sure that we have not read this node before. Nodes that
have already been read will have their tag stored in the 'aux'
@ -1098,8 +1143,14 @@ input_node (struct lto_file_decl_data *file_data,
/* Store a reference for now, and fix up later to be a pointer. */
node->global.inlined_to = (cgraph_node_ptr) (intptr_t) ref;
/* Store a reference for now, and fix up later to be a pointer. */
node->same_comdat_group = (symtab_node *) (intptr_t) ref2;
if (group)
{
node->set_comdat_group (group);
/* Store a reference for now, and fix up later to be a pointer. */
node->same_comdat_group = (symtab_node *) (intptr_t) ref2;
}
else
node->same_comdat_group = (symtab_node *) (intptr_t) LCC_NOT_FOUND;
if (node->thunk.thunk_p)
{
@ -1131,6 +1182,7 @@ input_varpool_node (struct lto_file_decl_data *file_data,
struct bitpack_d bp;
int ref = LCC_NOT_FOUND;
int order;
tree group;
order = streamer_read_hwi (ib) + order_base;
decl_index = streamer_read_uhwi (ib);
@ -1168,9 +1220,16 @@ input_varpool_node (struct lto_file_decl_data *file_data,
}
if (node->alias && !node->analyzed && node->weakref)
node->alias_target = get_alias_symbol (node->decl);
ref = streamer_read_hwi (ib);
/* Store a reference for now, and fix up later to be a pointer. */
node->same_comdat_group = (symtab_node *) (intptr_t) ref;
group = read_comdat_group (ib);
if (group)
{
node->set_comdat_group (group);
ref = streamer_read_hwi (ib);
/* Store a reference for now, and fix up later to be a pointer. */
node->same_comdat_group = (symtab_node *) (intptr_t) ref;
}
else
node->same_comdat_group = (symtab_node *) (intptr_t) LCC_NOT_FOUND;
node->resolution = streamer_read_enum (ib, ld_plugin_symbol_resolution,
LDPR_NUM_KNOWN);
gcc_assert (flag_ltrans

View File

@ -535,7 +535,6 @@ DFS_write_tree_body (struct output_block *ob,
if (DECL_ASSEMBLER_NAME_SET_P (expr))
DFS_follow_tree_edge (DECL_ASSEMBLER_NAME (expr));
DFS_follow_tree_edge (DECL_SECTION_NAME (expr));
DFS_follow_tree_edge (DECL_COMDAT_GROUP (expr));
}
if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))
@ -974,7 +973,6 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
if (DECL_ASSEMBLER_NAME_SET_P (t))
visit (DECL_ASSEMBLER_NAME (t));
visit (DECL_SECTION_NAME (t));
visit (DECL_COMDAT_GROUP (t));
}
if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))

View File

@ -1,3 +1,9 @@
2014-05-23 Jan Hubicka <hubicka@ucw.cz>
* lto-symtab.c (lto_symtab_merge_symbols): Update code setting
symtab pointer.
* lto.c (compare_tree_sccs_1): Do not compare comdat groups.
2014-05-22 Thomas Schwinge <thomas@codesourcery.com>
* lto-lang.c (DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_6)

View File

@ -644,7 +644,7 @@ lto_symtab_merge_symbols (void)
&& cnode2 != cnode)
cgraph_remove_node (cnode2);
symtab_insert_node_to_hashtable (node);
node->decl->decl_with_vis.symtab_node = node;
}
}
}

View File

@ -1530,7 +1530,6 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
compare_tree_edges (DECL_ASSEMBLER_NAME (t1),
DECL_ASSEMBLER_NAME (t2));
compare_tree_edges (DECL_SECTION_NAME (t1), DECL_SECTION_NAME (t2));
compare_tree_edges (DECL_COMDAT_GROUP (t1), DECL_COMDAT_GROUP (t2));
}
if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))

View File

@ -57,8 +57,6 @@ const char * const ld_plugin_symbol_resolution_names[]=
"prevailing_def_ironly_exp"
};
/* Hash table used to convert declarations into nodes. */
static GTY((param_is (symtab_node))) htab_t symtab_hash;
/* Hash table used to convert assembler names into nodes. */
static GTY((param_is (symtab_node))) htab_t assembler_name_hash;
@ -70,26 +68,6 @@ symtab_node *symtab_nodes;
them, to support -fno-toplevel-reorder. */
int symtab_order;
/* Returns a hash code for P. */
static hashval_t
hash_node (const void *p)
{
const symtab_node *n = (const symtab_node *) p;
return (hashval_t) DECL_UID (n->decl);
}
/* Returns nonzero if P1 and P2 are equal. */
static int
eq_node (const void *p1, const void *p2)
{
const symtab_node *n1 = (const symtab_node *) p1;
const symtab_node *n2 = (const symtab_node *) p2;
return DECL_UID (n1->decl) == DECL_UID (n2->decl);
}
/* Hash asmnames ignoring the user specified marks. */
static hashval_t
@ -282,21 +260,14 @@ symtab_prevail_in_asm_name_hash (symtab_node *node)
void
symtab_register_node (symtab_node *node)
{
struct symtab_node key;
symtab_node **slot;
node->next = symtab_nodes;
node->previous = NULL;
if (symtab_nodes)
symtab_nodes->previous = node;
symtab_nodes = node;
if (!symtab_hash)
symtab_hash = htab_create_ggc (10, hash_node, eq_node, NULL);
key.decl = node->decl;
slot = (symtab_node **) htab_find_slot (symtab_hash, &key, INSERT);
if (*slot == NULL)
*slot = node;
if (!node->decl->decl_with_vis.symtab_node)
node->decl->decl_with_vis.symtab_node = node;
ipa_empty_ref_list (&node->ref_list);
@ -307,22 +278,6 @@ symtab_register_node (symtab_node *node)
insert_to_assembler_name_hash (node, false);
}
/* Make NODE to be the one symtab hash is pointing to. Used when reshaping tree
of inline clones. */
void
symtab_insert_node_to_hashtable (symtab_node *node)
{
struct symtab_node key;
symtab_node **slot;
if (!symtab_hash)
symtab_hash = htab_create_ggc (10, hash_node, eq_node, NULL);
key.decl = node->decl;
slot = (symtab_node **) htab_find_slot (symtab_hash, &key, INSERT);
*slot = node;
}
/* Remove NODE from same comdat group. */
void
@ -349,7 +304,6 @@ symtab_remove_from_same_comdat_group (symtab_node *node)
void
symtab_unregister_node (symtab_node *node)
{
void **slot;
ipa_remove_all_references (&node->ref_list);
ipa_remove_all_referring (&node->ref_list);
@ -364,55 +318,20 @@ symtab_unregister_node (symtab_node *node)
node->next = NULL;
node->previous = NULL;
slot = htab_find_slot (symtab_hash, node, NO_INSERT);
/* During LTO symtab merging we temporarily corrupt decl to symtab node
hash. */
gcc_assert ((slot && *slot) || in_lto_p);
if (slot && *slot && *slot == node)
gcc_assert (node->decl->decl_with_vis.symtab_node || in_lto_p);
if (node->decl->decl_with_vis.symtab_node == node)
{
symtab_node *replacement_node = NULL;
if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
replacement_node = cgraph_find_replacement_node (cnode);
if (!replacement_node)
htab_clear_slot (symtab_hash, slot);
else
*slot = replacement_node;
node->decl->decl_with_vis.symtab_node = replacement_node;
}
if (!is_a <varpool_node *> (node) || !DECL_HARD_REGISTER (node->decl))
unlink_from_assembler_name_hash (node, false);
}
/* Return symbol table node associated with DECL, if any,
and NULL otherwise. */
symtab_node *
symtab_get_node (const_tree decl)
{
symtab_node **slot;
struct symtab_node 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;
key.decl = CONST_CAST2 (tree, const_tree, decl);
slot = (symtab_node **) htab_find_slot (symtab_hash, &key,
NO_INSERT);
if (slot)
return *slot;
return NULL;
}
/* Remove symtab NODE from the symbol table. */
@ -513,11 +432,11 @@ void
symtab_add_to_same_comdat_group (symtab_node *new_node,
symtab_node *old_node)
{
gcc_assert (DECL_COMDAT_GROUP (old_node->decl));
gcc_assert (old_node->get_comdat_group ());
gcc_assert (!new_node->same_comdat_group);
gcc_assert (new_node != old_node);
DECL_COMDAT_GROUP (new_node->decl) = DECL_COMDAT_GROUP (old_node->decl);
new_node->set_comdat_group (old_node->get_comdat_group ());
new_node->same_comdat_group = old_node;
if (!old_node->same_comdat_group)
old_node->same_comdat_group = new_node;
@ -546,10 +465,10 @@ symtab_dissolve_same_comdat_group_list (symtab_node *node)
{
next = n->same_comdat_group;
n->same_comdat_group = NULL;
/* Clear DECL_COMDAT_GROUP for comdat locals, since
/* Clear comdat_group for comdat locals, since
make_decl_local doesn't. */
if (!TREE_PUBLIC (n->decl))
DECL_COMDAT_GROUP (n->decl) = NULL_TREE;
n->set_comdat_group (NULL);
n = next;
}
while (n != node);
@ -639,9 +558,9 @@ dump_symtab_base (FILE *f, symtab_node *node)
fprintf (f, " dll_import");
if (DECL_COMDAT (node->decl))
fprintf (f, " comdat");
if (DECL_COMDAT_GROUP (node->decl))
if (node->get_comdat_group ())
fprintf (f, " comdat_group:%s",
IDENTIFIER_POINTER (DECL_COMDAT_GROUP (node->decl)));
IDENTIFIER_POINTER (node->get_comdat_group ()));
if (DECL_ONE_ONLY (node->decl))
fprintf (f, " one_only");
if (DECL_SECTION_NAME (node->decl))
@ -766,7 +685,7 @@ verify_symtab_base (symtab_node *node)
hashed_node = symtab_get_node (node->decl);
if (!hashed_node)
{
error ("node not found in symtab decl hashtable");
error ("node not found node->decl->decl_with_vis.symtab_node");
error_found = true;
}
if (hashed_node != node
@ -775,7 +694,7 @@ verify_symtab_base (symtab_node *node)
|| dyn_cast <cgraph_node *> (node)->clone_of->decl
!= node->decl))
{
error ("node differs from symtab decl hashtable");
error ("node differs from node->decl->decl_with_vis.symtab_node");
error_found = true;
}
}
@ -832,12 +751,12 @@ verify_symtab_base (symtab_node *node)
{
symtab_node *n = node->same_comdat_group;
if (!DECL_COMDAT_GROUP (n->decl))
if (!n->get_comdat_group ())
{
error ("node is in same_comdat_group list but has no DECL_COMDAT_GROUP");
error ("node is in same_comdat_group list but has no comdat_group");
error_found = true;
}
if (DECL_COMDAT_GROUP (n->decl) != DECL_COMDAT_GROUP (node->same_comdat_group->decl))
if (n->get_comdat_group () != node->get_comdat_group ())
{
error ("same_comdat_group list across different groups");
error_found = true;
@ -950,7 +869,7 @@ symtab_make_decl_local (tree decl)
{
rtx rtl, symbol;
/* Avoid clearing DECL_COMDAT_GROUP on comdat-local decls. */
/* Avoid clearing comdat_groups on comdat-local decls. */
if (TREE_PUBLIC (decl) == 0)
return;
@ -958,12 +877,11 @@ symtab_make_decl_local (tree decl)
DECL_COMMON (decl) = 0;
else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
if (DECL_COMDAT_GROUP (decl) || DECL_COMDAT (decl))
if (DECL_COMDAT (decl))
{
DECL_SECTION_NAME (decl) = 0;
DECL_COMDAT (decl) = 0;
}
DECL_COMDAT_GROUP (decl) = 0;
DECL_WEAK (decl) = 0;
DECL_EXTERNAL (decl) = 0;
DECL_VISIBILITY_SPECIFIED (decl) = 0;
@ -1097,11 +1015,13 @@ fixup_same_cpp_alias_visibility (symtab_node *node, symtab_node *target)
DECL_VIRTUAL_P (node->decl) = DECL_VIRTUAL_P (target->decl);
if (TREE_PUBLIC (node->decl))
{
tree group;
DECL_EXTERNAL (node->decl) = DECL_EXTERNAL (target->decl);
DECL_COMDAT (node->decl) = DECL_COMDAT (target->decl);
DECL_COMDAT_GROUP (node->decl)
= DECL_COMDAT_GROUP (target->decl);
if (DECL_COMDAT_GROUP (target->decl)
group = target->get_comdat_group ();
node->set_comdat_group (group);
if (group
&& !node->same_comdat_group)
symtab_add_to_same_comdat_group (node, target);
}
@ -1231,9 +1151,6 @@ symtab_nonoverwritable_alias (symtab_node *node)
/* Update the properties. */
DECL_EXTERNAL (new_decl) = 0;
if (DECL_COMDAT_GROUP (node->decl))
DECL_SECTION_NAME (new_decl) = NULL;
DECL_COMDAT_GROUP (new_decl) = 0;
TREE_PUBLIC (new_decl) = 0;
DECL_COMDAT (new_decl) = 0;
DECL_WEAK (new_decl) = 0;
@ -1246,8 +1163,7 @@ symtab_nonoverwritable_alias (symtab_node *node)
(new_decl, node->decl);
}
else
new_node = varpool_create_variable_alias (new_decl,
node->decl);
new_node = varpool_create_variable_alias (new_decl, node->decl);
symtab_resolve_alias (new_node, node);
gcc_assert (decl_binds_to_current_def_p (new_decl));
return new_node;

View File

@ -4852,7 +4852,7 @@ ipa_tm_create_version_alias (struct cgraph_node *node, void *data)
/* Perform the same remapping to the comdat group. */
if (DECL_ONE_ONLY (new_decl))
DECL_COMDAT_GROUP (new_decl) = tm_mangle (DECL_COMDAT_GROUP (old_decl));
varpool_get_node (new_decl)->set_comdat_group (tm_mangle (DECL_COMDAT_GROUP (old_decl)));
new_node = cgraph_same_body_alias (NULL, new_decl, info->new_decl);
new_node->tm_clone = true;
@ -4892,7 +4892,7 @@ ipa_tm_create_version (struct cgraph_node *old_node)
/* Perform the same remapping to the comdat group. */
if (DECL_ONE_ONLY (new_decl))
DECL_COMDAT_GROUP (new_decl) = tm_mangle (DECL_COMDAT_GROUP (old_decl));
varpool_get_node (new_decl)->set_comdat_group (tm_mangle (DECL_COMDAT_GROUP (old_decl)));
gcc_assert (!old_node->ipa_transforms_to_apply.exists ());
new_node = cgraph_copy_node_for_versioning (old_node, new_decl, vNULL, NULL);

View File

@ -1442,7 +1442,7 @@ struct GTY(()) tree_decl_with_vis {
struct tree_decl_with_rtl common;
tree assembler_name;
tree section_name;
tree comdat_group;
struct symtab_node *symtab_node;
/* Belong to VAR_DECL exclusively. */
unsigned defer_output : 1;

View File

@ -760,7 +760,6 @@ lto_input_ts_decl_with_vis_tree_pointers (struct lto_input_block *ib,
}
DECL_SECTION_NAME (expr) = stream_read_tree (ib, data_in);
DECL_COMDAT_GROUP (expr) = stream_read_tree (ib, data_in);
}

View File

@ -662,7 +662,6 @@ write_ts_decl_with_vis_tree_pointers (struct output_block *ob, tree expr,
stream_write_tree (ob, NULL_TREE, false);
stream_write_tree (ob, DECL_SECTION_NAME (expr), ref_p);
stream_write_tree (ob, DECL_COMDAT_GROUP (expr), ref_p);
}

View File

@ -972,14 +972,20 @@ copy_node_stat (tree node MEM_STAT_DECL)
}
/* DECL_DEBUG_EXPR is copied explicitely by callers. */
if (TREE_CODE (node) == VAR_DECL)
DECL_HAS_DEBUG_EXPR_P (t) = 0;
{
DECL_HAS_DEBUG_EXPR_P (t) = 0;
t->decl_with_vis.symtab_node = NULL;
}
if (TREE_CODE (node) == VAR_DECL && DECL_HAS_INIT_PRIORITY_P (node))
{
SET_DECL_INIT_PRIORITY (t, DECL_INIT_PRIORITY (node));
DECL_HAS_INIT_PRIORITY_P (t) = 1;
}
if (TREE_CODE (node) == FUNCTION_DECL)
DECL_STRUCT_FUNCTION (t) = NULL;
{
DECL_STRUCT_FUNCTION (t) = NULL;
t->decl_with_vis.symtab_node = NULL;
}
}
else if (TREE_CODE_CLASS (code) == tcc_type)
{
@ -5238,7 +5244,6 @@ find_decls_types_r (tree *tp, int *ws, void *data)
else if (TREE_CODE (t) == VAR_DECL)
{
fld_worklist_push (DECL_SECTION_NAME (t), fld);
fld_worklist_push (DECL_COMDAT_GROUP (t), fld);
}
if ((TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == PARM_DECL)

View File

@ -2323,7 +2323,7 @@ extern void decl_value_expr_insert (tree, tree);
(DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_flag)
#define DECL_COMDAT_GROUP(NODE) \
(DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_group)
decl_comdat_group (NODE)
/* Used in TREE_PUBLIC decls to indicate that copies of this DECL in
multiple translation units should be merged. */

View File

@ -5919,17 +5919,23 @@ supports_one_only (void)
void
make_decl_one_only (tree decl, tree comdat_group)
{
struct symtab_node *symbol;
gcc_assert (TREE_CODE (decl) == VAR_DECL
|| TREE_CODE (decl) == FUNCTION_DECL);
TREE_PUBLIC (decl) = 1;
if (TREE_CODE (decl) == VAR_DECL)
symbol = varpool_node_for_decl (decl);
else
symbol = cgraph_get_create_node (decl);
if (SUPPORTS_ONE_ONLY)
{
#ifdef MAKE_DECL_ONE_ONLY
MAKE_DECL_ONE_ONLY (decl);
#endif
DECL_COMDAT_GROUP (decl) = comdat_group;
symbol->set_comdat_group (comdat_group);
}
else if (TREE_CODE (decl) == VAR_DECL
&& (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))