* lto-symtab.c (lto_varpool_replace_node): Merge TLS models.
authorJan Hubicka <hubicka@ucw.cz>
Wed, 28 Jan 2015 19:57:35 +0000 (20:57 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 28 Jan 2015 19:57:35 +0000 (19:57 +0000)
From-SVN: r220214

gcc/lto/ChangeLog
gcc/lto/lto-symtab.c

index f247f4193c771997e92ecaad5ca3eea6c3bf1898..98f256a035c0af31717bafda73a365db75e0126b 100644 (file)
@@ -1,3 +1,7 @@
+2014-12-11  Jan Hubicka  <hubicka@ucw.cz>
+
+       * lto-symtab.c (lto_varpool_replace_node): Merge TLS models.
+
 2014-12-11  Jan Hubicka  <hubicka@ucw.cz>
 
        * lto.c (compare_tree_sccs_1): Add comparsion of
index e3cc1902e03ffd0de0df4faf6a6c8fd78ea28257..98edb883440a94047c48f8322ed0da5aad018aec 100644 (file)
@@ -158,11 +158,44 @@ lto_varpool_replace_node (varpool_node *vnode,
 
   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 ();