From 24dfead40d71fa47beecd9ea8852925b7cd67144 Mon Sep 17 00:00:00 2001 From: jakub Date: Fri, 27 Sep 2002 13:30:10 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@57588 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 16 ++++++++++++++++ gcc/c-common.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ gcc/config/alpha/alpha.c | 17 +---------------- gcc/config/i386/i386.c | 18 +----------------- gcc/config/i386/i386.md | 19 ++++++++++++++----- gcc/config/ia64/ia64.c | 19 +------------------ gcc/doc/extend.texi | 9 +++++++++ gcc/flags.h | 11 ----------- gcc/tree.h | 11 +++++++++++ gcc/varasm.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 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 + + * 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 * 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. -- 2.7.4