extend.texi (tls_model): Document.
authorJakub Jelinek <jakub@redhat.com>
Fri, 27 Sep 2002 13:30:10 +0000 (15:30 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 27 Sep 2002 13:30:10 +0000 (15:30 +0200)
* doc/extend.texi (tls_model): Document.
* varasm.c (decl_tls_model): New.
* c-common.c (handle_tls_model_attribute): New.
(c_common_attribute_table): Add tls_model.
* config/alpha/alpha.c (alpha_encode_section_info): Use
decl_tls_model.
* flags.h (enum tls_model, flag_tls_default): Move...
* tree.h (enum tls_model, flag_tls_default): ...here.
(decl_tls_model): New prototype.
* config/ia64/ia64.c (ia64_encode_section_info): Likewise.
* config/i386/i386.c (ix86_encode_section_info): Likewise.
* config/i386/i386.md (tls_global_dynamic, tls_local_dynamic_base):
Allow !flag_pic.

From-SVN: r57588

gcc/ChangeLog
gcc/c-common.c
gcc/config/alpha/alpha.c
gcc/config/i386/i386.c
gcc/config/i386/i386.md
gcc/config/ia64/ia64.c
gcc/doc/extend.texi
gcc/flags.h
gcc/tree.h
gcc/varasm.c

index 8029dd1fdd8267aa20399b3863eb58898d730767..97e46f9ee4fed1a1696b5d35f8b163d7e321209b 100644 (file)
@@ -1,3 +1,19 @@
+2002-09-27  Jakub Jelinek  <jakub@redhat.com>
+
+       * doc/extend.texi (tls_model): Document.
+       * varasm.c (decl_tls_model): New.
+       * c-common.c (handle_tls_model_attribute): New.
+       (c_common_attribute_table): Add tls_model.
+       * config/alpha/alpha.c (alpha_encode_section_info): Use
+       decl_tls_model.
+       * flags.h (enum tls_model, flag_tls_default): Move...
+       * tree.h (enum tls_model, flag_tls_default): ...here.
+       (decl_tls_model): New prototype.
+       * config/ia64/ia64.c (ia64_encode_section_info): Likewise.
+       * config/i386/i386.c (ix86_encode_section_info): Likewise.
+       * config/i386/i386.md (tls_global_dynamic, tls_local_dynamic_base):
+       Allow !flag_pic.
+
 2002-09-27  Kazu Hirata  <kazu@cs.umass.edu>
 
        * LANGUAGES: Follow spelling conventions.
index 960e4cfe75bd89c3edda63edb416fabbde766c67..b3358c2c1c2edca2da5643926bf6d39d5fb08f26 100644 (file)
@@ -749,6 +749,8 @@ static tree handle_alias_attribute  PARAMS ((tree *, tree, tree, int,
                                                 bool *));
 static tree handle_visibility_attribute        PARAMS ((tree *, tree, tree, int,
                                                 bool *));
+static tree handle_tls_model_attribute PARAMS ((tree *, tree, tree, int,
+                                                bool *));
 static tree handle_no_instrument_function_attribute PARAMS ((tree *, tree,
                                                             tree, int,
                                                             bool *));
@@ -847,6 +849,8 @@ const struct attribute_spec c_common_attribute_table[] =
                              handle_vector_size_attribute },
   { "visibility",            1, 1, true,  false, false,
                              handle_visibility_attribute },
+  { "tls_model",             1, 1, true,  false, false,
+                             handle_tls_model_attribute },
   { "nonnull",                0, -1, false, true, true,
                              handle_nonnull_attribute },
   { "nothrow",                0, 0, true,  false, false,
@@ -5895,6 +5899,49 @@ handle_visibility_attribute (node, name, args, flags, no_add_attrs)
   return NULL_TREE;
 }
 
+/* Handle an "tls_model" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_tls_model_attribute (node, name, args, flags, no_add_attrs)
+     tree *node;
+     tree name;
+     tree args;
+     int flags ATTRIBUTE_UNUSED;
+     bool *no_add_attrs;
+{
+  tree decl = *node;
+
+  if (! DECL_THREAD_LOCAL (decl))
+    {
+      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+      *no_add_attrs = true;
+    }
+  else
+    {
+      tree id;
+
+      id = TREE_VALUE (args);
+      if (TREE_CODE (id) != STRING_CST)
+       {
+         error ("tls_model arg not a string");
+         *no_add_attrs = true;
+         return NULL_TREE;
+       }
+      if (strcmp (TREE_STRING_POINTER (id), "local-exec")
+         && strcmp (TREE_STRING_POINTER (id), "initial-exec")
+         && strcmp (TREE_STRING_POINTER (id), "local-dynamic")
+         && strcmp (TREE_STRING_POINTER (id), "global-dynamic"))
+       {
+         error ("tls_model arg must be one of \"local-exec\", \"initial-exec\", \"local-dynamic\" or \"global-dynamic\"");
+         *no_add_attrs = true;
+         return NULL_TREE;
+       }
+    }
+
+  return NULL_TREE;
+}
+
 /* Handle a "no_instrument_function" attribute; arguments as in
    struct attribute_spec.handler.  */
 
index d26cb547425b6b5bb85839eca01eeaccd062bbb1..b35e3f9c85d2184bdc8a0877cc68c03c6c7dfad3 100644 (file)
@@ -1880,22 +1880,7 @@ alpha_encode_section_info (decl, first)
   /* Care for TLS variables.  */
   if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
     {
-      enum tls_model kind;
-      if (!flag_pic)
-       {
-         if (is_local)
-           kind = TLS_MODEL_LOCAL_EXEC;
-         else
-           kind = TLS_MODEL_INITIAL_EXEC;
-       }
-      else if (is_local)
-       kind = TLS_MODEL_LOCAL_DYNAMIC;
-      else
-       kind = TLS_MODEL_GLOBAL_DYNAMIC;
-      if (kind < flag_tls_default)
-       kind = flag_tls_default;
-
-      switch (kind)
+      switch (decl_tls_model (decl))
        {
        case TLS_MODEL_GLOBAL_DYNAMIC:
          encoding = 'G';
index 777721c61bc86659d97588e94faa4ffb7cbd5582..f27f0a25e15f2fc338b2e2e3b9abfcf9fee39a1c 100644 (file)
@@ -5542,23 +5542,7 @@ ix86_encode_section_info (decl, first)
       const char *symbol_str;
       char *newstr;
       size_t len;
-      enum tls_model kind;
-
-      if (!flag_pic)
-       {
-         if (local_p)
-           kind = TLS_MODEL_LOCAL_EXEC;
-         else
-           kind = TLS_MODEL_INITIAL_EXEC;
-       }
-      /* Local dynamic is inefficient when we're not combining the
-        parts of the address.  */
-      else if (optimize && local_p)
-       kind = TLS_MODEL_LOCAL_DYNAMIC;
-      else
-       kind = TLS_MODEL_GLOBAL_DYNAMIC;
-      if (kind < flag_tls_default)
-       kind = flag_tls_default;
+      enum tls_model kind = decl_tls_model (decl);
 
       symbol_str = XSTR (symbol, 0);
 
index 02e4ee8c0e39aa61c3a3900b632cffcb231616f5..f616ed2f4c9e5f77be690fe037a74e1a3c04548e 100644 (file)
              (clobber (reg:CC 17))])]
   ""
 {
-  if (!flag_pic)
-    abort ();
-  operands[2] = pic_offset_table_rtx;
+  if (flag_pic)
+    operands[2] = pic_offset_table_rtx;
+  else
+    {
+      operands[2] = gen_reg_rtx (Pmode);
+      emit_insn (gen_set_got (operands[2]));
+    }
   operands[3] = ix86_tls_get_addr ();
 })
 
              (clobber (reg:CC 17))])]
   ""
 {
-  if (!flag_pic)
-    abort ();
+  if (flag_pic)
+    operands[2] = pic_offset_table_rtx;
+  else
+    {
+      operands[2] = gen_reg_rtx (Pmode);
+      emit_insn (gen_set_got (operands[2]));
+    }
   operands[1] = pic_offset_table_rtx;
   operands[2] = ix86_tls_get_addr ();
 })
index 93b02dd68c15a12ff02c204f213d89828f5e0f9a..0db9878023eb0ea1f4ec4d82affb0504eb72e08b 100644 (file)
@@ -7142,24 +7142,7 @@ ia64_encode_section_info (decl, first)
   is_local = (*targetm.binds_local_p) (decl);
 
   if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
-    {
-      enum tls_model kind;
-      if (!flag_pic)
-       {
-         if (is_local)
-           kind = TLS_MODEL_LOCAL_EXEC;
-         else
-           kind = TLS_MODEL_INITIAL_EXEC;
-       }
-      else if (is_local)
-       kind = TLS_MODEL_LOCAL_DYNAMIC;
-      else
-       kind = TLS_MODEL_GLOBAL_DYNAMIC;
-      if (kind < flag_tls_default)
-       kind = flag_tls_default;
-
-      encoding = " GLil"[kind];
-    }
+    encoding = " GLil"[decl_tls_model (decl)];
   /* Determine if DECL will wind up in .sdata/.sbss.  */
   else if (is_local && ia64_in_small_data_p (decl))
     encoding = 's';
index 9e121e4fc0962d86cba02172a94df3035d0c43f5..a95098fc1c7f164fe8269a214cc6a227fb32e96b 100644 (file)
@@ -2332,6 +2332,15 @@ since it is known that the calling function loaded the correct value.
 
 Not all ELF targets support this attribute.
 
+@item tls_model ("@var{tls_model}")
+@cindex @code{tls_model} attribute
+The @code{tls_model} attribute sets thread-local storage model
+(@pxref{Thread-Local}) of a particular @code{__thread} variable,
+overriding @code{-ftls-model=} command line switch on a per-variable
+basis.
+The @var{tls_model} argument should be one of @code{global-dynamic},
+@code{local-dynamic}, @code{initial-exec} or @code{local-exec}.
+
 @item regparm (@var{number})
 @cindex functions that are passed arguments in registers on the 386
 On the Intel 386, the @code{regparm} attribute causes the compiler to
index f033887e02c1e2852d14e4edf8bfb71f87fa6ff2..1578a2499cdc08b2abf2070215e7e1e0b11b1629 100644 (file)
@@ -467,17 +467,6 @@ extern int flag_pedantic_errors;
 
 extern int flag_pic;
 
-/* Set to the default thread-local storage (tls) model to use.  */
-
-enum tls_model {
-  TLS_MODEL_GLOBAL_DYNAMIC = 1,
-  TLS_MODEL_LOCAL_DYNAMIC,
-  TLS_MODEL_INITIAL_EXEC,
-  TLS_MODEL_LOCAL_EXEC
-};
-
-extern enum tls_model flag_tls_default;
-
 /* Nonzero means generate extra code for exception handling and enable
    exception handling.  */
 
index ad3409849cfeafe9cc894843e8f29cab0076953d..e9647816378f1e633d891b155eba467e0afd3b7d 100644 (file)
@@ -2102,7 +2102,17 @@ extern GTY(()) tree integer_types[itk_none];
 #define long_unsigned_type_node                integer_types[itk_unsigned_long]
 #define long_long_integer_type_node    integer_types[itk_long_long]
 #define long_long_unsigned_type_node   integer_types[itk_unsigned_long_long]
+\f
+/* Set to the default thread-local storage (tls) model to use.  */
+
+enum tls_model {
+  TLS_MODEL_GLOBAL_DYNAMIC = 1,
+  TLS_MODEL_LOCAL_DYNAMIC,
+  TLS_MODEL_INITIAL_EXEC,
+  TLS_MODEL_LOCAL_EXEC
+};
 
+extern enum tls_model flag_tls_default;
 \f
 #define NULL_TREE (tree) NULL
 
@@ -2988,6 +2998,7 @@ extern void make_decl_rtl         PARAMS ((tree, const char *));
 extern void make_decl_one_only         PARAMS ((tree));
 extern int supports_one_only           PARAMS ((void));
 extern void variable_section           PARAMS ((tree, int));
+enum tls_model decl_tls_model          PARAMS ((tree));
 
 /* In fold-const.c */
 extern int div_and_round_double                PARAMS ((enum tree_code, int,
index 0ff605f7b13ec9c2f0b54a1b1395e4c116ab38be..d24e914811c7b5341a16771e2b5d1ef49355747c 100644 (file)
@@ -4726,6 +4726,52 @@ init_varasm_once ()
   const_alias_set = new_alias_set ();
 }
 
+enum tls_model
+decl_tls_model (decl)
+     tree decl;
+{
+  enum tls_model kind;
+  tree attr = lookup_attribute ("tls_model", DECL_ATTRIBUTES (decl));
+  bool is_local;
+
+  if (attr)
+    {
+      attr = TREE_VALUE (TREE_VALUE (attr));
+      if (TREE_CODE (attr) != STRING_CST)
+       abort ();
+      if (!strcmp (TREE_STRING_POINTER (attr), "local-exec"))
+       kind = TLS_MODEL_LOCAL_EXEC;
+      else if (!strcmp (TREE_STRING_POINTER (attr), "initial-exec"))
+       kind = TLS_MODEL_INITIAL_EXEC;
+      else if (!strcmp (TREE_STRING_POINTER (attr), "local-dynamic"))
+       kind = optimize ? TLS_MODEL_LOCAL_DYNAMIC : TLS_MODEL_GLOBAL_DYNAMIC;
+      else if (!strcmp (TREE_STRING_POINTER (attr), "global-dynamic"))
+       kind = TLS_MODEL_GLOBAL_DYNAMIC;
+      else
+       abort ();
+      return kind;
+    }
+
+  is_local = (*targetm.binds_local_p) (decl);
+  if (!flag_pic)
+    {
+      if (is_local)
+       kind = TLS_MODEL_LOCAL_EXEC;
+      else
+       kind = TLS_MODEL_INITIAL_EXEC;
+    }
+  /* Local dynamic is inefficient when we're not combining the
+     parts of the address.  */
+  else if (optimize && is_local)
+    kind = TLS_MODEL_LOCAL_DYNAMIC;
+  else
+    kind = TLS_MODEL_GLOBAL_DYNAMIC;
+  if (kind < flag_tls_default)
+    kind = flag_tls_default;
+
+  return kind;
+}
+
 /* Select a set of attributes for section NAME based on the properties
    of DECL and whether or not RELOC indicates that DECL's initializer
    might contain runtime relocations.