On Tue, May 14, 2013 at 11:12 AM, Jan Hubicka <hubi...@ucw.cz> wrote: > Hi, > this patch fixes with weakrefs seen on building latest firefox. The problem > is > that currently we handle weakrefs as external variables/functions that makes > us > to merge them. In firefox there are two weakrefs with different aliases used > in different units. This is correct and well defined even if weird use. > > This patch adds special cases for weakrefs into lto-symtab and lto-partition > to make them go through correctly. I also fixed two fallouts of my previous > change that reproduce on firefox (and the testcase addded). > > For lto-partition the weakrefs with defined target are even bit more special > animals, since they needs to be duplicated into every unit that use them. > > It is ugly to special case wekarefs all around. My plan is to cleanup whole > area, but it seems that the correctness issue deserve to be fixed first. > > I have bootstrapped/regtested x86_64-linux and tested mozilla build. Will > commit it tonight if there are no complains.
Does this affect the 4.8 branch, too? Thanks, Richard. > Honza > > PR lto/57038 > PR lto/47375 > * lto-symtab.c (lto_symtab_symbol_p): Add external symbol; weakrefs > are > not external. > (lto_symtab_merge_decls): Fix thinko when dealing with non-lto_symtab > decls. > (lto_symtab_merge_cgraph_nodes): Use lto_symtab_symbol_p. > (lto_symtab_prevailing_decl): Get int sync with lto_symtab_symbol_p. > * varpool.c (dump_varpool_node): Dump more flags. > > * lto-partition.c (get_symbol_class): Fix weakrefs. > (lto_balanced_map): Fix weakrefs. > (privatize_symbol_name): Remove unnecesary label. > (rename_statics): Handle weakrefs as statics. > > * gcc.dg/lto/attr-weakref-1_0.c: New testcase. > * gcc.dg/lto/attr-weakref-1_1.c: New testcase. > * gcc.dg/lto/attr-weakref-1_2.c: New testcase. > Index: lto-symtab.c > =================================================================== > *** lto-symtab.c (revision 198824) > --- lto-symtab.c (working copy) > *************** lto_symtab_resolve_replaceable_p (symtab > *** 227,239 **** > } > > /* Return true, if the symbol E should be resolved by lto-symtab. > ! Those are all real symbols that are not static (we handle renaming > ! of static later in partitioning). */ > > static bool > lto_symtab_symbol_p (symtab_node e) > { > ! if (!TREE_PUBLIC (e->symbol.decl)) > return false; > return symtab_real_symbol_p (e); > } > --- 227,242 ---- > } > > /* Return true, if the symbol E should be resolved by lto-symtab. > ! Those are all external symbols and all real symbols that are not static > (we > ! handle renaming of static later in partitioning). */ > > static bool > lto_symtab_symbol_p (symtab_node e) > { > ! if (!TREE_PUBLIC (e->symbol.decl) && !DECL_EXTERNAL (e->symbol.decl)) > ! return false; > ! /* weakrefs are really static variables that are made external by a hack. > */ > ! if (lookup_attribute ("weakref", DECL_ATTRIBUTES (e->symbol.decl))) > return false; > return symtab_real_symbol_p (e); > } > *************** lto_symtab_merge_decls (void) > *** 528,537 **** > symtab_initialize_asm_name_hash (); > > FOR_EACH_SYMBOL (node) > ! if (TREE_PUBLIC (node->symbol.decl) > ! && node->symbol.next_sharing_asm_name > ! && !node->symbol.previous_sharing_asm_name) > ! lto_symtab_merge_decls_1 (node); > } > > /* Helper to process the decl chain for the symbol table entry *SLOT. */ > --- 531,549 ---- > symtab_initialize_asm_name_hash (); > > FOR_EACH_SYMBOL (node) > ! if (lto_symtab_symbol_p (node) > ! && node->symbol.next_sharing_asm_name) > ! { > ! symtab_node n; > ! > ! /* To avoid duplicated work, see if this is first real symbol in the > ! chain. */ > ! for (n = node->symbol.previous_sharing_asm_name; > ! n && !lto_symtab_symbol_p (n); n = > n->symbol.previous_sharing_asm_name) > ! ; > ! if (!n) > ! lto_symtab_merge_decls_1 (node); > ! } > } > > /* Helper to process the decl chain for the symbol table entry *SLOT. */ > *************** lto_symtab_merge_cgraph_nodes (void) > *** 574,580 **** > > if (!flag_ltrans) > FOR_EACH_SYMBOL (node) > ! if (TREE_PUBLIC (node->symbol.decl) > && node->symbol.next_sharing_asm_name > && !node->symbol.previous_sharing_asm_name) > lto_symtab_merge_cgraph_nodes_1 (node); > --- 586,592 ---- > > if (!flag_ltrans) > FOR_EACH_SYMBOL (node) > ! if (lto_symtab_symbol_p (node) > && node->symbol.next_sharing_asm_name > && !node->symbol.previous_sharing_asm_name) > lto_symtab_merge_cgraph_nodes_1 (node); > *************** lto_symtab_prevailing_decl (tree decl) > *** 602,608 **** > symtab_node ret; > > /* Builtins and local symbols are their own prevailing decl. */ > ! if (!TREE_PUBLIC (decl) || is_builtin_fn (decl)) > return decl; > > /* DECL_ABSTRACTs are their own prevailng decl. */ > --- 614,620 ---- > symtab_node ret; > > /* Builtins and local symbols are their own prevailing decl. */ > ! if ((!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl)) || is_builtin_fn > (decl)) > return decl; > > /* DECL_ABSTRACTs are their own prevailng decl. */ > *************** lto_symtab_prevailing_decl (tree decl) > *** 614,619 **** > --- 626,636 ---- > if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl)) > return decl; > > + /* As an anoying special cases weakrefs are really static variables with > + EXTERNAL flag. */ > + if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))) > + return decl; > + > /* Ensure DECL_ASSEMBLER_NAME will not set assembler name. */ > gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl)); > > Index: testsuite/gcc.dg/lto/attr-weakref-1_0.c > =================================================================== > *** testsuite/gcc.dg/lto/attr-weakref-1_0.c (revision 0) > --- testsuite/gcc.dg/lto/attr-weakref-1_0.c (revision 0) > *************** > *** 0 **** > --- 1,29 ---- > + /* { dg-lto-do run } */ > + int first = 0; > + void abort (void); > + int second = 0; > + void callmealias (void) > + { > + if (!first || !second) > + abort (); > + } > + void callmefirst (void) > + { > + if (first) > + abort(); > + first = 1; > + } > + void callmesecond (void) > + { > + if (!first) > + abort(); > + if (second) > + abort(); > + second = 1; > + } > + main() > + { > + c(); > + b(); > + return 0; > + } > Index: testsuite/gcc.dg/lto/attr-weakref-1_1.c > =================================================================== > *** testsuite/gcc.dg/lto/attr-weakref-1_1.c (revision 0) > --- testsuite/gcc.dg/lto/attr-weakref-1_1.c (revision 0) > *************** > *** 0 **** > --- 1,7 ---- > + extern void callmesecond(); > + static void callmealias() __attribute__((weakref ("callmesecond"))); > + > + b() > + { > + callmealias(); > + } > Index: testsuite/gcc.dg/lto/attr-weakref-1_2.c > =================================================================== > *** testsuite/gcc.dg/lto/attr-weakref-1_2.c (revision 0) > --- testsuite/gcc.dg/lto/attr-weakref-1_2.c (revision 0) > *************** > *** 0 **** > --- 1,7 ---- > + extern void callmefirst(); > + static void callmealias() __attribute__((weakref ("callmefirst"))); > + > + c() > + { > + callmealias(); > + } > Index: lto/lto-partition.c > =================================================================== > *** lto/lto-partition.c (revision 198824) > --- lto/lto-partition.c (working copy) > *************** get_symbol_class (symtab_node node) > *** 59,64 **** > --- 59,68 ---- > if (cnode && cnode->global.inlined_to) > return SYMBOL_DUPLICATE; > > + /* Weakref aliases are always duplicated. */ > + if (lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl))) > + return SYMBOL_DUPLICATE; > + > /* External declarations are external. */ > if (DECL_EXTERNAL (node->symbol.decl)) > return SYMBOL_EXTERNAL; > *************** get_symbol_class (symtab_node node) > *** 79,88 **** > else if (!cgraph (node)->analyzed) > return SYMBOL_EXTERNAL; > > - /* Weakref aliases are always duplicated. */ > - if (lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl))) > - return SYMBOL_DUPLICATE; > - > /* Comdats are duplicated to every use unless they are keyed. > Those do not need duplication. */ > if (DECL_COMDAT (node->symbol.decl) > --- 83,88 ---- > *************** lto_balanced_map (void) > *** 561,567 **** > > last_visited_node++; > > ! gcc_assert (node->analyzed); > > /* Compute boundary cost of callgraph edges. */ > for (edge = node->callees; edge; edge = edge->next_callee) > --- 561,568 ---- > > last_visited_node++; > > ! gcc_assert (node->analyzed > ! || lookup_attribute ("weakref", DECL_ATTRIBUTES > (node->symbol.decl))); > > /* Compute boundary cost of callgraph edges. */ > for (edge = node->callees; edge; edge = edge->next_callee) > *************** privatize_symbol_name (symtab_node node) > *** 768,774 **** > { > 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. */ > --- 769,774 ---- > *************** privatize_symbol_name (symtab_node node) > *** 793,799 **** > 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, > --- 793,798 ---- > *************** rename_statics (lto_symtab_encoder_t enc > *** 869,875 **** > 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. > --- 868,875 ---- > once this is fixed. */ > || DECL_EXTERNAL (node->symbol.decl) > || !symtab_real_symbol_p (node)) > ! && !may_need_named_section_p (encoder, node) > ! && !lookup_attribute ("weakref", DECL_ATTRIBUTES > (node->symbol.decl))) > return; > > /* Now walk symbols sharing the same name and see if there are any > conflicts. > *************** rename_statics (lto_symtab_encoder_t enc > *** 894,902 **** > /* 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 > --- 894,904 ---- > /* 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 > ! || lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl))) > && ((symtab_real_symbol_p (s) > ! && (!DECL_EXTERNAL (node->symbol.decl) > ! || lookup_attribute ("weakref", DECL_ATTRIBUTES > (node->symbol.decl))) > && !TREE_PUBLIC (node->symbol.decl)) > || may_need_named_section_p (encoder, s)) > && (!encoder > Index: varpool.c > =================================================================== > *** varpool.c (revision 198824) > --- varpool.c (working copy) > *************** dump_varpool_node (FILE *f, struct varpo > *** 86,91 **** > --- 86,95 ---- > fprintf (f, " finalized"); > if (node->output) > fprintf (f, " output"); > + if (TREE_READONLY (node->symbol.decl)) > + fprintf (f, " read-only"); > + if (const_value_known_p (node->symbol.decl)) > + fprintf (f, " const-value-known"); > fprintf (f, "\n"); > } >