diff options
-rw-r--r-- | gcc/ChangeLog | 50 | ||||
-rw-r--r-- | gcc/bb-reorder.c | 1 | ||||
-rw-r--r-- | gcc/c/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c/c-decl.c | 15 | ||||
-rw-r--r-- | gcc/cgraph.c | 3 | ||||
-rw-r--r-- | gcc/cgraph.h | 53 | ||||
-rw-r--r-- | gcc/cgraphclones.c | 3 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 2 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 2 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 2 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 2 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/decl.c | 42 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 9 | ||||
-rw-r--r-- | gcc/cp/optimize.c | 6 | ||||
-rw-r--r-- | gcc/ipa-comdats.c | 13 | ||||
-rw-r--r-- | gcc/ipa-inline-transform.c | 2 | ||||
-rw-r--r-- | gcc/ipa.c | 35 | ||||
-rw-r--r-- | gcc/lto-cgraph.c | 99 | ||||
-rw-r--r-- | gcc/lto-streamer-out.c | 2 | ||||
-rw-r--r-- | gcc/lto/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/lto/lto-symtab.c | 2 | ||||
-rw-r--r-- | gcc/lto/lto.c | 1 | ||||
-rw-r--r-- | gcc/symtab.c | 132 | ||||
-rw-r--r-- | gcc/trans-mem.c | 4 | ||||
-rw-r--r-- | gcc/tree-core.h | 2 | ||||
-rw-r--r-- | gcc/tree-streamer-in.c | 1 | ||||
-rw-r--r-- | gcc/tree-streamer-out.c | 1 | ||||
-rw-r--r-- | gcc/tree.c | 11 | ||||
-rw-r--r-- | gcc/tree.h | 2 | ||||
-rw-r--r-- | gcc/varasm.c | 8 |
31 files changed, 350 insertions, 175 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b68063c7d39..09f014a7591 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,55 @@ 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. * optabs.c (widening_optab_handler): Bring offline. * optabs.h (widening_optab_handler): Likewise. diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c index f16f57b6961..61b0caba8b8 100644 --- a/gcc/bb-reorder.c +++ b/gcc/bb-reorder.c @@ -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 diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 5bee1cadd9f..dc4a653d508 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -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 diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 75d12205b04..e8e6bd2b221 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -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; } diff --git a/gcc/cgraph.c b/gcc/cgraph.c index e3ddc235009..ff65b86a567 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -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; diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 9dc6f0186f1..cfb2d4850fd 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -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 */ diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index df8b2a29e22..4387b99f3af 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -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; diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 4084cc4ec1e..3bd364bbaac 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -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) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 24c6f82c4b2..0bde73241f9 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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)); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 17af1d6fbd6..eefcfd24521 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -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)); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 36e5e990d32..b4305dff301 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2cfc428e466..66eebc440a2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,14 @@ 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 (emit_tinfo_decl): Force RTTI data to be aligned to required ABI alignment only. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 3752d17fad1..9e97ff854ce 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index b18f65a383f..de3499904d3 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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; diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index b089432a305..a58565cd8fd 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -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])); } diff --git a/gcc/ipa-comdats.c b/gcc/ipa-comdats.c index d6840648fec..41e27fd42ab 100644 --- a/gcc/ipa-comdats.c +++ b/gcc/ipa-comdats.c @@ -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)) { diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c index 82fe839b380..4cfd87b1015 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -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 diff --git a/gcc/ipa.c b/gcc/ipa.c index d0beefe214c..b0cc6d5887a 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -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); diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index 2329d1a6be5..4f8d5b701ff 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -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) + group = node->get_comdat_group (); + if (group) + comdat = IDENTIFIER_POINTER (group); + else + comdat = ""; + lto_output_data_stream (ob->main_stream, comdat, strlen (comdat) + 1); + if (group) { - ref = lto_symtab_encoder_lookup (encoder, - node->same_comdat_group); - gcc_assert (ref != LCC_NOT_FOUND); + 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); } - 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) + group = node->get_comdat_group (); + if (group) + comdat = IDENTIFIER_POINTER (group); + else + comdat = ""; + lto_output_data_stream (ob->main_stream, comdat, strlen (comdat) + 1); + if (group) { - ref = lto_symtab_encoder_lookup (encoder, - node->same_comdat_group); - gcc_assert (ref != LCC_NOT_FOUND); + 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); } - 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 diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index 6f2bf9c307d..79f667649fe 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -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)) diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 79ada63f6d7..f4a226b66b2 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -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) diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c index 957261ec8b7..7f48c5e9a8e 100644 --- a/gcc/lto/lto-symtab.c +++ b/gcc/lto/lto-symtab.c @@ -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; } } } diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 00f5f62b37e..e5cdfc1cf3e 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -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)) diff --git a/gcc/symtab.c b/gcc/symtab.c index 9d7c7e64b49..301f7e3bef8 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -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; diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index f73f454cab5..a0903e45157 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -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); diff --git a/gcc/tree-core.h b/gcc/tree-core.h index 98c3951c691..ebe584939f7 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -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; diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c index 97ffc1e03c5..3338e327dc4 100644 --- a/gcc/tree-streamer-in.c +++ b/gcc/tree-streamer-in.c @@ -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); } diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c index 5858047b4b5..6fb808e4fa0 100644 --- a/gcc/tree-streamer-out.c +++ b/gcc/tree-streamer-out.c @@ -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); } diff --git a/gcc/tree.c b/gcc/tree.c index 22b92f3b6b2..84563170115 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -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) diff --git a/gcc/tree.h b/gcc/tree.h index 968b389dd11..7aeb288fc8a 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -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. */ diff --git a/gcc/varasm.c b/gcc/varasm.c index 57b33d78419..d72d11e7bdc 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -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)) |