Hi, this patch makes change_decl_assembler_name to do the right thing with inline clones. My original plan was to remove inline clones from assembler_name_hash, but it hits the problem that we currently need to make them unique for purposes of LTO sreaming.
It is not hard to walk the clone tree and update it. Later we can reorg streaming to not rely on uniqueness of symbol names of function bodies not associated with a real symbol and perhaps simplify this somewhat. Bootstrapped/regtested x86_64-linux, will commit it shortly. PR lto/54095 * symtab.c (insert_to_assembler_name_hash): Handle clones. (unlink_from_assembler_name_hash): Likewise. (symtab_prevail_in_asm_name_hash, symtab_register_node, symtab_unregister_node, symtab_initialize_asm_name_hash, change_decl_assembler_name): Update. Index: symtab.c =================================================================== *** symtab.c (revision 197551) --- symtab.c (working copy) *************** eq_assembler_name (const void *p1, const *** 102,108 **** /* Insert NODE to assembler name hash. */ static void ! insert_to_assembler_name_hash (symtab_node node) { if (is_a <varpool_node> (node) && DECL_HARD_REGISTER (node->symbol.decl)) return; --- 102,108 ---- /* Insert NODE to assembler name hash. */ static void ! insert_to_assembler_name_hash (symtab_node node, bool with_clones) { if (is_a <varpool_node> (node) && DECL_HARD_REGISTER (node->symbol.decl)) return; *************** insert_to_assembler_name_hash (symtab_no *** 111,116 **** --- 111,119 ---- if (assembler_name_hash) { void **aslot; + struct cgraph_node *cnode; + tree decl = node->symbol.decl; + tree name = DECL_ASSEMBLER_NAME (node->symbol.decl); aslot = htab_find_slot_with_hash (assembler_name_hash, name, *************** insert_to_assembler_name_hash (symtab_no *** 121,126 **** --- 124,136 ---- if (*aslot != NULL) ((symtab_node)*aslot)->symbol.previous_sharing_asm_name = node; *aslot = node; + + /* Update also possible inline clones sharing a decl. */ + cnode = dyn_cast <cgraph_node> (node); + if (cnode && cnode->clones && with_clones) + for (cnode = cnode->clones; cnode; cnode = cnode->next_sibling_clone) + if (cnode->symbol.decl == decl) + insert_to_assembler_name_hash ((symtab_node) cnode, true); } } *************** insert_to_assembler_name_hash (symtab_no *** 128,137 **** /* Remove NODE from assembler name hash. */ static void ! unlink_from_assembler_name_hash (symtab_node node) { if (assembler_name_hash) { if (node->symbol.next_sharing_asm_name) node->symbol.next_sharing_asm_name->symbol.previous_sharing_asm_name = node->symbol.previous_sharing_asm_name; --- 138,150 ---- /* Remove NODE from assembler name hash. */ static void ! unlink_from_assembler_name_hash (symtab_node node, bool with_clones) { if (assembler_name_hash) { + struct cgraph_node *cnode; + tree decl = node->symbol.decl; + if (node->symbol.next_sharing_asm_name) node->symbol.next_sharing_asm_name->symbol.previous_sharing_asm_name = node->symbol.previous_sharing_asm_name; *************** unlink_from_assembler_name_hash (symtab_ *** 155,160 **** --- 168,180 ---- } node->symbol.next_sharing_asm_name = NULL; node->symbol.previous_sharing_asm_name = NULL; + + /* Update also possible inline clones sharing a decl. */ + cnode = dyn_cast <cgraph_node> (node); + if (cnode && cnode->clones && with_clones) + for (cnode = cnode->clones; cnode; cnode = cnode->next_sibling_clone) + if (cnode->symbol.decl == decl) + unlink_from_assembler_name_hash ((symtab_node) cnode, true); } } *************** unlink_from_assembler_name_hash (symtab_ *** 163,170 **** void symtab_prevail_in_asm_name_hash (symtab_node node) { ! unlink_from_assembler_name_hash (node); ! insert_to_assembler_name_hash (node); } --- 183,190 ---- void symtab_prevail_in_asm_name_hash (symtab_node node) { ! unlink_from_assembler_name_hash (node, false); ! insert_to_assembler_name_hash (node, false); } *************** symtab_register_node (symtab_node node) *** 196,202 **** /* Be sure to do this last; C++ FE might create new nodes via DECL_ASSEMBLER_NAME langhook! */ ! insert_to_assembler_name_hash (node); } /* Make NODE to be the one symtab hash is pointing to. Used when reshaping tree --- 216,222 ---- /* Be sure to do this last; C++ FE might create new nodes via DECL_ASSEMBLER_NAME langhook! */ ! insert_to_assembler_name_hash (node, false); } /* Make NODE to be the one symtab hash is pointing to. Used when reshaping tree *************** symtab_unregister_node (symtab_node node *** 259,265 **** else *slot = replacement_node; } ! unlink_from_assembler_name_hash (node); } /* Return symbol table node associated with DECL, if any, --- 279,285 ---- else *slot = replacement_node; } ! unlink_from_assembler_name_hash (node, false); } /* Return symbol table node associated with DECL, if any, *************** symtab_initialize_asm_name_hash (void) *** 312,318 **** htab_create_ggc (10, hash_node_by_assembler_name, eq_assembler_name, NULL); FOR_EACH_SYMBOL (node) ! insert_to_assembler_name_hash (node); } } --- 332,338 ---- htab_create_ggc (10, hash_node_by_assembler_name, eq_assembler_name, NULL); FOR_EACH_SYMBOL (node) ! insert_to_assembler_name_hash (node, false); } } *************** change_decl_assembler_name (tree decl, t *** 355,361 **** { SET_DECL_ASSEMBLER_NAME (decl, name); if (node) ! insert_to_assembler_name_hash (node); } else { --- 375,381 ---- { SET_DECL_ASSEMBLER_NAME (decl, name); if (node) ! insert_to_assembler_name_hash (node, true); } else { *************** change_decl_assembler_name (tree decl, t *** 363,376 **** return; if (node) ! unlink_from_assembler_name_hash (node); if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) && DECL_RTL_SET_P (decl)) warning (0, "%D renamed after being referenced in assembly", decl); SET_DECL_ASSEMBLER_NAME (decl, name); if (node) ! insert_to_assembler_name_hash (node); } } --- 383,396 ---- return; if (node) ! unlink_from_assembler_name_hash (node, true); if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) && DECL_RTL_SET_P (decl)) warning (0, "%D renamed after being referenced in assembly", decl); SET_DECL_ASSEMBLER_NAME (decl, name); if (node) ! insert_to_assembler_name_hash (node, true); } }