diff options
Diffstat (limited to 'gcc-4.9/gcc/l-ipo.c')
-rw-r--r-- | gcc-4.9/gcc/l-ipo.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/gcc-4.9/gcc/l-ipo.c b/gcc-4.9/gcc/l-ipo.c index 59dbd33..43c5146 100644 --- a/gcc-4.9/gcc/l-ipo.c +++ b/gcc-4.9/gcc/l-ipo.c @@ -47,6 +47,8 @@ along with GCC; see the file COPYING3. If not see #include "timevar.h" #include "vec.h" #include "params.h" +#include "rtl.h" +#include "varasm.h" unsigned ggc_total_memory; /* in KB */ @@ -1118,6 +1120,27 @@ cgraph_unify_type_alias_sets (void) htab_delete (type_hash_tab); } +/* Return true if DECL is an artificial function that we do not want + to promote and which may not be available in the primary module. + The sole exception is currently __tls_init. */ + +static bool +decl_artificial_nopromote (tree decl) +{ + if (!DECL_ARTIFICIAL (decl)) + return false; + + /* Handle the __tls_init function specially as we do want to promote it and + allow the aux module to be resolved to the version in the primary module. + We check if it is prefixed by __tls_init to catch it after promotion + as well from cgraph_is_aux_decl_external. */ + if (!strncmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), "__tls_init", + 10)) + return false; + + return true; +} + /* Return true if NODE->decl from an auxiliary module has external definition (and therefore is not needed for expansion). */ @@ -1138,8 +1161,11 @@ cgraph_is_aux_decl_external (struct cgraph_node *node) /* Comdat or weak functions in aux modules are not external -- there is no guarantee that the definitition will be emitted - in the primary compilation of this auxiliary module. */ - if (DECL_COMDAT (decl) || DECL_WEAK (decl)) + in the primary compilation of this auxiliary module. + Functions marked artificial (e.g. an implicitly instantiated virtual + destructor) are also not guaranteed to be available in the primary module, + as they are not promoted by process_module_scope_static_func. */ + if (DECL_COMDAT (decl) || DECL_WEAK (decl) || decl_artificial_nopromote (decl)) return false; /* virtual functions won't be deleted in the primary module. */ @@ -1909,6 +1935,9 @@ promote_static_var_func (unsigned module_id, tree decl, bool is_extern) } varpool_link_node (node); insert_to_assembler_name_hash (node, false); + /* Possibly update the RTL name as well. */ + if (DECL_RTL_SET_P (decl)) + XSTR (XEXP (DECL_RTL (decl), 0), 0) = IDENTIFIER_POINTER (assemb_id); } if (is_extern) @@ -2014,7 +2043,7 @@ process_module_scope_static_func (struct cgraph_node *cnode) if (TREE_PUBLIC (decl) || !TREE_STATIC (decl) || DECL_EXTERNAL (decl) - || DECL_ARTIFICIAL (decl)) + || decl_artificial_nopromote (decl)) return; if (flag_ripa_no_promote_always_inline |