Hi, this patch adds a new symbol flag UNIQUE_NAME. Its purpose is to disable renaming at LTO time when the symbol is already known to be unique in the whole resulting DSO. This happens for symbols that was previously global and we know from LTO plugin resolution data that they are not bound by non-LTO world.
I also made clones to be unique. This needs more care. 1) when clonning at compilation time, one can produce two clones of same name (like foo.sra.1) for static functions. 2) we make an assumption here that the namespace .clonetype.num is private for GCC. This is how things works since introduction of WHOPR, but it is not documented. We may need to add those ugly __GLOBAL_XYZ manglings. I would like to handle 2) incrementally after some discussion with plugin folks. The flag is currently write only, I am going to use by later patch. Bootstrapped/regtested x86_64-linux, will commit it after we settle on the ohter changes that needs the flag. Honza PR lto/54095 * cgraph.c (cgraph_make_node_local_1): Se unique_name. * cgraph.h (symtab_node_base): Add unique_name. * lto-cgraph.c (lto_output_node, lto_output_varpool_node, input_overwrite_node, input_varpool_node): Stream unique_name. * cgraphclones.c (cgraph_create_virtual_clone, cgraph_function_versioning): Set unique_name. * ipa.c (function_and_variable_visibility): Set unique_name. Index: cgraph.c =================================================================== *** cgraph.c (revision 197551) --- cgraph.c (working copy) *************** cgraph_make_node_local_1 (struct cgraph_ *** 1798,1803 **** --- 1800,1807 ---- node->symbol.externally_visible = false; node->local.local = true; + node->symbol.unique_name = (node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY + || node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP); node->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY; gcc_assert (cgraph_function_body_availability (node) == AVAIL_LOCAL); } Index: cgraph.h =================================================================== *** cgraph.h (revision 197551) --- cgraph.h (working copy) *************** struct GTY(()) symtab_node_base *** 62,67 **** --- 62,69 ---- /* Needed variables might become dead by optimization. This flag forces the variable to be output even if it appears dead otherwise. */ unsigned force_output : 1; + /* True when the name is known to be unique and thus it does not need mangling. */ + unsigned unique_name : 1; /* Ordering of all symtab entries. */ int order; Index: lto-cgraph.c =================================================================== *** lto-cgraph.c (revision 197551) --- lto-cgraph.c (working copy) *************** lto_output_node (struct lto_simple_outpu *** 468,473 **** --- 468,474 ---- bp_pack_value (&bp, node->local.can_change_signature, 1); bp_pack_value (&bp, node->local.redefined_extern_inline, 1); bp_pack_value (&bp, node->symbol.force_output, 1); + bp_pack_value (&bp, node->symbol.unique_name, 1); bp_pack_value (&bp, node->symbol.address_taken, 1); bp_pack_value (&bp, node->abstract_and_needed, 1); bp_pack_value (&bp, tag == LTO_symtab_analyzed_node *************** lto_output_varpool_node (struct lto_simp *** 533,538 **** --- 534,540 ---- bp = bitpack_create (ob->main_stream); bp_pack_value (&bp, node->symbol.externally_visible, 1); bp_pack_value (&bp, node->symbol.force_output, 1); + bp_pack_value (&bp, node->symbol.unique_name, 1); bp_pack_value (&bp, node->finalized, 1); bp_pack_value (&bp, node->alias, 1); bp_pack_value (&bp, node->alias_of != NULL, 1); *************** input_overwrite_node (struct lto_file_de *** 886,891 **** --- 888,894 ---- node->local.can_change_signature = bp_unpack_value (bp, 1); node->local.redefined_extern_inline = bp_unpack_value (bp, 1); node->symbol.force_output = bp_unpack_value (bp, 1); + node->symbol.unique_name = bp_unpack_value (bp, 1); node->symbol.address_taken = bp_unpack_value (bp, 1); node->abstract_and_needed = bp_unpack_value (bp, 1); node->symbol.used_from_other_partition = bp_unpack_value (bp, 1); *************** input_varpool_node (struct lto_file_decl *** 1040,1045 **** --- 1043,1049 ---- bp = streamer_read_bitpack (ib); node->symbol.externally_visible = bp_unpack_value (&bp, 1); node->symbol.force_output = bp_unpack_value (&bp, 1); + node->symbol.unique_name = bp_unpack_value (&bp, 1); node->finalized = bp_unpack_value (&bp, 1); node->alias = bp_unpack_value (&bp, 1); non_null_aliasof = bp_unpack_value (&bp, 1); Index: cgraphclones.c =================================================================== *** cgraphclones.c (revision 197551) --- cgraphclones.c (working copy) *************** cgraph_create_virtual_clone (struct cgra *** 324,329 **** --- 324,337 ---- DECL_STATIC_DESTRUCTOR (new_node->symbol.decl) = 0; new_node->clone.tree_map = tree_map; new_node->clone.args_to_skip = args_to_skip; + + /* Clones of global symbols or symbols with unique names are unique. */ + if ((TREE_PUBLIC (old_decl) + && !DECL_EXTERNAL (old_decl) + && !DECL_WEAK (old_decl) + && !DECL_COMDAT (old_decl)) + || in_lto_p) + new_node->symbol.unique_name = true; FOR_EACH_VEC_SAFE_ELT (tree_map, i, map) { tree var = map->new_tree; *************** cgraph_function_versioning (struct cgrap *** 739,744 **** --- 747,759 ---- new_version_node->symbol.externally_visible = 0; new_version_node->local.local = 1; new_version_node->lowered = true; + /* Clones of global symbols or symbols with unique names are unique. */ + if ((TREE_PUBLIC (old_decl) + && !DECL_EXTERNAL (old_decl) + && !DECL_WEAK (old_decl) + && !DECL_COMDAT (old_decl)) + || in_lto_p) + new_version_node->symbol.unique_name = true; /* Update the call_expr on the edges to call the new version node. */ update_call_expr (new_version_node); Index: ipa.c =================================================================== *** ipa.c (revision 197551) --- ipa.c (working copy) *************** function_and_variable_visibility (bool w *** 831,836 **** --- 831,839 ---- { gcc_assert (whole_program || in_lto_p || !TREE_PUBLIC (node->symbol.decl)); + node->symbol.unique_name = ((node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY + || node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) + && TREE_PUBLIC (node->symbol.decl)); symtab_make_decl_local (node->symbol.decl); node->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY; if (node->symbol.same_comdat_group) *************** function_and_variable_visibility (bool w *** 908,913 **** --- 911,919 ---- { gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->symbol.decl)); symtab_make_decl_local (vnode->symbol.decl); + vnode->symbol.unique_name = ((vnode->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY + || vnode->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) + && TREE_PUBLIC (vnode->symbol.decl)); if (vnode->symbol.same_comdat_group) symtab_dissolve_same_comdat_group_list ((symtab_node) vnode); vnode->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY;