Commit 64cfa6c0 by Jan Hubicka Committed by Jan Hubicka

Jan Hubicka <jh@suse.cz>

	Richard Biener  <rguenther@suse.de>

	PR lto/54095
	* symtab.c (symtab_make_decl_local): Do not add private names.

	* lto.c (lto_register_var_decl_in_symtab): Don't do renaming.
	(lto_register_var_decl_in_symtab): Likewise.
	(lto_main): Promote statics.
	* lto-partition.c (privatize_symbol_name): New function.
	(promote_symbol): Use it.
	(may_need_named_section_p): New predicate.
	(rename_statics): New functions.
	(lto_promote_cross_file_statics): Simplify; do renaming.
	(lto_promote_statics_nonwpa): New function.
	* lto-partition.h (lto_promote_statics_nonwpa): New function.

Co-Authored-By: Richard Biener <rguenther@suse.de>

From-SVN: r198741
parent c3167b00
2013-05-09 Jan Hubicka <jh@suse.cz>
Richard Biener <rguenther@suse.de>
PR lto/54095
* symtab.c (symtab_make_decl_local): Do not add private names.
2013-05-09 Jan Hubicka <jh@suse.cz>
PR lto/54095
* symtab.c (insert_to_assembler_name_hash): Handle clones.
......
2013-05-09 Jan Hubicka <jh@suse.cz>
Richard Biener <rguenther@suse.de>
* lto.c (lto_register_var_decl_in_symtab): Don't do renaming.
(lto_register_var_decl_in_symtab): Likewise.
(lto_main): Promote statics.
* lto-partition.c (privatize_symbol_name): New function.
(promote_symbol): Use it.
(may_need_named_section_p): New predicate.
(rename_statics): New functions.
(lto_promote_cross_file_statics): Simplify; do renaming.
(lto_promote_statics_nonwpa): New function.
* lto-partition.h (lto_promote_statics_nonwpa): New function.
2013-02-08 Richard Biener <rguenther@suse.de>
PR lto/56231
......
......@@ -755,6 +755,56 @@ lto_balanced_map (void)
free (order);
}
/* Mangle NODE symbol name into a local name.
This is necessary to do
1) if two or more static vars of same assembler name
are merged into single ltrans unit.
2) if prevoiusly static var was promoted hidden to avoid possible conflict
with symbols defined out of the LTO world.
*/
static void
privatize_symbol_name (symtab_node node)
{
tree decl = node->symbol.decl;
const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
char *label;
/* Our renaming machinery do not handle more than one change of assembler name.
We should not need more than one anyway. */
if (node->symbol.lto_file_data
&& lto_get_decl_name_mapping (node->symbol.lto_file_data, name) != name)
{
if (cgraph_dump_file)
fprintf (cgraph_dump_file,
"Not privatizing symbol name: %s. It privatized already.\n",
name);
return;
}
/* Avoid mangling of already mangled clones.
??? should have a flag whether a symbol has a 'private' name already,
since we produce some symbols like that i.e. for global constructors
that are not really clones. */
if (node->symbol.unique_name)
{
if (cgraph_dump_file)
fprintf (cgraph_dump_file,
"Not privatizing symbol name: %s. Has unique name.\n",
name);
return;
}
ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl));
change_decl_assembler_name (decl, clone_function_name (decl, "lto_priv"));
if (node->symbol.lto_file_data)
lto_record_renamed_decl (node->symbol.lto_file_data, name,
IDENTIFIER_POINTER
(DECL_ASSEMBLER_NAME (decl)));
if (cgraph_dump_file)
fprintf (cgraph_dump_file,
"Privatizing symbol name: %s -> %s\n",
name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
}
/* Promote variable VNODE to be static. */
static void
......@@ -768,6 +818,9 @@ promote_symbol (symtab_node node)
gcc_checking_assert (!TREE_PUBLIC (node->symbol.decl)
&& !DECL_EXTERNAL (node->symbol.decl));
/* Be sure that newly public symbol does not conflict with anything already
defined by the non-LTO part. */
privatize_symbol_name (node);
TREE_PUBLIC (node->symbol.decl) = 1;
DECL_VISIBILITY (node->symbol.decl) = VISIBILITY_HIDDEN;
DECL_VISIBILITY_SPECIFIED (node->symbol.decl) = true;
......@@ -776,6 +829,85 @@ promote_symbol (symtab_node node)
"Promoting as hidden: %s\n", symtab_node_name (node));
}
/* Return true if NODE needs named section even if it won't land in the partition
symbol table.
FIXME: we should really not use named sections for inline clones and master clones. */
static bool
may_need_named_section_p (lto_symtab_encoder_t encoder, symtab_node node)
{
struct cgraph_node *cnode = dyn_cast <cgraph_node> (node);
if (!cnode)
return false;
if (symtab_real_symbol_p (node))
return false;
if (!cnode->global.inlined_to && !cnode->clones)
return false;
return (!encoder
|| (lto_symtab_encoder_lookup (encoder, node) != LCC_NOT_FOUND
&& lto_symtab_encoder_encode_body_p (encoder,
cnode)));
}
/* If NODE represents a static variable. See if there are other variables
of the same name in partition ENCODER (or in whole compilation unit if
ENCODER is NULL) and if so, mangle the statics. Always mangle all
conflicting statics, so we reduce changes of silently miscompiling
asm statemnets refering to them by symbol name. */
static void
rename_statics (lto_symtab_encoder_t encoder, symtab_node node)
{
tree decl = node->symbol.decl;
symtab_node s;
tree name = DECL_ASSEMBLER_NAME (decl);
/* See if this is static symbol. */
if ((node->symbol.externally_visible
/* FIXME: externally_visible is somewhat illogically not set for
external symbols (i.e. those not defined). Remove this test
once this is fixed. */
|| DECL_EXTERNAL (node->symbol.decl)
|| !symtab_real_symbol_p (node))
&& !may_need_named_section_p (encoder, node))
return;
/* Now walk symbols sharing the same name and see if there are any conflicts.
(all types of symbols counts here, since we can not have static of the
same name as external or public symbol.) */
for (s = symtab_node_for_asm (name);
s; s = s->symbol.next_sharing_asm_name)
if ((symtab_real_symbol_p (s) || may_need_named_section_p (encoder, s))
&& s->symbol.decl != node->symbol.decl
&& (!encoder
|| lto_symtab_encoder_lookup (encoder, s) != LCC_NOT_FOUND))
break;
/* OK, no confict, so we have nothing to do. */
if (!s)
return;
if (cgraph_dump_file)
fprintf (cgraph_dump_file,
"Renaming statics with asm name: %s\n", symtab_node_name (node));
/* Assign every symbol in the set that shares the same ASM name an unique
mangled name. */
for (s = symtab_node_for_asm (name); s;)
if (!s->symbol.externally_visible
&& ((symtab_real_symbol_p (s)
&& !DECL_EXTERNAL (node->symbol.decl)
&& !TREE_PUBLIC (node->symbol.decl))
|| may_need_named_section_p (encoder, s))
&& (!encoder
|| lto_symtab_encoder_lookup (encoder, s) != LCC_NOT_FOUND))
{
privatize_symbol_name (s);
/* Re-start from beggining since we do not know how many symbols changed a name. */
s = symtab_node_for_asm (name);
}
else s = s->symbol.next_sharing_asm_name;
}
/* Find out all static decls that need to be promoted to global because
of cross file sharing. This function must be run in the WPA mode after
......@@ -801,16 +933,17 @@ lto_promote_cross_file_statics (void)
for (i = 0; i < n_sets; i++)
{
lto_symtab_encoder_iterator lsei;
lto_symtab_encoder_t encoder;
ltrans_partition part
= ltrans_partitions[i];
lto_symtab_encoder_t encoder = ltrans_partitions[i]->encoder;
encoder = part->encoder;
for (lsei = lsei_start (encoder); !lsei_end_p (lsei);
lsei_next (&lsei))
{
symtab_node node = lsei_node (lsei);
/* If symbol is static, rename it if its assembler name clash with
anything else in this unit. */
rename_statics (encoder, node);
/* No need to promote if symbol already is externally visible ... */
if (node->symbol.externally_visible
/* ... or if it is part of current partition ... */
......@@ -824,3 +957,14 @@ lto_promote_cross_file_statics (void)
}
}
}
/* Rename statics in the whole unit in the case that
we do -flto-partition=none. */
void
lto_promote_statics_nonwpa (void)
{
symtab_node node;
FOR_EACH_SYMBOL (node)
rename_statics (NULL, node);
}
......@@ -37,3 +37,4 @@ void lto_max_map (void);
void lto_balanced_map (void);
void lto_promote_cross_file_statics (void);
void free_ltrans_partitions (void);
void lto_promote_statics_nonwpa (void);
......@@ -1748,23 +1748,11 @@ lto_register_var_decl_in_symtab (struct data_in *data_in, tree decl)
{
tree context;
/* Variable has file scope, not local. Need to ensure static variables
between different files don't clash unexpectedly. */
/* Variable has file scope, not local. */
if (!TREE_PUBLIC (decl)
&& !((context = decl_function_context (decl))
&& auto_var_in_fn_p (decl, context)))
{
/* ??? We normally pre-mangle names before we serialize them
out. Here, in lto1, we do not know the language, and
thus cannot do the mangling again. Instead, we just
append a suffix to the mangled name. The resulting name,
however, is not a properly-formed mangled name, and will
confuse any attempt to unmangle it. */
const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
char *label;
ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl));
SET_DECL_ASSEMBLER_NAME (decl, get_identifier (label));
rest_of_decl_compilation (decl, 1, 0);
}
......@@ -1788,44 +1776,6 @@ lto_register_var_decl_in_symtab (struct data_in *data_in, tree decl)
static void
lto_register_function_decl_in_symtab (struct data_in *data_in, tree decl)
{
/* Need to ensure static entities between different files
don't clash unexpectedly. */
if (!TREE_PUBLIC (decl))
{
/* We must not use the DECL_ASSEMBLER_NAME macro here, as it
may set the assembler name where it was previously empty. */
tree old_assembler_name = decl->decl_with_vis.assembler_name;
/* FIXME lto: We normally pre-mangle names before we serialize
them out. Here, in lto1, we do not know the language, and
thus cannot do the mangling again. Instead, we just append a
suffix to the mangled name. The resulting name, however, is
not a properly-formed mangled name, and will confuse any
attempt to unmangle it. */
const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
char *label;
ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl));
SET_DECL_ASSEMBLER_NAME (decl, get_identifier (label));
/* We may arrive here with the old assembler name not set
if the function body is not needed, e.g., it has been
inlined away and does not appear in the cgraph. */
if (old_assembler_name)
{
tree new_assembler_name = DECL_ASSEMBLER_NAME (decl);
/* Make the original assembler name available for later use.
We may have used it to indicate the section within its
object file where the function body may be found.
FIXME lto: Find a better way to maintain the function decl
to body section mapping so we don't need this hack. */
lto_record_renamed_decl (data_in->file_data,
IDENTIFIER_POINTER (old_assembler_name),
IDENTIFIER_POINTER (new_assembler_name));
}
}
/* If this variable has already been declared, queue the
declaration for merging. */
if (TREE_PUBLIC (decl) && !DECL_ABSTRACT (decl))
......@@ -3396,6 +3346,8 @@ lto_main (void)
timevar_start (TV_PHASE_OPT_GEN);
materialize_cgraph ();
if (!flag_ltrans)
lto_promote_statics_nonwpa ();
/* Let the middle end know that we have read and merged all of
the input files. */
......
......@@ -756,23 +756,6 @@ symtab_make_decl_local (tree decl)
if (DECL_ONE_ONLY (decl) || DECL_COMDAT (decl))
{
/* It is possible that we are linking against library defining same COMDAT
function. To avoid conflict we need to rename our local name of the
function just in the case WHOPR partitioning decide to make it hidden
to avoid cross partition references. */
if (flag_wpa)
{
const char *old_name;
symtab_node node = symtab_get_node (decl);
old_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
change_decl_assembler_name (decl,
clone_function_name (decl, "local"));
if (node->symbol.lto_file_data)
lto_record_renamed_decl (node->symbol.lto_file_data,
old_name,
IDENTIFIER_POINTER
(DECL_ASSEMBLER_NAME (decl)));
}
DECL_SECTION_NAME (decl) = 0;
DECL_COMDAT (decl) = 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment