aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/l-ipo.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/l-ipo.c')
-rw-r--r--gcc-4.9/gcc/l-ipo.c35
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 59dbd33fd..43c514696 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