From c2f7fa15c0edbf2a3873ab402813f428d44908f8 Mon Sep 17 00:00:00 2001 From: Steven Bosscher Date: Thu, 30 Jun 2005 12:17:52 +0000 Subject: [PATCH] coretypes.h (tls_model): Add TLS_MODEL_NONE as 0. * 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. 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. From-SVN: r101465 --- gcc/ChangeLog | 32 ++++++++++++++++++++++++++++- gcc/c-common.c | 45 ++++++++++++++++++++++------------------- gcc/c-decl.c | 8 ++++---- gcc/config/sparc/sol2.h | 2 +- gcc/coretypes.h | 3 ++- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/decl.c | 8 ++++---- gcc/dwarf2out.c | 2 +- gcc/passes.c | 2 +- gcc/print-tree.c | 23 +++++++++++++++++++-- gcc/rtl.h | 3 ++- gcc/tree.c | 5 +++-- gcc/tree.h | 20 +++++++++++++----- gcc/varasm.c | 34 ++++++++----------------------- 14 files changed, 124 insertions(+), 70 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a3e2696e382..4897a1e9351 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,33 @@ +2005-06-30 Steven Bosscher + + * 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 PR testsuite/21967 @@ -933,7 +963,7 @@ config/sh/linux.h (FUNCTION_PROFILER): Constify a char*. 2005-06-20 Roger Sayle -2005-06-20 Fariborz Jahanian + Fariborz Jahanian * combine.c (simplify_set): Simplify setting of CC register by removing redundant compare with 0 on RHS. diff --git a/gcc/c-common.c b/gcc/c-common.c index 2b13ad912ec..997fc717749 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -4833,35 +4833,38 @@ static tree 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; } diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 21248ae7b1d..667a28a1728 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1384,9 +1384,9 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, { /* 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 @@ -3176,7 +3176,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, 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; @@ -4663,7 +4663,7 @@ grokdeclarator (const struct c_declarator *declarator, 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. */ diff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h index eb771f6bf0d..4b3ee2d7f23 100644 --- a/gcc/config/sparc/sol2.h +++ b/gcc/config/sparc/sol2.h @@ -83,7 +83,7 @@ Boston, MA 02110-1301, USA. */ { \ 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"); \ diff --git a/gcc/coretypes.h b/gcc/coretypes.h index acf2ad99900..935f660217f 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -54,7 +54,8 @@ struct cpp_reader; 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 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a9736222b87..e7a5ca2388d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2005-06-30 Steven Bosscher + + * 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 * cvt.c (ocp_convert): Use invalid_conversion hook. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 5f2ea695f6f..4379973448e 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3749,7 +3749,7 @@ start_decl (const cp_declarator *declarator, 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 @@ -4808,7 +4808,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) { /* 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 @@ -4822,7 +4822,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) { 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); @@ -5884,7 +5884,7 @@ grokvardecl (tree type, 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. */ diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index f29f4ef526b..d16b809857d 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -8951,7 +8951,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address) 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; diff --git a/gcc/passes.c b/gcc/passes.c index 6910f333ea3..a5670e2f1b7 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -1009,7 +1009,7 @@ rest_of_handle_cse2 (void) 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 diff --git a/gcc/print-tree.c b/gcc/print-tree.c index 0b2563aa479..b251933da66 100644 --- a/gcc/print-tree.c +++ b/gcc/print-tree.c @@ -357,8 +357,27 @@ print_node (FILE *file, const char *prefix, tree node, int indent) 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); diff --git a/gcc/rtl.h b/gcc/rtl.h index 72fe10a66a7..92a15586f29 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -2089,7 +2089,8 @@ extern rtx emit_library_call_value (rtx, rtx, enum libcall_type, /* 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; }; diff --git a/gcc/tree.c b/gcc/tree.c index 0088a9b2216..9a747ac5c36 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -1652,7 +1652,7 @@ staticp (tree arg) 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); @@ -2480,7 +2480,8 @@ do { tree _node = (NODE); \ ; 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; diff --git a/gcc/tree.h b/gcc/tree.h index 191ba133141..802ab15ac26 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2184,14 +2184,20 @@ extern void decl_debug_expr_insert (tree, tree); /* 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. */ @@ -2385,6 +2391,8 @@ struct tree_decl GTY(()) location_t locus; unsigned int uid; tree size; + + /* 32 bits: */ ENUM_BITFIELD(machine_mode) mode : 8; unsigned external_flag : 1; @@ -2413,10 +2421,11 @@ struct tree_decl GTY(()) 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; @@ -2438,8 +2447,9 @@ struct tree_decl GTY(()) 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 diff --git a/gcc/varasm.c b/gcc/varasm.c index 3c1eb115235..9e3183dd9d6 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -1716,7 +1716,7 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED, 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"); @@ -4745,31 +4745,12 @@ init_varasm_once (void) 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) { @@ -4778,6 +4759,7 @@ decl_tls_model (tree decl) 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) @@ -4828,7 +4810,7 @@ default_section_type_flags_1 (tree decl, const char *name, int reloc, 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 @@ -5106,7 +5088,7 @@ categorize_decl_for_section (tree decl, int reloc, int shlib) 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. */ @@ -5370,8 +5352,8 @@ default_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED) 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 -- 2.30.2