* tree.h (struct tree_decl): New field `tls_model'.
(DECL_TLS_MODEL): New.
(DECL_THREAD_LOCAL_P): Rename from DECL_THREAD_LOCAL, make it
a predicate.
* rtl.h (decl_default_tls_model): Add prototype for it.
* varasm.c (decl_tls_model): Rewritten and renamed to ...
(decl_default_tls_model): ... this.
(default_encode_section_info): Use DECL_TLS_MODEL instead of
decl_tls_model.
(assemble_variable): Replace DECL_THREAD_LOCAL with
DECL_THREAD_LOCAL_P.
(default_section_type_flags_1): Likewise.
(categorize_decl_for_section): Likewise.
* tree.c (staticp): Likewise.
(recompute_tree_invarant_for_addr_expr): Likewise.
* drawf2out (loc_descriptor_from_tree_1): Likewise.
* c-decl.c (diagnose_mismatched_decls): Likewise.
with DECL_THREAD_LOCAL_P.
(start_decl): Likewise.
* print-tree.c (print_node): Likewise. Print the TLS model.
(grokdeclarator): Set the default DECL_TLS_MODEL here.
* c-common.c (handle_tls_model_attribute): Rewrite to set the
TLS model up based on the attribute. Never add the attribute
to the decl's attributes list.
* config/sparc/sol2.h (ASM_DECLARE_OBJECT_NAME): Replace
DECL_THREAD_LOCAL with DECL_THREAD_LOCAL_P.
cp/
* decl.c (start_decl): Replace DECL_THREAD_LOCAL with
DECL_THREAD_LOCAL_P.
(cp_finish_decl): Likewise.
(grokvardecl): Set the default DECL_TLS_MODEL here.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101465
138bc75d-0d04-0410-961f-
82ee72b054a4
+2005-06-30 Steven Bosscher <stevenb@suse.de>
+
+ * coretypes.h (tls_model): Add TLS_MODEL_NONE as 0.
+ * tree.h (struct tree_decl): New field `tls_model'.
+ (DECL_TLS_MODEL): New.
+ (DECL_THREAD_LOCAL_P): Rename from DECL_THREAD_LOCAL, make it
+ a predicate.
+ * rtl.h (decl_default_tls_model): Add prototype for it.
+ * varasm.c (decl_tls_model): Rewritten and renamed to ...
+ (decl_default_tls_model): ... this.
+ (default_encode_section_info): Use DECL_TLS_MODEL instead of
+ decl_tls_model.
+ (assemble_variable): Replace DECL_THREAD_LOCAL with
+ DECL_THREAD_LOCAL_P.
+ (default_section_type_flags_1): Likewise.
+ (categorize_decl_for_section): Likewise.
+ * tree.c (staticp): Likewise.
+ (recompute_tree_invarant_for_addr_expr): Likewise.
+ * drawf2out (loc_descriptor_from_tree_1): Likewise.
+ * c-decl.c (diagnose_mismatched_decls): Likewise.
+ with DECL_THREAD_LOCAL_P.
+ (start_decl): Likewise.
+ * print-tree.c (print_node): Likewise. Print the TLS model.
+ (grokdeclarator): Set the default DECL_TLS_MODEL here.
+ * c-common.c (handle_tls_model_attribute): Rewrite to set the
+ TLS model up based on the attribute. Never add the attribute
+ to the decl's attributes list.
+ * config/sparc/sol2.h (ASM_DECLARE_OBJECT_NAME): Replace
+ DECL_THREAD_LOCAL with DECL_THREAD_LOCAL_P.
+
2005-06-30 Zdenek Dvorak <dvorakz@suse.cz>
PR testsuite/21967
config/sh/linux.h (FUNCTION_PROFILER): Constify a char*.
2005-06-20 Roger Sayle <roger@eyesopen.com>
-2005-06-20 Fariborz Jahanian <fjahanian@apple.com>
+ Fariborz Jahanian <fjahanian@apple.com>
* combine.c (simplify_set): Simplify setting of CC register
by removing redundant compare with 0 on RHS.
handle_tls_model_attribute (tree *node, tree name, tree args,
int ARG_UNUSED (flags), bool *no_add_attrs)
{
+ tree id;
tree decl = *node;
+ enum tls_model kind;
- if (!DECL_THREAD_LOCAL (decl))
+ *no_add_attrs = true;
+
+ if (!DECL_THREAD_LOCAL_P (decl))
{
warning (OPT_Wattributes, "%qE attribute ignored", name);
- *no_add_attrs = true;
+ return NULL_TREE;
}
- else
- {
- tree id;
- id = TREE_VALUE (args);
- if (TREE_CODE (id) != STRING_CST)
- {
- error ("tls_model argument 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 argument must be one of \"local-exec\", \"initial-exec\", \"local-dynamic\" or \"global-dynamic\"");
- *no_add_attrs = true;
- return NULL_TREE;
- }
+ kind = DECL_TLS_MODEL (decl);
+ id = TREE_VALUE (args);
+ if (TREE_CODE (id) != STRING_CST)
+ {
+ error ("tls_model argument not a string");
+ return NULL_TREE;
}
+ if (!strcmp (TREE_STRING_POINTER (id), "local-exec"))
+ kind = TLS_MODEL_LOCAL_EXEC;
+ else if (!strcmp (TREE_STRING_POINTER (id), "initial-exec"))
+ kind = TLS_MODEL_INITIAL_EXEC;
+ else if (!strcmp (TREE_STRING_POINTER (id), "local-dynamic"))
+ kind = optimize ? TLS_MODEL_LOCAL_DYNAMIC : TLS_MODEL_GLOBAL_DYNAMIC;
+ else if (!strcmp (TREE_STRING_POINTER (id), "global-dynamic"))
+ kind = TLS_MODEL_GLOBAL_DYNAMIC;
+ else
+ error ("tls_model argument must be one of \"local-exec\", \"initial-exec\", \"local-dynamic\" or \"global-dynamic\"");
+
+ DECL_TLS_MODEL (decl) = kind;
return NULL_TREE;
}
{
/* Only variables can be thread-local, and all declarations must
agree on this property. */
- if (DECL_THREAD_LOCAL (newdecl) != DECL_THREAD_LOCAL (olddecl))
+ if (DECL_THREAD_LOCAL_P (newdecl) != DECL_THREAD_LOCAL_P (olddecl))
{
- if (DECL_THREAD_LOCAL (newdecl))
+ if (DECL_THREAD_LOCAL_P (newdecl))
error ("%Jthread-local declaration of %qD follows "
"non-thread-local declaration", newdecl, newdecl);
else
if (TREE_CODE (decl) == VAR_DECL
&& !initialized
&& TREE_PUBLIC (decl)
- && !DECL_THREAD_LOCAL (decl)
+ && !DECL_THREAD_LOCAL_P (decl)
&& !flag_no_common)
DECL_COMMON (decl) = 1;
if (threadp)
{
if (targetm.have_tls)
- DECL_THREAD_LOCAL (decl) = 1;
+ DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
else
/* A mere warning is sure to result in improper semantics
at runtime. Don't bother to allow this to compile. */
{ \
HOST_WIDE_INT size; \
\
- if (DECL_THREAD_LOCAL (DECL)) \
+ if (DECL_THREAD_LOCAL_P (DECL)) \
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "tls_object"); \
else \
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
or SYMBOL_REF. This isn't used much, but both trees and RTL refer
to it, so it's here. */
enum tls_model {
- TLS_MODEL_GLOBAL_DYNAMIC = 1,
+ TLS_MODEL_NONE,
+ TLS_MODEL_GLOBAL_DYNAMIC,
TLS_MODEL_LOCAL_DYNAMIC,
TLS_MODEL_INITIAL_EXEC,
TLS_MODEL_LOCAL_EXEC
+2005-06-30 Steven Bosscher <stevenb@suse.de>
+
+ * decl.c (start_decl): Replace DECL_THREAD_LOCAL with
+ DECL_THREAD_LOCAL_P.
+ (cp_finish_decl): Likewise.
+ (grokvardecl): Set the default DECL_TLS_MODEL here.
+
2005-06-28 Joseph S. Myers <joseph@codesourcery.com>
* cvt.c (ocp_convert): Use invalid_conversion hook.
produce errors about redefs; to do this we force variables into the
data segment. */
DECL_COMMON (tem) = ((TREE_CODE (tem) != VAR_DECL
- || !DECL_THREAD_LOCAL (tem))
+ || !DECL_THREAD_LOCAL_P (tem))
&& (flag_conserve_space || ! TREE_PUBLIC (tem)));
#endif
{
/* Only PODs can have thread-local storage. Other types may require
various kinds of non-trivial initialization. */
- if (DECL_THREAD_LOCAL (decl) && !pod_type_p (TREE_TYPE (decl)))
+ if (DECL_THREAD_LOCAL_P (decl) && !pod_type_p (TREE_TYPE (decl)))
error ("%qD cannot be thread-local because it has non-POD type %qT",
decl, TREE_TYPE (decl));
/* Convert the initializer to the type of DECL, if we have not
{
init = check_initializer (decl, init, flags, &cleanup);
/* Thread-local storage cannot be dynamically initialized. */
- if (DECL_THREAD_LOCAL (decl) && init)
+ if (DECL_THREAD_LOCAL_P (decl) && init)
{
error ("%qD is thread-local and so cannot be dynamically "
"initialized", decl);
if (declspecs->specs[(int)ds_thread])
{
if (targetm.have_tls)
- DECL_THREAD_LOCAL (decl) = 1;
+ DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
else
/* A mere warning is sure to result in improper semantics
at runtime. Don't bother to allow this to compile. */
return loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), 1);
case VAR_DECL:
- if (DECL_THREAD_LOCAL (loc))
+ if (DECL_THREAD_LOCAL_P (loc))
{
rtx rtl;
open_dump_file (DFI_cse2, current_function_decl);
if (dump_file)
dump_flow_info (dump_file);
- /* CFG is no longer maintained up-to-date. */
+
tem = cse_main (get_insns (), max_reg_num (), dump_file);
/* Run a pass to eliminate duplicated assignments to condition code
if (TREE_CODE (node) == VAR_DECL && DECL_IN_TEXT_SECTION (node))
fputs (" in-text-section", file);
- if (TREE_CODE (node) == VAR_DECL && DECL_THREAD_LOCAL (node))
- fputs (" thread-local", file);
+ if (TREE_CODE (node) == VAR_DECL && DECL_THREAD_LOCAL_P (node))
+ {
+ enum tls_model kind = DECL_TLS_MODEL (node);
+ switch (kind)
+ {
+ case TLS_MODEL_GLOBAL_DYNAMIC:
+ fputs (" tls-global-dynamic", file);
+ break;
+ case TLS_MODEL_LOCAL_DYNAMIC:
+ fputs (" tls-local-dynamic", file);
+ break;
+ case TLS_MODEL_INITIAL_EXEC:
+ fputs (" tls-initial-exec", file);
+ break;
+ case TLS_MODEL_LOCAL_EXEC:
+ fputs (" tls-local-exec", file);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ }
if (TREE_CODE (node) == PARM_DECL && DECL_TRANSPARENT_UNION (node))
fputs (" transparent-union", file);
/* In varasm.c */
extern int in_data_section (void);
extern void init_varasm_once (void);
-
+extern enum tls_model decl_default_tls_model (tree);
+
/* In rtl.c */
extern void traverse_md_constants (int (*) (void **, void *), void *);
struct md_constant { char *name, *value; };
case VAR_DECL:
return ((TREE_STATIC (arg) || DECL_EXTERNAL (arg))
- && ! DECL_THREAD_LOCAL (arg)
+ && ! DECL_THREAD_LOCAL_P (arg)
&& ! DECL_NON_ADDR_CONST_P (arg)
? arg : NULL);
;
else if (decl_function_context (node) == current_function_decl
/* Addresses of thread-local variables are invariant. */
- || (TREE_CODE (node) == VAR_DECL && DECL_THREAD_LOCAL (node)))
+ || (TREE_CODE (node) == VAR_DECL
+ && DECL_THREAD_LOCAL_P (node)))
tc = false;
else
ti = tc = false;
/* Nonzero means that the decl had its visibility specified rather than
being inferred. */
-#define DECL_VISIBILITY_SPECIFIED(NODE) (DECL_CHECK (NODE)->decl.visibility_specified)
+#define DECL_VISIBILITY_SPECIFIED(NODE) \
+ (DECL_CHECK (NODE)->decl.visibility_specified)
/* In a FUNCTION_DECL, nonzero if the function cannot be inlined. */
#define DECL_UNINLINABLE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.uninlinable)
+/* In a VAR_DECL, the model to use if the data should be allocated from
+ thread-local storage. */
+#define DECL_TLS_MODEL(NODE) (VAR_DECL_CHECK (NODE)->decl.tls_model)
+
/* In a VAR_DECL, nonzero if the data should be allocated from
thread-local storage. */
-#define DECL_THREAD_LOCAL(NODE) (VAR_DECL_CHECK (NODE)->decl.thread_local_flag)
+#define DECL_THREAD_LOCAL_P(NODE) \
+ (VAR_DECL_CHECK (NODE)->decl.tls_model != TLS_MODEL_NONE)
/* In a FUNCTION_DECL, the saved representation of the body of the
entire function. */
location_t locus;
unsigned int uid;
tree size;
+
+ /* 32 bits: */
ENUM_BITFIELD(machine_mode) mode : 8;
unsigned external_flag : 1;
ENUM_BITFIELD(built_in_class) built_in_class : 2;
unsigned pure_flag : 1;
+ /* 32 bits: */
unsigned non_addressable : 1;
unsigned user_align : 1;
unsigned uninlinable : 1;
- unsigned thread_local_flag : 1;
+ unsigned gimple_reg_flag : 1;
unsigned declared_inline_flag : 1;
ENUM_BITFIELD(symbol_visibility) visibility : 2;
unsigned visibility_specified : 1;
unsigned seen_in_bind_expr : 1;
unsigned novops_flag : 1;
unsigned has_value_expr : 1;
- unsigned gimple_reg_flag : 1;
- /* 7 unused bits. */
+
+ ENUM_BITFIELD(tls_model) tls_model : 3;
+ /* 5 unused bits. */
union tree_decl_u1 {
/* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
if (DECL_SECTION_NAME (decl) || dont_output_data)
;
/* We don't implement common thread-local data at present. */
- else if (DECL_THREAD_LOCAL (decl))
+ else if (DECL_THREAD_LOCAL_P (decl))
{
if (DECL_COMMON (decl))
sorry ("thread-local COMMON data not implemented");
const_alias_set = new_alias_set ();
}
-static enum tls_model
-decl_tls_model (tree decl)
+enum tls_model
+decl_default_tls_model (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));
- gcc_assert (TREE_CODE (attr) == STRING_CST);
-
- 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
- gcc_unreachable ();
- return kind;
- }
-
is_local = targetm.binds_local_p (decl);
if (!flag_shlib)
{
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)
if (decl && DECL_ONE_ONLY (decl))
flags |= SECTION_LINKONCE;
- if (decl && TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
+ if (decl && TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
flags |= SECTION_TLS | SECTION_WRITE;
if (strcmp (name, ".bss") == 0
ret = SECCAT_RODATA;
/* There are no read-only thread-local sections. */
- if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
+ if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
{
/* Note that this would be *just* SECCAT_BSS, except that there's
no concept of a read-only thread-local-data section. */
flags |= SYMBOL_FLAG_FUNCTION;
if (targetm.binds_local_p (decl))
flags |= SYMBOL_FLAG_LOCAL;
- if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
- flags |= decl_tls_model (decl) << SYMBOL_FLAG_TLS_SHIFT;
+ if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
+ flags |= DECL_TLS_MODEL (decl) << SYMBOL_FLAG_TLS_SHIFT;
else if (targetm.in_small_data_p (decl))
flags |= SYMBOL_FLAG_SMALL;
/* ??? Why is DECL_EXTERNAL ever set for non-PUBLIC names? Without