Commit dce81a1a by Jakub Jelinek Committed by Jakub Jelinek

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
parent 0e9e1e0a
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> 2002-09-27 Kazu Hirata <kazu@cs.umass.edu>
* LANGUAGES: Follow spelling conventions. * LANGUAGES: Follow spelling conventions.
......
...@@ -749,6 +749,8 @@ static tree handle_alias_attribute PARAMS ((tree *, tree, tree, int, ...@@ -749,6 +749,8 @@ static tree handle_alias_attribute PARAMS ((tree *, tree, tree, int,
bool *)); bool *));
static tree handle_visibility_attribute PARAMS ((tree *, tree, tree, int, static tree handle_visibility_attribute PARAMS ((tree *, tree, tree, int,
bool *)); bool *));
static tree handle_tls_model_attribute PARAMS ((tree *, tree, tree, int,
bool *));
static tree handle_no_instrument_function_attribute PARAMS ((tree *, tree, static tree handle_no_instrument_function_attribute PARAMS ((tree *, tree,
tree, int, tree, int,
bool *)); bool *));
...@@ -847,6 +849,8 @@ const struct attribute_spec c_common_attribute_table[] = ...@@ -847,6 +849,8 @@ const struct attribute_spec c_common_attribute_table[] =
handle_vector_size_attribute }, handle_vector_size_attribute },
{ "visibility", 1, 1, true, false, false, { "visibility", 1, 1, true, false, false,
handle_visibility_attribute }, handle_visibility_attribute },
{ "tls_model", 1, 1, true, false, false,
handle_tls_model_attribute },
{ "nonnull", 0, -1, false, true, true, { "nonnull", 0, -1, false, true, true,
handle_nonnull_attribute }, handle_nonnull_attribute },
{ "nothrow", 0, 0, true, false, false, { "nothrow", 0, 0, true, false, false,
...@@ -5895,6 +5899,49 @@ handle_visibility_attribute (node, name, args, flags, no_add_attrs) ...@@ -5895,6 +5899,49 @@ handle_visibility_attribute (node, name, args, flags, no_add_attrs)
return NULL_TREE; 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 /* Handle a "no_instrument_function" attribute; arguments as in
struct attribute_spec.handler. */ struct attribute_spec.handler. */
......
...@@ -1880,22 +1880,7 @@ alpha_encode_section_info (decl, first) ...@@ -1880,22 +1880,7 @@ alpha_encode_section_info (decl, first)
/* Care for TLS variables. */ /* Care for TLS variables. */
if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl)) if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
{ {
enum tls_model kind; switch (decl_tls_model (decl))
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)
{ {
case TLS_MODEL_GLOBAL_DYNAMIC: case TLS_MODEL_GLOBAL_DYNAMIC:
encoding = 'G'; encoding = 'G';
......
...@@ -5542,23 +5542,7 @@ ix86_encode_section_info (decl, first) ...@@ -5542,23 +5542,7 @@ ix86_encode_section_info (decl, first)
const char *symbol_str; const char *symbol_str;
char *newstr; char *newstr;
size_t len; size_t len;
enum tls_model kind; enum tls_model kind = decl_tls_model (decl);
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;
symbol_str = XSTR (symbol, 0); symbol_str = XSTR (symbol, 0);
......
...@@ -13822,9 +13822,13 @@ ...@@ -13822,9 +13822,13 @@
(clobber (reg:CC 17))])] (clobber (reg:CC 17))])]
"" ""
{ {
if (!flag_pic) if (flag_pic)
abort (); operands[2] = pic_offset_table_rtx;
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 (); operands[3] = ix86_tls_get_addr ();
}) })
...@@ -13864,8 +13868,13 @@ ...@@ -13864,8 +13868,13 @@
(clobber (reg:CC 17))])] (clobber (reg:CC 17))])]
"" ""
{ {
if (!flag_pic) if (flag_pic)
abort (); 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[1] = pic_offset_table_rtx;
operands[2] = ix86_tls_get_addr (); operands[2] = ix86_tls_get_addr ();
}) })
......
...@@ -7142,24 +7142,7 @@ ia64_encode_section_info (decl, first) ...@@ -7142,24 +7142,7 @@ ia64_encode_section_info (decl, first)
is_local = (*targetm.binds_local_p) (decl); is_local = (*targetm.binds_local_p) (decl);
if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl)) if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
{ encoding = " GLil"[decl_tls_model (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];
}
/* Determine if DECL will wind up in .sdata/.sbss. */ /* Determine if DECL will wind up in .sdata/.sbss. */
else if (is_local && ia64_in_small_data_p (decl)) else if (is_local && ia64_in_small_data_p (decl))
encoding = 's'; encoding = 's';
......
...@@ -2332,6 +2332,15 @@ since it is known that the calling function loaded the correct value. ...@@ -2332,6 +2332,15 @@ since it is known that the calling function loaded the correct value.
Not all ELF targets support this attribute. 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}) @item regparm (@var{number})
@cindex functions that are passed arguments in registers on the 386 @cindex functions that are passed arguments in registers on the 386
On the Intel 386, the @code{regparm} attribute causes the compiler to On the Intel 386, the @code{regparm} attribute causes the compiler to
......
...@@ -467,17 +467,6 @@ extern int flag_pedantic_errors; ...@@ -467,17 +467,6 @@ extern int flag_pedantic_errors;
extern int flag_pic; 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 /* Nonzero means generate extra code for exception handling and enable
exception handling. */ exception handling. */
......
...@@ -2102,7 +2102,17 @@ extern GTY(()) tree integer_types[itk_none]; ...@@ -2102,7 +2102,17 @@ extern GTY(()) tree integer_types[itk_none];
#define long_unsigned_type_node integer_types[itk_unsigned_long] #define long_unsigned_type_node integer_types[itk_unsigned_long]
#define long_long_integer_type_node integer_types[itk_long_long] #define long_long_integer_type_node integer_types[itk_long_long]
#define long_long_unsigned_type_node integer_types[itk_unsigned_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 #define NULL_TREE (tree) NULL
...@@ -2988,6 +2998,7 @@ extern void make_decl_rtl PARAMS ((tree, const char *)); ...@@ -2988,6 +2998,7 @@ extern void make_decl_rtl PARAMS ((tree, const char *));
extern void make_decl_one_only PARAMS ((tree)); extern void make_decl_one_only PARAMS ((tree));
extern int supports_one_only PARAMS ((void)); extern int supports_one_only PARAMS ((void));
extern void variable_section PARAMS ((tree, int)); extern void variable_section PARAMS ((tree, int));
enum tls_model decl_tls_model PARAMS ((tree));
/* In fold-const.c */ /* In fold-const.c */
extern int div_and_round_double PARAMS ((enum tree_code, int, extern int div_and_round_double PARAMS ((enum tree_code, int,
......
...@@ -4726,6 +4726,52 @@ init_varasm_once () ...@@ -4726,6 +4726,52 @@ init_varasm_once ()
const_alias_set = new_alias_set (); 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 /* Select a set of attributes for section NAME based on the properties
of DECL and whether or not RELOC indicates that DECL's initializer of DECL and whether or not RELOC indicates that DECL's initializer
might contain runtime relocations. might contain runtime relocations.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment