This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Relat TLS model merging in lto-symtab
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 28 Jan 2015 20:59:07 +0100
- Subject: Relat TLS model merging in lto-symtab
- Authentication-results: sourceware.org; auth=none
Hi,
newer Firefox trees fails to build because jsmalloc contain variable that is
declared as tls-initial-exec in one unit but used as tls-global-dynamic
in others.
As discussed with Jakub on IRC, the linker supports some model transitions,
so we should do the same in symtab.c too.
Bootstrapped/regtested x86_64-linux, tested on firefox, comitted.
Honza
* lto-symtab.c (lto_varpool_replace_node): Merge TLS models.
Index: lto-symtab.c
===================================================================
--- lto-symtab.c (revision 220212)
+++ lto-symtab.c (working copy)
@@ -158,11 +158,44 @@ lto_varpool_replace_node (varpool_node *
if (vnode->tls_model != prevailing_node->tls_model)
{
- error_at (DECL_SOURCE_LOCATION (vnode->decl),
- "%qD is defined as %s", vnode->decl, tls_model_names [vnode->tls_model]);
- inform (DECL_SOURCE_LOCATION (prevailing_node->decl),
- "previously defined here as %s",
- tls_model_names [prevailing_node->tls_model]);
+ bool error = false;
+
+ /* Non-TLS and TLS never mix together. Also emulated model is not
+ compatible with anything else. */
+ if (prevailing_node->tls_model == TLS_MODEL_NONE
+ || prevailing_node->tls_model == TLS_MODEL_EMULATED
+ || vnode->tls_model == TLS_MODEL_NONE
+ || vnode->tls_model == TLS_MODEL_EMULATED)
+ error = true;
+ /* Linked is silently supporting transitions
+ GD -> IE, GD -> LE, LD -> LE, IE -> LE, LD -> IE.
+ Do the same transitions and error out on others. */
+ else if ((prevailing_node->tls_model == TLS_MODEL_REAL
+ || prevailing_node->tls_model == TLS_MODEL_LOCAL_DYNAMIC)
+ && (vnode->tls_model == TLS_MODEL_INITIAL_EXEC
+ || vnode->tls_model == TLS_MODEL_LOCAL_EXEC))
+ prevailing_node->tls_model = vnode->tls_model;
+ else if ((vnode->tls_model == TLS_MODEL_REAL
+ || vnode->tls_model == TLS_MODEL_LOCAL_DYNAMIC)
+ && (prevailing_node->tls_model == TLS_MODEL_INITIAL_EXEC
+ || prevailing_node->tls_model == TLS_MODEL_LOCAL_EXEC))
+ ;
+ else if (prevailing_node->tls_model == TLS_MODEL_INITIAL_EXEC
+ && vnode->tls_model == TLS_MODEL_LOCAL_EXEC)
+ prevailing_node->tls_model = vnode->tls_model;
+ else if (vnode->tls_model == TLS_MODEL_INITIAL_EXEC
+ && prevailing_node->tls_model == TLS_MODEL_LOCAL_EXEC)
+ ;
+ else
+ error = true;
+ if (error)
+ {
+ error_at (DECL_SOURCE_LOCATION (vnode->decl),
+ "%qD is defined with tls model %s", vnode->decl, tls_model_names [vnode->tls_model]);
+ inform (DECL_SOURCE_LOCATION (prevailing_node->decl),
+ "previously defined here as %s",
+ tls_model_names [prevailing_node->tls_model]);
+ }
}
/* Finally remove the replaced node. */
vnode->remove ();