This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] include the TLS model in the tree decl
- From: Steven Bosscher <stevenb at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 21 Jun 2005 18:10:03 +0200
- Subject: [patch] include the TLS model in the tree decl
Hi,
Right now the TLS model of a VAR_DECL is determined in decl_tls_model
in varasm.c, with an attribute to allow the user to set the model by
hand. This patch steals three bits on tree_decl to store the model on
the tree instead. This is more convenient if we're going to expose
TLS addressing modes at the tree level.
Bootstrapped and tested (c,c++,objc) on x86_64-unknown-linux-gnu.
OK for mainline?
Gr.
Steven
* 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.
* print-tree.c (print_node): Likewise.
* c-decl.c (diagnose_mismatched_decls): Likewise.
with DECL_THREAD_LOCAL_P.
(start_decl): Likewise.
(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.
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.635
diff -u -3 -p -r1.635 c-common.c
--- c-common.c 15 Jun 2005 10:33:32 -0000 1.635
+++ c-common.c 21 Jun 2005 13:35:31 -0000
@@ -4713,35 +4713,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;
}
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.664
diff -u -3 -p -r1.664 c-decl.c
--- c-decl.c 19 Jun 2005 16:55:20 -0000 1.664
+++ c-decl.c 21 Jun 2005 13:35:34 -0000
@@ -1402,9 +1402,9 @@ diagnose_mismatched_decls (tree newdecl,
{
/* 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
@@ -3192,7 +3192,7 @@ start_decl (struct c_declarator *declara
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;
@@ -4678,7 +4678,7 @@ grokdeclarator (const struct c_declarato
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. */
Index: coretypes.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/coretypes.h,v
retrieving revision 1.6
diff -u -3 -p -r1.6 coretypes.h
--- coretypes.h 15 Oct 2004 14:47:06 -0000 1.6
+++ coretypes.h 21 Jun 2005 13:35:34 -0000
@@ -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
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.601
diff -u -3 -p -r1.601 dwarf2out.c
--- dwarf2out.c 9 Jun 2005 16:21:31 -0000 1.601
+++ dwarf2out.c 21 Jun 2005 13:35:38 -0000
@@ -8950,7 +8950,7 @@ loc_descriptor_from_tree_1 (tree loc, in
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;
Index: print-tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/print-tree.c,v
retrieving revision 1.100
diff -u -3 -p -r1.100 print-tree.c
--- print-tree.c 31 Mar 2005 00:09:10 -0000 1.100
+++ print-tree.c 21 Jun 2005 13:35:38 -0000
@@ -357,7 +357,7 @@ print_node (FILE *file, const char *pref
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))
+ if (TREE_CODE (node) == VAR_DECL && DECL_THREAD_LOCAL_P (node))
fputs (" thread-local", file);
if (TREE_CODE (node) == PARM_DECL && DECL_TRANSPARENT_UNION (node))
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.553
diff -u -3 -p -r1.553 rtl.h
--- rtl.h 11 Jun 2005 22:30:16 -0000 1.553
+++ rtl.h 21 Jun 2005 13:35:39 -0000
@@ -2089,7 +2089,8 @@ extern rtx emit_library_call_value (rtx,
/* 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; };
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.487
diff -u -3 -p -r1.487 tree.c
--- tree.c 7 Jun 2005 21:45:01 -0000 1.487
+++ tree.c 21 Jun 2005 13:35:41 -0000
@@ -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;
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.737
diff -u -3 -p -r1.737 tree.h
--- tree.h 16 Jun 2005 18:09:34 -0000 1.737
+++ tree.h 21 Jun 2005 13:35:43 -0000
@@ -2179,14 +2179,20 @@ extern void decl_debug_expr_insert (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. */
@@ -2380,6 +2386,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;
@@ -2408,10 +2416,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;
@@ -2433,8 +2442,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
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.513
diff -u -3 -p -r1.513 varasm.c
--- varasm.c 8 Jun 2005 00:15:53 -0000 1.513
+++ varasm.c 21 Jun 2005 13:35:45 -0000
@@ -1716,7 +1716,7 @@ assemble_variable (tree decl, int top_le
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");
@@ -4743,31 +4743,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)
{
@@ -4776,6 +4757,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)
@@ -4826,7 +4808,7 @@ default_section_type_flags_1 (tree decl,
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
@@ -5104,7 +5086,7 @@ categorize_decl_for_section (tree decl,
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. */
@@ -5368,8 +5350,8 @@ default_encode_section_info (tree decl,
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
Index: config/sparc/sol2.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sol2.h,v
retrieving revision 1.73
diff -u -3 -p -r1.73 sol2.h
--- config/sparc/sol2.h 14 Jun 2005 13:07:42 -0000 1.73
+++ config/sparc/sol2.h 21 Jun 2005 13:35:46 -0000
@@ -83,7 +83,7 @@ Boston, MA 02111-1307, 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"); \
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1408
diff -u -3 -p -r1.1408 decl.c
--- cp/decl.c 15 Jun 2005 08:17:56 -0000 1.1408
+++ cp/decl.c 21 Jun 2005 13:35:50 -0000
@@ -3749,7 +3749,7 @@ start_decl (const cp_declarator *declara
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, tr
{
/* 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, tr
{
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. */