diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-05-27 09:08:20 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-05-27 09:08:20 +0000 |
commit | 131f3644ef87d5406722ee42b0989cb5783156fa (patch) | |
tree | 6f9c3016cb1696987ba7b0cc8c1b8c5400c6157d /gcc/symtab.c | |
parent | 851ccf1afd9b0e045e7dda2539a3dfa30c16bb64 (diff) | |
download | gcc-131f3644ef87d5406722ee42b0989cb5783156fa.tar.gz |
2015-05-27 Basile Starynkevitch <basile@starynkevitch.net>
{{merged with almost GCC 5. i.e. trunk r222129 from 2015-04-15,
using svn merge -r219880:222129
svn+ssh://bstarynk@gcc.gnu.org/svn/gcc/trunk }}
[gcc/]
2015-05-27 Basile Starynkevitch <basile@starynkevitch.net>
{{merged with GCC 5, so}}
* melt-runtime.h (melt_fatal_error, melt_fatal_error_at_line):
Pass UNKNOWN_LOCATION for GCC 5. Re-indented with command:
astyle --style=gnu -s2
* melt-runtime.cc: Re-indented with command:
astyle --style=gnu -s2
(melt_branch_process_arguments, melt_ggcstart_callback)
(melt_reserved_allocation_failure): Use melt_fatal_error instead
of fatal_error.
* melt/generated/meltrunsup-inc.cc: Manually edited for fatal_error.
* melt/generated/warmelt-first.cc: Ditto.
* melt/warmelt-first.melt (melt_assert_failure_fun): Ditto.
* melt/warmelt-modes.melt (generate_runtypesupport_scanning):
Ditto, in the emitted code.
* Makefile.in: mention s-gtype instead of gt-melt-runtime.h in
dependencies.
(TEXI_GCCINT_FILES): Add meltgendoc.texi.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@223739 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/symtab.c')
-rw-r--r-- | gcc/symtab.c | 349 |
1 files changed, 202 insertions, 147 deletions
diff --git a/gcc/symtab.c b/gcc/symtab.c index aba1ae4063b..156fa3d9f28 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -313,18 +313,6 @@ symbol_table::change_decl_assembler_name (tree decl, tree name) } } -/* Return true when RESOLUTION indicate that linker will use - the symbol from non-LTO object files. */ - -bool -resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution resolution) -{ - return (resolution == LDPR_PREVAILING_DEF - || resolution == LDPR_PREEMPTED_REG - || resolution == LDPR_RESOLVED_EXEC - || resolution == LDPR_RESOLVED_DYN); -} - /* Hash sections by their names. */ hashval_t @@ -527,18 +515,18 @@ symtab_node::create_reference (symtab_node *referred_node, /* IPA_REF_ALIAS is always inserted at the beginning of the list. */ if(use_type == IPA_REF_ALIAS) - { - list2->referring.safe_insert (0, ref); - ref->referred_index = 0; + { + list2->referring.safe_insert (0, ref); + ref->referred_index = 0; - for (unsigned int i = 1; i < list2->referring.length (); i++) - list2->referring[i]->referred_index = i; - } + for (unsigned int i = 1; i < list2->referring.length (); i++) + list2->referring[i]->referred_index = i; + } else - { - list2->referring.safe_push (ref); - ref->referred_index = list2->referring.length () - 1; - } + { + list2->referring.safe_push (ref); + ref->referred_index = list2->referring.length () - 1; + } ref->referring = this; ref->referred = referred_node; @@ -743,52 +731,6 @@ symtab_node::dump_referring (FILE *file) fprintf (file, "\n"); } -/* Return true if list contains an alias. */ -bool -symtab_node::has_aliases_p (void) -{ - ipa_ref *ref = NULL; - int i; - - for (i = 0; iterate_referring (i, ref); i++) - if (ref->use == IPA_REF_ALIAS) - return true; - return false; -} - -/* Iterates I-th reference in the list, REF is also set. */ - -ipa_ref * -symtab_node::iterate_reference (unsigned i, ipa_ref *&ref) -{ - vec_safe_iterate (ref_list.references, i, &ref); - - return ref; -} - -/* Iterates I-th referring item in the list, REF is also set. */ - -ipa_ref * -symtab_node::iterate_referring (unsigned i, ipa_ref *&ref) -{ - ref_list.referring.iterate (i, &ref); - - return ref; -} - -/* Iterates I-th referring alias item in the list, REF is also set. */ - -ipa_ref * -symtab_node::iterate_direct_aliases (unsigned i, ipa_ref *&ref) -{ - ref_list.referring.iterate (i, &ref); - - if (ref && ref->use != IPA_REF_ALIAS) - return NULL; - - return ref; -} - static const char * const symtab_type_names[] = {"symbol", "function", "variable"}; /* Dump base fields of symtab nodes to F. Not to be used directly. */ @@ -1036,6 +978,11 @@ symtab_node::verify_base (void) error ("double linked list of assembler names corrupted"); error_found = true; } + if (body_removed && definition) + { + error ("node has body_removed but is definition"); + error_found = true; + } if (analyzed && !definition) { error ("node is analyzed byt it is not a definition"); @@ -1070,11 +1017,6 @@ symtab_node::verify_base (void) error ("same_comdat_group list across different groups"); error_found = true; } - if (!n->definition) - { - error ("Node has same_comdat_group but it is not a definition"); - error_found = true; - } if (n->type != type) { error ("mixing different types of symbol in same comdat groups is not supported"); @@ -1188,42 +1130,25 @@ symtab_node::verify_symtab_nodes (void) &existed); if (!existed) *entry = node; - else - for (s = (*entry)->same_comdat_group; s != NULL && s != node; s = s->same_comdat_group) + else if (!DECL_EXTERNAL (node->decl)) + { + for (s = (*entry)->same_comdat_group; + s != NULL && s != node && s != *entry; + 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."); + error ("Two symbols with same comdat_group are not linked by " + "the same_comdat_group list."); (*entry)->debug (); node->debug (); internal_error ("symtab_node::verify failed"); } + } } } } -/* Return true when NODE is known to be used from other (non-LTO) - object file. Known only when doing LTO via linker plugin. */ - -bool -symtab_node::used_from_object_file_p_worker (symtab_node *node) -{ - if (!TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl)) - return false; - if (resolution_used_from_other_file_p (node->resolution)) - return true; - return false; -} - - -/* Return true when symtab_node is known to be used from other (non-LTO) - object file. Known only when doing LTO via linker plugin. */ - -bool -symtab_node::used_from_object_file_p (void) -{ - return symtab_node::used_from_object_file_p_worker (this); -} - /* Make DECL local. FIXME: We shouldn't need to mess with rtl this early, but other code such as notice_global_symbol generates rtl. */ @@ -1237,7 +1162,11 @@ symtab_node::make_decl_local (void) return; if (TREE_CODE (decl) == VAR_DECL) - DECL_COMMON (decl) = 0; + { + DECL_COMMON (decl) = 0; + /* ADDRESSABLE flag is not defined for public symbols. */ + TREE_ADDRESSABLE (decl) = 1; + } else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); DECL_COMDAT (decl) = 0; @@ -1246,6 +1175,7 @@ symtab_node::make_decl_local (void) DECL_VISIBILITY_SPECIFIED (decl) = 0; DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; TREE_PUBLIC (decl) = 0; + DECL_DLLIMPORT_P (decl) = 0; if (!DECL_RTL_SET_P (decl)) return; @@ -1265,20 +1195,13 @@ symtab_node::make_decl_local (void) /* Walk the alias chain to return the symbol NODE is alias of. If NODE is not an alias, return NODE. - When AVAILABILITY is non-NULL, get minimal availability in the chain. */ + Assumes NODE is known to be alias. */ symtab_node * -symtab_node::ultimate_alias_target (enum availability *availability) +symtab_node::ultimate_alias_target_1 (enum availability *availability) { bool weakref_p = false; - if (!alias) - { - if (availability) - *availability = get_availability (); - return this; - } - /* To determine visibility of the target, we follow ELF semantic of aliases. Here alias is an alternative assembler name of a given definition. Its availability prevails the availability of its target (i.e. static alias of @@ -1458,16 +1381,6 @@ symtab_node::get_init_priority () return h ? h->init : DEFAULT_INIT_PRIORITY; } -/* Return availability of NODE. */ -enum availability symtab_node::get_availability (void) -{ - if (is_a <cgraph_node *> (this)) - return dyn_cast <cgraph_node *> (this)->get_availability (); - else - return dyn_cast <varpool_node *> (this)->get_availability ();; -} - - /* Return the finalization priority. */ priority_type @@ -1610,34 +1523,20 @@ symtab_node::resolve_alias (symtab_node *target) /* If alias has address taken, so does the target. */ if (address_taken) target->ultimate_alias_target ()->address_taken = true; - return true; -} - -/* Call calback on symtab node and aliases associated to this node. - When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are - skipped. */ -bool -symtab_node::call_for_symbol_and_aliases (bool (*callback) (symtab_node *, - void *), - void *data, bool include_overwritable) -{ - int i; + /* All non-weakref aliases of THIS are now in fact aliases of TARGET. */ ipa_ref *ref; - - if (callback (this, data)) - return true; - for (i = 0; iterate_referring (i, ref); i++) - if (ref->use == IPA_REF_ALIAS) - { - symtab_node *alias = ref->referring; - if (include_overwritable - || alias->get_availability () > AVAIL_INTERPOSABLE) - if (alias->call_for_symbol_and_aliases (callback, data, - include_overwritable)) - return true; - } - return false; + for (unsigned i = 0; iterate_direct_aliases (i, ref);) + { + struct symtab_node *alias_alias = ref->referring; + if (!alias_alias->weakref) + { + alias_alias->remove_all_references (); + alias_alias->create_reference (target, IPA_REF_ALIAS, NULL); + } + else i++; + } + return true; } /* Worker searching noninterposable alias. */ @@ -1659,7 +1558,6 @@ symtab_node::noninterposable_alias (symtab_node *node, void *data) != flags_from_decl_or_type (fn->decl)) || DECL_ATTRIBUTES (node->decl) != DECL_ATTRIBUTES (fn->decl)) return false; - *(symtab_node **)data = node; return true; } @@ -1691,6 +1589,7 @@ symtab_node::noninterposable_alias (void) /* Otherwise create a new one. */ new_decl = copy_node (node->decl); + DECL_DLLIMPORT_P (new_decl) = 0; DECL_NAME (new_decl) = clone_function_name (node->decl, "localalias"); if (TREE_CODE (new_decl) == FUNCTION_DECL) DECL_STRUCT_FUNCTION (new_decl) = NULL; @@ -1784,18 +1683,22 @@ symtab_node::get_partitioning_class (void) if (varpool_node *vnode = dyn_cast <varpool_node *> (this)) { + if (alias && definition && !ultimate_alias_target ()->definition) + return SYMBOL_EXTERNAL; /* Constant pool references use local symbol names that can not be promoted global. We should never put into a constant pool objects that can not be duplicated across partitions. */ if (DECL_IN_CONSTANT_POOL (decl)) return SYMBOL_DUPLICATE; + if (DECL_HARD_REGISTER (decl)) + return SYMBOL_DUPLICATE; gcc_checking_assert (vnode->definition); } /* Functions that are cloned may stay in callgraph even if they are unused. Handle them as external; compute_ltrans_boundary take care to make proper things to happen (i.e. to make them appear in the boundary but with body streamed, so clone can me materialized). */ - else if (!dyn_cast <cgraph_node *> (this)->definition) + else if (!dyn_cast <cgraph_node *> (this)->function_symbol ()->definition) return SYMBOL_EXTERNAL; /* Linker discardable symbols are duplicated to every use unless they are @@ -1964,3 +1867,155 @@ symtab_node::equal_address_to (symtab_node *s2) return 2; } + +/* Worker for call_for_symbol_and_aliases. */ + +bool +symtab_node::call_for_symbol_and_aliases_1 (bool (*callback) (symtab_node *, + void *), + void *data, + bool include_overwritable) +{ + ipa_ref *ref; + FOR_EACH_ALIAS (this, ref) + { + symtab_node *alias = ref->referring; + if (include_overwritable + || alias->get_availability () > AVAIL_INTERPOSABLE) + if (alias->call_for_symbol_and_aliases (callback, data, + include_overwritable)) + return true; + } + return false; +} + +/* Return ture if address of N is possibly compared. */ + +static bool +address_matters_1 (symtab_node *n, void *) +{ + struct ipa_ref *ref; + + if (!n->address_can_be_compared_p ()) + return false; + if (n->externally_visible || n->force_output) + return true; + + for (unsigned int i = 0; n->iterate_referring (i, ref); i++) + if (ref->address_matters_p ()) + return true; + return false; +} + +/* Return true if symbol's address may possibly be compared to other + symbol's address. */ + +bool +symtab_node::address_matters_p () +{ + gcc_assert (!alias); + return call_for_symbol_and_aliases (address_matters_1, NULL, true); +} + +/* Return ture if symbol's alignment may be increased. */ + +bool +symtab_node::can_increase_alignment_p (void) +{ + symtab_node *target = ultimate_alias_target (); + + /* For now support only variables. */ + if (TREE_CODE (decl) != VAR_DECL) + return false; + + /* With -fno-toplevel-reorder we may have already output the constant. */ + if (TREE_ASM_WRITTEN (target->decl)) + return false; + + /* If target is already placed in an anchor, we can not touch its + alignment. */ + if (DECL_RTL_SET_P (target->decl) + && MEM_P (DECL_RTL (target->decl)) + && SYMBOL_REF_HAS_BLOCK_INFO_P (XEXP (DECL_RTL (target->decl), 0))) + return false; + + /* Constant pool entries may be shared. */ + if (DECL_IN_CONSTANT_POOL (target->decl)) + return false; + + /* We cannot change alignment of symbols that may bind to symbols + in other translation unit that may contain a definition with lower + alignment. */ + if (!decl_binds_to_current_def_p (decl)) + return false; + + /* When compiling partition, be sure the symbol is not output by other + partition. */ + if (flag_ltrans + && (target->in_other_partition + || target->get_partitioning_class () == SYMBOL_DUPLICATE)) + return false; + + /* Do not override the alignment as specified by the ABI when the used + attribute is set. */ + if (DECL_PRESERVE_P (decl) || DECL_PRESERVE_P (target->decl)) + return false; + + /* Do not override explicit alignment set by the user when an explicit + section name is also used. This is a common idiom used by many + software projects. */ + if (DECL_SECTION_NAME (target->decl) != NULL && !target->implicit_section) + return false; + + return true; +} + +/* Worker for symtab_node::increase_alignment. */ + +static bool +increase_alignment_1 (symtab_node *n, void *v) +{ + unsigned int align = (size_t)v; + if (DECL_ALIGN (n->decl) < align + && n->can_increase_alignment_p ()) + { + DECL_ALIGN (n->decl) = align; + DECL_USER_ALIGN (n->decl) = 1; + } + return false; +} + +/* Increase alignment of THIS to ALIGN. */ + +void +symtab_node::increase_alignment (unsigned int align) +{ + gcc_assert (can_increase_alignment_p () && align < MAX_OFILE_ALIGNMENT); + ultimate_alias_target()->call_for_symbol_and_aliases (increase_alignment_1, + (void *)(size_t) align, + true); + gcc_assert (DECL_ALIGN (decl) >= align); +} + +/* Helper for symtab_node::definition_alignment. */ + +static bool +get_alignment_1 (symtab_node *n, void *v) +{ + *((unsigned int *)v) = MAX (*((unsigned int *)v), DECL_ALIGN (n->decl)); + return false; +} + +/* Return desired alignment of the definition. This is NOT alignment useful + to access THIS, because THIS may be interposable and DECL_ALIGN should + be used instead. It however must be guaranteed when output definition + of THIS. */ + +unsigned int +symtab_node::definition_alignment () +{ + unsigned int align = 0; + gcc_assert (!alias); + call_for_symbol_and_aliases (get_alignment_1, &align, true); + return align; +} |