aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2002-09-27 15:30:10 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2002-09-27 15:30:10 +0200
commitdce81a1a59f9663eb72e722e17f490adc3f5a2d6 (patch)
treeb7ac095e3e844e739365675e99f4e724059e2a38
parent0e9e1e0a42eff5ec265470b7e8928cb3b3ad2d70 (diff)
downloadgcc-dce81a1a59f9663eb72e722e17f490adc3f5a2d6.zip
gcc-dce81a1a59f9663eb72e722e17f490adc3f5a2d6.tar.gz
gcc-dce81a1a59f9663eb72e722e17f490adc3f5a2d6.tar.bz2
extend.texi (tls_model): Document.
* 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
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/c-common.c47
-rw-r--r--gcc/config/alpha/alpha.c17
-rw-r--r--gcc/config/i386/i386.c18
-rw-r--r--gcc/config/i386/i386.md19
-rw-r--r--gcc/config/ia64/ia64.c19
-rw-r--r--gcc/doc/extend.texi9
-rw-r--r--gcc/flags.h11
-rw-r--r--gcc/tree.h11
-rw-r--r--gcc/varasm.c46
10 files changed, 146 insertions, 67 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8029dd1..97e46f9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 960e4cf..b3358c2 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -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. */
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index d26cb54..b35e3f9 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -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';
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 777721c..f27f0a2 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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);
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 02e4ee8..f616ed2 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -13822,9 +13822,13 @@
(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 ();
})
@@ -13864,8 +13868,13 @@
(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 ();
})
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 93b02dd..0db9878 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -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';
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 9e121e4..a95098f 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -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
diff --git a/gcc/flags.h b/gcc/flags.h
index f033887..1578a24 100644
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -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. */
diff --git a/gcc/tree.h b/gcc/tree.h
index ad34098..e964781 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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]
+
+/* 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;
#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,
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 0ff605f..d24e914 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -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.