diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2014-06-11 07:51:23 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2014-06-11 05:51:23 +0000 |
commit | e257a17cb9cc4dc76a79680616420e75ba030b5f (patch) | |
tree | 1eaa587ddb6f0f91bbd446438e1bb46f9b1df815 /gcc | |
parent | 58170a6621f1677c692634d28c4f67a24da42b13 (diff) | |
download | gcc-e257a17cb9cc4dc76a79680616420e75ba030b5f.zip gcc-e257a17cb9cc4dc76a79680616420e75ba030b5f.tar.gz gcc-e257a17cb9cc4dc76a79680616420e75ba030b5f.tar.bz2 |
varasm.c (set_implicit_section): New function.
* varasm.c (set_implicit_section): New function.
(resolve_unique_section): Use it to set implicit section
for aliases, too.
(get_named_text_section): Use symtab_get_node (decl)->implicit_section
(default_function_section): Likewise.
(decl_binds_to_current_def_p): Constify argument.
* varasm.h (decl_binds_to_current_def_p): Update prototype.
* asan.c (asan_protect_global): Use symtab_get_node (decl)->implicit_section.
* symtab.c (dump_symtab_base): Dump implicit sections.
(verify_symtab_base): Verify sanity of sectoins and comdats.
(symtab_resolve_alias): Alias share the section of its target.
(set_section_1): New function.
(symtab_node::set_section): Move here, recurse to aliases.
(verify_symtab): Check for duplicated symtab lists.
* tree-core.h (implicit_section_name_p): Remove.
* tree-vect-data-refs.c: Include varasm.h.
(vect_can_force_dr_alignment_p): Fix conditional on when
decl bints to current definition; use
symtab_get_node (decl)->implicit_section.
* cgraph.c (cgraph_make_node_local_1): Fix section set.
* cgraph.h (struct symtab_node): Add implicit_section.
(set_section): Rename to ...
(set_section_for_node): ... this one.
(set_section): Declare.
* tree.h (DECL_HAS_IMPLICIT_SECTION_NAME_P): Remove.
* lto-cgraph.c (lto_output_node, lto_output_varpool_node,
input_overwrite_node, input_varpool_node): Stream implicit_section.
* ipa.c (symtab_remove_unreachable_nodes): Do not check symtab before
removal; it will fail in LTO.
* vtable-class-hierarchy.c: Use symtab_get_node (var_decl)->implicit_section.
* optimize.c (cdtor_comdat_group): Fix handling of aliases.
(maybe_clone_body): Move symbol across comdat groups.
* method.c (use_thunk): Copy implicit section flag.
* go/go-gcc.cc (Gcc_backend::global_variable_set_init): Use
symtab_get_node(var_decl)->implicit_section.
* lto.c (read_cgraph_and_symbols): Remove unreachable symbols.
(do_whole_program_analysis): Use verify_symtab.
From-SVN: r211434
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 32 | ||||
-rw-r--r-- | gcc/asan.c | 2 | ||||
-rw-r--r-- | gcc/cgraph.c | 2 | ||||
-rw-r--r-- | gcc/cgraph.h | 26 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/method.c | 19 | ||||
-rw-r--r-- | gcc/cp/optimize.c | 4 | ||||
-rw-r--r-- | gcc/cp/vtable-class-hierarchy.c | 2 | ||||
-rw-r--r-- | gcc/go/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/go/go-gcc.cc | 3 | ||||
-rw-r--r-- | gcc/ipa-visibility.c | 10 | ||||
-rw-r--r-- | gcc/ipa.c | 3 | ||||
-rw-r--r-- | gcc/lto-cgraph.c | 20 | ||||
-rw-r--r-- | gcc/lto/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/lto/lto.c | 6 | ||||
-rw-r--r-- | gcc/symtab.c | 107 | ||||
-rw-r--r-- | gcc/tree-core.h | 4 | ||||
-rw-r--r-- | gcc/tree-vect-data-refs.c | 2 | ||||
-rw-r--r-- | gcc/tree.c | 2 | ||||
-rw-r--r-- | gcc/tree.h | 5 | ||||
-rw-r--r-- | gcc/varasm.c | 20 | ||||
-rw-r--r-- | gcc/varasm.h | 2 |
22 files changed, 240 insertions, 48 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 839cb0d..80887df 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,35 @@ +2014-06-10 Jan Hubicka <hubicka@ucw.cz> + + * varasm.c (set_implicit_section): New function. + (resolve_unique_section): Use it to set implicit section + for aliases, too. + (get_named_text_section): Use symtab_get_node (decl)->implicit_section + (default_function_section): Likewise. + (decl_binds_to_current_def_p): Constify argument. + * varasm.h (decl_binds_to_current_def_p): Update prototype. + * asan.c (asan_protect_global): Use symtab_get_node (decl)->implicit_section. + * symtab.c (dump_symtab_base): Dump implicit sections. + (verify_symtab_base): Verify sanity of sectoins and comdats. + (symtab_resolve_alias): Alias share the section of its target. + (set_section_1): New function. + (symtab_node::set_section): Move here, recurse to aliases. + (verify_symtab): Check for duplicated symtab lists. + * tree-core.h (implicit_section_name_p): Remove. + * tree-vect-data-refs.c: Include varasm.h. + (vect_can_force_dr_alignment_p): Fix conditional on when + decl bints to current definition; use + symtab_get_node (decl)->implicit_section. + * cgraph.c (cgraph_make_node_local_1): Fix section set. + * cgraph.h (struct symtab_node): Add implicit_section. + (set_section): Rename to ... + (set_section_for_node): ... this one. + (set_section): Declare. + * tree.h (DECL_HAS_IMPLICIT_SECTION_NAME_P): Remove. + * lto-cgraph.c (lto_output_node, lto_output_varpool_node, + input_overwrite_node, input_varpool_node): Stream implicit_section. + * ipa.c (symtab_remove_unreachable_nodes): Do not check symtab before + removal; it will fail in LTO. + 2014-06-10 Kyrylo Tkachov <kyrylo.tkachov@arm.com> * config/aarch64/aarch64-simd.md (move_lo_quad_<mode>): @@ -1289,7 +1289,7 @@ asan_protect_global (tree decl) to be an array of such vars, putting padding in there breaks this assumption. */ || (DECL_SECTION_NAME (decl) != NULL_TREE - && !DECL_HAS_IMPLICIT_SECTION_NAME_P (decl)) + && !symtab_get_node (decl)->implicit_section) || DECL_SIZE (decl) == 0 || ASAN_RED_ZONE_SIZE * BITS_PER_UNIT > MAX_OFILE_ALIGNMENT || !valid_constant_size_p (DECL_SIZE_UNIT (decl)) diff --git a/gcc/cgraph.c b/gcc/cgraph.c index c3a3eef..610bf67 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -2264,7 +2264,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->set_section (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 882f1e8..dc286d9 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -93,6 +93,9 @@ public: unsigned forced_by_abi : 1; /* True when the name is known to be unique and thus it does not need mangling. */ unsigned unique_name : 1; + /* Specify whether the section was set by user or by + compiler via -ffunction-sections. */ + unsigned implicit_section : 1; /* True when body and other characteristics have been removed by symtab_remove_unreachable_nodes. */ unsigned body_removed : 1; @@ -162,17 +165,29 @@ public: comdat_group_ = group; } - /* Return section. */ - tree get_section () + /* Return section as STRING_CST. */ + tree get_section_name () { return section_; } - /* Set section. */ - void set_section (tree section) + /* Return section as string. */ + const char * get_section () + { + if (!section_) + return NULL; + return TREE_STRING_POINTER (section_); + } + + /* Set section, do not recurse into aliases. + When one wants to change section of symbol and its aliases, + use set_section */ + void set_section_for_node (tree section) { gcc_checking_assert (!section || TREE_CODE (section) == STRING_CST); section_ = section; + if (!section) + implicit_section = false; } /* Vectors of referring and referenced entities. */ @@ -193,6 +208,9 @@ public: /* Section name. Again can be private, if allowed. */ tree section_; + + /* Set section for symbol and its aliases. */ + void set_section (tree section); }; enum availability diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6b20688..35aa7bf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2014-06-10 Jan Hubicka <hubicka@ucw.cz> + + * vtable-class-hierarchy.c: Use symtab_get_node (var_decl)->implicit_section. + * optimize.c (cdtor_comdat_group): Fix handling of aliases. + (maybe_clone_body): Move symbol across comdat groups. + * method.c (use_thunk): Copy implicit section flag. + 2014-06-09 Paolo Carlini <paolo.carlini@oracle.com> PR c++/22556 diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 0ae190a..447334f 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -356,14 +356,27 @@ use_thunk (tree thunk_fndecl, bool emit_p) if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function) && targetm_common.have_named_sections) { - resolve_unique_section (function, 0, flag_function_sections); + tree fn = function; + struct symtab_node *symbol; - if (DECL_SECTION_NAME (function) != NULL && DECL_ONE_ONLY (function)) + if ((symbol = symtab_get_node (function)) + && symbol->alias) + { + if (symbol->analyzed) + fn = symtab_alias_ultimate_target (symtab_get_node (function))->decl; + else + fn = symtab_get_node (function)->alias_target; + } + resolve_unique_section (fn, 0, flag_function_sections); + + if (DECL_SECTION_NAME (fn) != NULL && DECL_ONE_ONLY (fn)) { resolve_unique_section (thunk_fndecl, 0, flag_function_sections); /* Output the thunk into the same section as function. */ - set_decl_section_name (thunk_fndecl, DECL_SECTION_NAME (function)); + set_decl_section_name (thunk_fndecl, DECL_SECTION_NAME (fn)); + symtab_get_node (thunk_fndecl)->implicit_section + = symtab_get_node (fn)->implicit_section; } } diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index ffa5258..c16e163 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -191,7 +191,7 @@ cdtor_comdat_group (tree complete, tree base) diff_seen = true; } grp_name[idx] = '\0'; - gcc_assert (diff_seen); + gcc_assert (diff_seen || symtab_get_node (complete)->alias); return get_identifier (grp_name); } @@ -553,6 +553,8 @@ maybe_clone_body (tree fn) *[CD][12]*. */ comdat_group = cdtor_comdat_group (fns[1], fns[0]); cgraph_get_create_node (fns[0])->set_comdat_group (comdat_group); + if (symtab_get_node (clone)->same_comdat_group) + symtab_remove_from_same_comdat_group (symtab_get_node (clone)); symtab_add_to_same_comdat_group (symtab_get_node (clone), symtab_get_node (fns[0])); } diff --git a/gcc/cp/vtable-class-hierarchy.c b/gcc/cp/vtable-class-hierarchy.c index 3963d73..15a8a1c 100644 --- a/gcc/cp/vtable-class-hierarchy.c +++ b/gcc/cp/vtable-class-hierarchy.c @@ -1249,7 +1249,7 @@ vtable_find_or_create_map_decl (tree base_type) set_decl_section_name (var_decl, build_string (strlen (".vtable_map_vars"), ".vtable_map_vars")); - DECL_HAS_IMPLICIT_SECTION_NAME_P (var_decl) = true; + symtab_get_node (var_decl)->implicit_section = true; DECL_INITIAL (var_decl) = initial_value; comdat_linkage (var_decl); diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 6d61c75..16d1340 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,8 @@ +2014-06-10 Jan Hubicka <hubicka@ucw.cz> + + * go/go-gcc.cc (Gcc_backend::global_variable_set_init): Use + symtab_get_node(var_decl)->implicit_section. + 2014-06-07 Jan Hubicka <hubicka@ucw.cz> * go-gcc.cc (global_variable_set_init): Use diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 7e67eed..0c9cb70 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -2374,7 +2374,8 @@ Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr) // If this variable goes in a unique section, it may need to go into // a different one now that DECL_INITIAL is set. - if (DECL_HAS_IMPLICIT_SECTION_NAME_P (var_decl)) + if (symtab_get_node(var_decl) + && symtab_get_node(var_decl)->implicit_section) { set_decl_section_name (var_decl, NULL); resolve_unique_section (var_decl, diff --git a/gcc/ipa-visibility.c b/gcc/ipa-visibility.c index 039b756..2d63441 100644 --- a/gcc/ipa-visibility.c +++ b/gcc/ipa-visibility.c @@ -512,7 +512,8 @@ function_and_variable_visibility (bool whole_program) next = next->same_comdat_group) { next->set_comdat_group (NULL); - next->set_section (NULL); + if (!next->alias) + next->set_section (NULL); symtab_make_decl_local (next->decl); next->unique_name = ((next->resolution == LDPR_PREVAILING_DEF_IRONLY || next->unique_name @@ -527,7 +528,7 @@ function_and_variable_visibility (bool whole_program) } if (TREE_PUBLIC (node->decl)) node->set_comdat_group (NULL); - if (DECL_COMDAT (node->decl)) + if (DECL_COMDAT (node->decl) && !node->alias) node->set_section (NULL); symtab_make_decl_local (node->decl); } @@ -646,7 +647,8 @@ function_and_variable_visibility (bool whole_program) next = next->same_comdat_group) { next->set_comdat_group (NULL); - next->set_section (NULL); + if (!next->alias) + next->set_section (NULL); symtab_make_decl_local (next->decl); next->unique_name = ((next->resolution == LDPR_PREVAILING_DEF_IRONLY || next->unique_name @@ -657,7 +659,7 @@ function_and_variable_visibility (bool whole_program) } if (TREE_PUBLIC (vnode->decl)) vnode->set_comdat_group (NULL); - if (DECL_COMDAT (vnode->decl)) + if (DECL_COMDAT (vnode->decl) && !vnode->alias) vnode->set_section (NULL); symtab_make_decl_local (vnode->decl); vnode->resolution = LDPR_PREVAILING_DEF_IRONLY; @@ -281,9 +281,6 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) struct pointer_set_t *reachable_call_targets = pointer_set_create (); timevar_push (TV_IPA_UNREACHABLE); -#ifdef ENABLE_CHECKING - verify_symtab (); -#endif if (optimize && flag_devirtualize) build_type_inheritance_graph (); if (file) diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index a19197d..70e813d 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -501,10 +501,8 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, streamer_write_hwi_stream (ob->main_stream, ref); } - group = node->get_section (); - if (group) - section = TREE_STRING_POINTER (group); - else + section = node->get_section (); + if (!section) section = ""; lto_output_data_stream (ob->main_stream, section, strlen (section) + 1); @@ -521,6 +519,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, bp_pack_value (&bp, node->forced_by_abi, 1); bp_pack_value (&bp, node->unique_name, 1); bp_pack_value (&bp, node->body_removed, 1); + bp_pack_value (&bp, node->implicit_section, 1); bp_pack_value (&bp, node->address_taken, 1); bp_pack_value (&bp, tag == LTO_symtab_analyzed_node && symtab_get_symbol_partitioning_class (node) == SYMBOL_PARTITION @@ -585,6 +584,7 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node, bp_pack_value (&bp, node->forced_by_abi, 1); bp_pack_value (&bp, node->unique_name, 1); bp_pack_value (&bp, node->body_removed, 1); + bp_pack_value (&bp, node->implicit_section, 1); bp_pack_value (&bp, node->writeonly, 1); bp_pack_value (&bp, node->definition, 1); alias_p = node->alias && (!boundary_p || node->weakref); @@ -631,10 +631,8 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node, streamer_write_hwi_stream (ob->main_stream, ref); } - group = node->get_section (); - if (group) - section = TREE_STRING_POINTER (group); - else + section = node->get_section (); + if (!section) section = ""; lto_output_data_stream (ob->main_stream, section, strlen (section) + 1); @@ -1054,6 +1052,7 @@ input_overwrite_node (struct lto_file_decl_data *file_data, node->forced_by_abi = bp_unpack_value (bp, 1); node->unique_name = bp_unpack_value (bp, 1); node->body_removed = bp_unpack_value (bp, 1); + node->implicit_section = bp_unpack_value (bp, 1); node->address_taken = bp_unpack_value (bp, 1); node->used_from_other_partition = bp_unpack_value (bp, 1); node->lowered = bp_unpack_value (bp, 1); @@ -1194,7 +1193,7 @@ input_node (struct lto_file_decl_data *file_data, else node->same_comdat_group = (symtab_node *) (intptr_t) LCC_NOT_FOUND; if (section) - node->set_section (section); + node->set_section_for_node (section); if (node->thunk.thunk_p) { @@ -1251,6 +1250,7 @@ input_varpool_node (struct lto_file_decl_data *file_data, node->forced_by_abi = bp_unpack_value (&bp, 1); node->unique_name = bp_unpack_value (&bp, 1); node->body_removed = bp_unpack_value (&bp, 1); + node->implicit_section = bp_unpack_value (&bp, 1); node->writeonly = bp_unpack_value (&bp, 1); node->definition = bp_unpack_value (&bp, 1); node->alias = bp_unpack_value (&bp, 1); @@ -1277,7 +1277,7 @@ input_varpool_node (struct lto_file_decl_data *file_data, node->same_comdat_group = (symtab_node *) (intptr_t) LCC_NOT_FOUND; section = read_string_cst (ib); if (section) - node->set_section (section); + node->set_section_for_node (section); node->resolution = streamer_read_enum (ib, ld_plugin_symbol_resolution, LDPR_NUM_KNOWN); gcc_assert (flag_ltrans diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 3edd6ba..ae48cdc 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,8 @@ +2014-06-10 Jan Hubicka <hubicka@ucw.cz> + + * lto.c (read_cgraph_and_symbols): Remove unreachable symbols. + (do_whole_program_analysis): Use verify_symtab. + 2014-06-07 Jan Hubicka <hubicka@ucw.cz> * lto.c (mentions_vars_p_decl_with_vis, compare_tree_sccs_1, diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 9db7845..c6c6c82 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -3090,6 +3090,10 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames) dump_symtab (cgraph_dump_file); } lto_symtab_merge_symbols (); + /* Removal of unreacable symbols is needed to make verify_symtab to pass; + we are still having duplicated comdat groups containing local statics. + We could also just remove them while merging. */ + symtab_remove_unreachable_nodes (false, dump_file); ggc_collect (); cgraph_state = CGRAPH_STATE_IPA_SSA; @@ -3261,7 +3265,7 @@ do_whole_program_analysis (void) dump_symtab (cgraph_dump_file); } #ifdef ENABLE_CHECKING - verify_cgraph (); + verify_symtab (); #endif bitmap_obstack_release (NULL); diff --git a/gcc/symtab.c b/gcc/symtab.c index 8265b4e..d7977f1 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -565,7 +565,9 @@ dump_symtab_base (FILE *f, symtab_node *node) fprintf (f, " one_only"); if (node->get_section ()) fprintf (f, " section:%s", - TREE_STRING_POINTER (node->get_section ())); + node->get_section ()); + if (node->implicit_section) + fprintf (f," (implicit_section)"); if (DECL_VISIBILITY_SPECIFIED (node->decl)) fprintf (f, " visibility_specified"); if (DECL_VISIBILITY (node->decl)) @@ -791,6 +793,7 @@ verify_symtab_base (symtab_node *node) { struct ipa_ref_list *refs = &node->ref_list; struct ipa_ref *ref; + for (int i = 0; ipa_ref_list_referring_iterate (refs, i, ref); ++i) { if (!symtab_in_same_comdat_p (ref->referring, node)) @@ -803,6 +806,38 @@ verify_symtab_base (symtab_node *node) } } } + if (node->implicit_section && !node->get_section ()) + { + error ("implicit_section flag is set but section isn't"); + error_found = true; + } + if (node->get_section () && node->get_comdat_group () + && !node->implicit_section) + { + error ("Both section and comdat group is set"); + error_found = true; + } + /* TODO: Add string table for sections, so we do not keep holding duplicated + strings. */ + if (node->alias && node->definition + && node->get_section () != symtab_alias_target (node)->get_section () + && (!node->get_section() + || !symtab_alias_target (node)->get_section () + || strcmp (node->get_section(), + symtab_alias_target (node)->get_section ()))) + { + error ("Alias and target's section differs"); + dump_symtab_node (stderr, symtab_alias_target (node)); + error_found = true; + } + if (node->alias && node->definition + && node->get_comdat_group () != symtab_alias_target (node)->get_comdat_group ()) + { + error ("Alias and target's comdat groups differs"); + dump_symtab_node (stderr, symtab_alias_target (node)); + error_found = true; + } + return error_found; } @@ -832,8 +867,30 @@ DEBUG_FUNCTION void verify_symtab (void) { symtab_node *node; + pointer_map<symtab_node *> comdat_head_map; + FOR_EACH_SYMBOL (node) - verify_symtab_node (node); + { + verify_symtab_node (node); + if (node->get_comdat_group ()) + { + symtab_node **entry, *s; + bool existed; + + entry = comdat_head_map.insert (node->get_comdat_group (), &existed); + if (!existed) + *entry = node; + else + for (s = (*entry)->same_comdat_group; s != NULL && s != node; s = s->same_comdat_group) + if (!s || s == *entry) + { + error ("Two symbols with same comdat_group are not linked by the same_comdat_group list."); + dump_symtab_node (stderr, *entry); + dump_symtab_node (stderr, s); + internal_error ("verify_symtab failed"); + } + } + } } /* Return true when RESOLUTION indicate that linker will use @@ -1024,6 +1081,33 @@ fixup_same_cpp_alias_visibility (symtab_node *node, symtab_node *target) node->externally_visible = target->externally_visible; } +/* Worker for set_section. */ + +static bool +set_section_1 (struct symtab_node *n, void *s) +{ + n->set_section_for_node ((tree)s); + return false; +} + +/* Set section of symbol and its aliases. */ + +void +symtab_node::set_section (tree section) +{ + gcc_assert (!this->alias); + symtab_for_node_and_aliases (this, set_section_1, section, true); +} + +/* Worker for symtab_resolve_alias. */ + +static bool +set_implicit_section (struct symtab_node *n, void *data ATTRIBUTE_UNUSED) +{ + n->implicit_section = true; + return false; +} + /* Add reference recording that NODE is alias of TARGET. The function can fail in the case of aliasing cycles; in this case it returns false. */ @@ -1058,6 +1142,25 @@ symtab_resolve_alias (symtab_node *node, symtab_node *target) node->analyzed = true; ipa_record_reference (node, target, IPA_REF_ALIAS, NULL); + /* Add alias into the comdat group of its target unless it is already there. */ + if (node->same_comdat_group) + symtab_remove_from_same_comdat_group (node); + node->set_comdat_group (NULL); + if (target->get_comdat_group ()) + symtab_add_to_same_comdat_group (node, target); + + if ((node->get_section () != target->get_section () + || target->get_comdat_group ()) + && node->get_section () && !node->implicit_section) + { + error ("section of alias %q+D must match section of its target", + node->decl); + } + symtab_for_node_and_aliases (node, set_section_1, target->get_section_name (), true); + if (target->implicit_section) + symtab_for_node_and_aliases (node, + set_implicit_section, NULL, true); + /* Alias targets become redundant after alias is resolved into an reference. We do not want to keep it around or we would have to mind updating them when renaming symbols. */ diff --git a/gcc/tree-core.h b/gcc/tree-core.h index b1bc0ce..b35ec77 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -1452,8 +1452,6 @@ struct GTY(()) tree_decl_with_vis { unsigned dllimport_flag : 1; /* Don't belong to VAR_DECL exclusively. */ unsigned weak_flag : 1; - /* When SECTION_NAME is implied by -ffunction-section. */ - unsigned implicit_section_name_p : 1; unsigned seen_in_bind_expr : 1; unsigned comdat_flag : 1; @@ -1472,7 +1470,7 @@ struct GTY(()) tree_decl_with_vis { unsigned cxx_destructor : 1; /* Belong to FUNCTION_DECL exclusively. */ unsigned final : 1; - /* 11 unused bits. */ + /* 12 unused bits. */ }; struct GTY(()) tree_var_decl { diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index e6be42a..1a30ea1 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -5215,7 +5215,7 @@ vect_can_force_dr_alignment_p (const_tree decl, unsigned int alignment) software projects. */ if (TREE_STATIC (decl) && DECL_SECTION_NAME (decl) != NULL_TREE - && !DECL_HAS_IMPLICIT_SECTION_NAME_P (decl)) + && !symtab_get_node (decl)->implicit_section) return false; if (TREE_STATIC (decl)) @@ -634,7 +634,7 @@ decl_section_name (const_tree node) struct symtab_node *snode = symtab_get_node (node); if (!snode) return NULL; - return snode->get_section (); + return snode->get_section_name (); } /* Set section section name of NODE to VALUE (that is expected to @@ -2399,11 +2399,6 @@ extern void decl_value_expr_insert (tree, tree); #define DECL_HAS_INIT_PRIORITY_P(NODE) \ (VAR_DECL_CHECK (NODE)->decl_with_vis.init_priority_p) -/* Specify whether the section name was set by user or by - compiler via -ffunction-sections. */ -#define DECL_HAS_IMPLICIT_SECTION_NAME_P(NODE) \ - (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.implicit_section_name_p) - extern tree decl_debug_expr_lookup (tree); extern void decl_debug_expr_insert (tree, tree); diff --git a/gcc/varasm.c b/gcc/varasm.c index 028e740..d56e67a 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -418,6 +418,15 @@ get_named_section (tree decl, const char *name, int reloc) return get_section (name, flags, decl); } +/* Worker for resolve_unique_section. */ + +static bool +set_implicit_section (struct symtab_node *n, void *data ATTRIBUTE_UNUSED) +{ + n->implicit_section = true; + return false; +} + /* If required, set DECL_SECTION_NAME to a unique name. */ void @@ -430,7 +439,9 @@ resolve_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED, || DECL_COMDAT_GROUP (decl))) { targetm.asm_out.unique_section (decl, reloc); - DECL_HAS_IMPLICIT_SECTION_NAME_P (decl) = true; + if (DECL_SECTION_NAME (decl)) + symtab_for_node_and_aliases (symtab_get_node (decl), + set_implicit_section, NULL, true); } } @@ -510,7 +521,7 @@ get_named_text_section (tree decl, buffer = ACONCAT ((stripped_name, named_section_suffix, NULL)); return get_named_section (decl, buffer, 0); } - else if (DECL_HAS_IMPLICIT_SECTION_NAME_P (decl)) + else if (symtab_get_node (decl)->implicit_section) { const char *name; @@ -539,8 +550,7 @@ default_function_section (tree decl, enum node_frequency freq, /* Old GNU linkers have buggy --gc-section support, which sometimes results in .gcc_except_table* sections being garbage collected. */ if (decl - && DECL_SECTION_NAME (decl) - && DECL_HAS_IMPLICIT_SECTION_NAME_P (decl)) + && symtab_get_node (decl)->implicit_section) return NULL; #endif @@ -6764,7 +6774,7 @@ default_binds_local_p_1 (const_tree exp, int shlib) definition from different object file) and when resolution info is available we simply use the knowledge passed to us by linker plugin. */ bool -decl_binds_to_current_def_p (tree decl) +decl_binds_to_current_def_p (const_tree decl) { gcc_assert (DECL_P (decl)); if (!targetm.binds_local_p (decl)) diff --git a/gcc/varasm.h b/gcc/varasm.h index 01b0850..aa9d47a 100644 --- a/gcc/varasm.h +++ b/gcc/varasm.h @@ -32,7 +32,7 @@ extern void notice_global_symbol (tree); extern void set_user_assembler_name (tree, const char *); extern void process_pending_assemble_externals (void); extern bool decl_replaceable_p (tree); -extern bool decl_binds_to_current_def_p (tree); +extern bool decl_binds_to_current_def_p (const_tree); extern enum tls_model decl_default_tls_model (const_tree); /* Declare DECL to be a weak symbol. */ |