Hello, this patch continues on my work to move symbol related things into symbol table rather than having them in decl_with_vis. This time I move TLS_MODEl, that is relatively easy thing to do. I again followed same scheme as with sections and comdat groups.
I tried to do this at once with DECL_VISBILITY but learnt the hard way that DECL_VISBILITY matters for TYPE_DECLs, too, in C++ FE. Jason, this is not the only case where I run into. In fact I would like to get DECL_SAVED_TREE, DECL_ARGUMENTS, DECL_RESULT and DECL_VINDEX out of tree_decl_non_common that is shared by functions, variables, namespaces, type decls and frontend's decls, such as templates. What would be preferred way of getting these out of the tree.h into C++ specific representation? Honza Bootstrapped/regtested x86_64-linux, comitted. * c-family/c-common.c (handle_tls_model_attribute): Use set_decl_tls_model. * cgraph.h (struct varpool_node): Add tls_model. * tree.c (decl_tls_model, set_decl_tls_model): New functions. * tree.h (DECL_TLS_MODEL): Update. (DECL_THREAD_LOCAL_P): Check that variable is static. (decl_tls_model): Declare. (set_decl_tls_model): Declare. * tree-emutls.c (get_emutls_init_templ_addr): First build decl and then set symbol prorperties. (get_emutls_init_templ_addr): Cleanup. (new_emutls_decl): Update. * lto-cgraph.c (lto_output_varpool_node): Stream TLS model (lto_input_varpool_node): Likewise. * lto-streamer-out.c (hash_tree): Likewise. * tree-streamer-in.c (unpack_ts_decl_with_vis_value_fields): Do not stream DECL_TLS_MODEL. * tree-profile.c (init_ic_make_global_vars): Use set_decl_tls_model. * tree-core.h (tree_decl_with_vis): Remove tls_model; update comments. * c-parser.c (c_parser_omp_threadprivate): Likewise. * c-decl.c (merge_decls): Likewise. * decl.c (duplicate_decls): Use set_decl_tls_model. (grokdeclarator): Likewise. * semantics.c (finish_id_expression): Check TLS only for static variables. (finish_omp_threadprivate): Use decl_default_tls_model. * decl2.c (get_guard): Likewise. * call.c (make_temporary_var_for_ref_to_temp): Likewise. * gcc-interface/utils.c (process_attributes): Use set_decl_tls_model. * trans-common.c (build_common_decl): Use set_decl_tls_model. * trans-decl.c (gfc_finish_var_decl): Likewise. (get_proc_pointer_decl): Likewise. * lto.c (compare_tree_sccs_1): Do not compare DECL_TLS_MODEL. Index: c-family/c-common.c =================================================================== --- c-family/c-common.c (revision 211688) +++ c-family/c-common.c (working copy) @@ -8036,7 +8036,7 @@ handle_tls_model_attribute (tree *node, else error ("tls_model argument must be one of \"local-exec\", \"initial-exec\", \"local-dynamic\" or \"global-dynamic\""); - DECL_TLS_MODEL (decl) = kind; + set_decl_tls_model (decl, kind); return NULL_TREE; } Index: c/c-parser.c =================================================================== --- c/c-parser.c (revision 211688) +++ c/c-parser.c (working copy) @@ -13557,7 +13557,7 @@ c_parser_omp_threadprivate (c_parser *pa { if (! DECL_THREAD_LOCAL_P (v)) { - DECL_TLS_MODEL (v) = decl_default_tls_model (v); + set_decl_tls_model (v, decl_default_tls_model (v)); /* If rtl has been already set for this var, call make_decl_rtl once again, so that encode_section_info has a chance to look at the new decl flags. */ Index: c/c-decl.c =================================================================== --- c/c-decl.c (revision 211688) +++ c/c-decl.c (working copy) @@ -2294,7 +2294,7 @@ merge_decls (tree newdecl, tree olddecl, /* Merge the threadprivate attribute. */ if (TREE_CODE (olddecl) == VAR_DECL && C_DECL_THREADPRIVATE_P (olddecl)) { - DECL_TLS_MODEL (newdecl) = DECL_TLS_MODEL (olddecl); + set_decl_tls_model (newdecl, DECL_TLS_MODEL (olddecl)); C_DECL_THREADPRIVATE_P (newdecl) = 1; } @@ -6345,7 +6345,7 @@ grokdeclarator (const struct c_declarato } if (threadp) - DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); + set_decl_tls_model (decl, decl_default_tls_model (decl)); } if ((storage_class == csc_extern Index: cgraph.h =================================================================== --- cgraph.h (revision 211688) +++ cgraph.h (working copy) @@ -708,6 +708,8 @@ public: /* Set if the variable is dynamically initialized, except for function local statics. */ unsigned dynamically_initialized : 1; + + ENUM_BITFIELD(tls_model) tls_model : 3; }; /* Every top level asm statement is put into a asm_node. */ Index: tree.c =================================================================== --- tree.c (revision 211688) +++ tree.c (working copy) @@ -657,6 +657,33 @@ set_decl_section_name (tree node, const snode->set_section (value); } +/* Return TLS model of a variable NODE. */ +enum tls_model +decl_tls_model (const_tree node) +{ + struct varpool_node *snode = varpool_get_node (node); + if (!snode) + return TLS_MODEL_NONE; + return snode->tls_model; +} + +/* Set TLS model of variable NODE to MODEL. */ +void +set_decl_tls_model (tree node, enum tls_model model) +{ + struct varpool_node *vnode; + + if (model == TLS_MODEL_NONE) + { + vnode = varpool_get_node (node); + if (!vnode) + return; + } + else + vnode = varpool_node_for_decl (node); + vnode->tls_model = model; +} + /* Compute the number of bytes occupied by a tree with code CODE. This function cannot be used for nodes that have variable sizes, including TREE_VEC, INTEGER_CST, STRING_CST, and CALL_EXPR. */ Index: tree.h =================================================================== --- tree.h (revision 211688) +++ tree.h (working copy) @@ -2386,12 +2386,12 @@ extern void decl_value_expr_insert (tree /* 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_with_vis.tls_model) +#define DECL_TLS_MODEL(NODE) decl_tls_model (NODE) /* In a VAR_DECL, nonzero if the data should be allocated from thread-local storage. */ #define DECL_THREAD_LOCAL_P(NODE) \ - (VAR_DECL_CHECK (NODE)->decl_with_vis.tls_model >= TLS_MODEL_REAL) + ((TREE_STATIC (NODE) || DECL_EXTERNAL (NODE)) && decl_tls_model (NODE) >= TLS_MODEL_REAL) /* In a non-local VAR_DECL with static storage duration, true if the variable has an initialization priority. If false, the variable @@ -3429,6 +3429,8 @@ extern tree decl_comdat_group (const_tre extern tree decl_comdat_group_id (const_tree); extern const char *decl_section_name (const_tree); extern void set_decl_section_name (tree, const char *); +extern enum tls_model decl_tls_model (const_tree); +extern void set_decl_tls_model (tree, enum tls_model); /* Compute the number of bytes occupied by 'node'. This routine only looks at TREE_CODE and, if the code is TREE_VEC, TREE_VEC_LENGTH. */ Index: tree-emutls.c =================================================================== --- tree-emutls.c (revision 211688) +++ tree-emutls.c (working copy) @@ -250,10 +250,10 @@ get_emutls_init_templ_addr (tree decl) DECL_WEAK (to) = DECL_WEAK (decl); if (DECL_ONE_ONLY (decl)) { - make_decl_one_only (to, DECL_ASSEMBLER_NAME (to)); TREE_STATIC (to) = TREE_STATIC (decl); TREE_PUBLIC (to) = TREE_PUBLIC (decl); DECL_VISIBILITY (to) = DECL_VISIBILITY (decl); + make_decl_one_only (to, DECL_ASSEMBLER_NAME (to)); } else TREE_STATIC (to) = 1; @@ -263,9 +263,7 @@ get_emutls_init_templ_addr (tree decl) DECL_INITIAL (decl) = NULL; if (targetm.emutls.tmpl_section) - { - set_decl_section_name (to, targetm.emutls.tmpl_section); - } + set_decl_section_name (to, targetm.emutls.tmpl_section); else set_decl_section_name (to, DECL_SECTION_NAME (decl)); @@ -292,7 +290,6 @@ new_emutls_decl (tree decl, tree alias_o SET_DECL_ASSEMBLER_NAME (to, DECL_NAME (to)); - DECL_TLS_MODEL (to) = TLS_MODEL_EMULATED; DECL_ARTIFICIAL (to) = 1; DECL_IGNORED_P (to) = 1; TREE_READONLY (to) = 0; @@ -314,6 +311,8 @@ new_emutls_decl (tree decl, tree alias_o if (DECL_ONE_ONLY (decl)) make_decl_one_only (to, DECL_ASSEMBLER_NAME (to)); + set_decl_tls_model (to, TLS_MODEL_EMULATED); + /* If we're not allowed to change the proxy object's alignment, pretend it has been set by the user. */ if (targetm.emutls.var_align_fixed) Index: cp/decl.c =================================================================== --- cp/decl.c (revision 211688) +++ cp/decl.c (working copy) @@ -1952,7 +1952,7 @@ duplicate_decls (tree newdecl, tree oldd if (!DECL_LANG_SPECIFIC (newdecl)) retrofit_lang_decl (newdecl); - DECL_TLS_MODEL (newdecl) = DECL_TLS_MODEL (olddecl); + set_decl_tls_model (newdecl, DECL_TLS_MODEL (olddecl)); CP_DECL_THREADPRIVATE_P (newdecl) = 1; } } @@ -8016,7 +8016,7 @@ grokvardecl (tree type, if (decl_spec_seq_has_spec_p (declspecs, ds_thread)) { - DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); + set_decl_tls_model (decl, decl_default_tls_model (decl)); if (declspecs->gnu_thread_keyword_p) DECL_GNU_TLS_P (decl) = true; } @@ -10699,7 +10699,7 @@ grokdeclarator (const cp_declarator *dec if (thread_p) { - DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); + set_decl_tls_model (decl, decl_default_tls_model (decl)); if (declspecs->gnu_thread_keyword_p) DECL_GNU_TLS_P (decl) = true; } Index: cp/semantics.c =================================================================== --- cp/semantics.c (revision 211688) +++ cp/semantics.c (working copy) @@ -3493,6 +3493,7 @@ finish_id_expression (tree id_expression tree wrap; if (VAR_P (decl) && !cp_unevaluated_operand + && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)) && DECL_THREAD_LOCAL_P (decl) && (wrap = get_tls_wrapper_fn (decl))) { @@ -5956,7 +5957,7 @@ finish_omp_threadprivate (tree vars) if (! DECL_THREAD_LOCAL_P (v)) { - DECL_TLS_MODEL (v) = decl_default_tls_model (v); + set_decl_tls_model (v, decl_default_tls_model (v)); /* If rtl has been already set for this var, call make_decl_rtl once again, so that encode_section_info has a chance to look at the new decl flags. */ Index: cp/decl2.c =================================================================== --- cp/decl2.c (revision 211688) +++ cp/decl2.c (working copy) @@ -2939,7 +2939,7 @@ get_guard (tree decl) TREE_STATIC (guard) = TREE_STATIC (decl); DECL_COMMON (guard) = DECL_COMMON (decl); DECL_COMDAT (guard) = DECL_COMDAT (decl); - DECL_TLS_MODEL (guard) = DECL_TLS_MODEL (decl); + set_decl_tls_model (guard, DECL_TLS_MODEL (decl)); if (DECL_ONE_ONLY (decl)) make_decl_one_only (guard, cxx_comdat_group (guard)); if (TREE_PUBLIC (decl)) @@ -4212,7 +4212,7 @@ handle_tls_init (void) DECL_ARTIFICIAL (guard) = true; DECL_IGNORED_P (guard) = true; TREE_USED (guard) = true; - DECL_TLS_MODEL (guard) = decl_default_tls_model (guard); + set_decl_tls_model (guard, decl_default_tls_model (guard)); pushdecl_top_level_and_finish (guard, NULL_TREE); tree fn = get_local_tls_init_fn (); Index: cp/call.c =================================================================== --- cp/call.c (revision 211688) +++ cp/call.c (working copy) @@ -9387,7 +9387,7 @@ make_temporary_var_for_ref_to_temp (tree tree name; TREE_STATIC (var) = TREE_STATIC (decl); - DECL_TLS_MODEL (var) = DECL_TLS_MODEL (decl); + set_decl_tls_model (var, DECL_TLS_MODEL (decl)); name = mangle_ref_init_variable (decl); DECL_NAME (var) = name; SET_DECL_ASSEMBLER_NAME (var, name); Index: lto-cgraph.c =================================================================== --- lto-cgraph.c (revision 211688) +++ lto-cgraph.c (working copy) @@ -609,6 +609,7 @@ lto_output_varpool_node (struct lto_simp && boundary_p && !DECL_EXTERNAL (node->decl), 1); /* in_other_partition. */ } + bp_pack_value (&bp, node->tls_model, 3); streamer_write_bitpack (&bp); group = node->get_comdat_group (); @@ -1265,6 +1266,7 @@ input_varpool_node (struct lto_file_decl } if (node->alias && !node->analyzed && node->weakref) node->alias_target = get_alias_symbol (node->decl); + node->tls_model = (enum tls_model)bp_unpack_value (&bp, 3); group = read_identifier (ib); if (group) { Index: lto-streamer-out.c =================================================================== --- lto-streamer-out.c (revision 211688) +++ lto-streamer-out.c (working copy) @@ -821,7 +821,6 @@ hash_tree (struct streamer_tree_cache_d v = iterative_hash_host_wide_int (DECL_HARD_REGISTER (t) | (DECL_IN_CONSTANT_POOL (t) << 1), v); - v = iterative_hash_host_wide_int (DECL_TLS_MODEL (t), v); } if (TREE_CODE (t) == FUNCTION_DECL) v = iterative_hash_host_wide_int (DECL_FINAL_P (t) Index: ada/gcc-interface/utils.c =================================================================== --- ada/gcc-interface/utils.c (revision 211688) +++ ada/gcc-interface/utils.c (working copy) @@ -2495,7 +2495,7 @@ process_attributes (tree *node, struct a break; case ATTR_THREAD_LOCAL_STORAGE: - DECL_TLS_MODEL (*node) = decl_default_tls_model (*node); + set_decl_tls_model (*node, decl_default_tls_model (*node)); DECL_COMMON (*node) = 0; break; } Index: fortran/trans-common.c =================================================================== --- fortran/trans-common.c (revision 211688) +++ fortran/trans-common.c (working copy) @@ -454,7 +454,7 @@ build_common_decl (gfc_common_head *com, gfc_set_decl_location (decl, &com->where); if (com->threadprivate) - DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); + set_decl_tls_model (decl, decl_default_tls_model (decl)); /* Place the back end declaration for this common block in GLOBAL_BINDING_LEVEL. */ Index: fortran/trans-decl.c =================================================================== --- fortran/trans-decl.c (revision 211688) +++ fortran/trans-decl.c (working copy) @@ -631,7 +631,7 @@ gfc_finish_var_decl (tree decl, gfc_symb /* Handle threadprivate variables. */ if (sym->attr.threadprivate && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) - DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); + set_decl_tls_model (decl, decl_default_tls_model (decl)); gfc_finish_decl_attrs (decl, &sym->attr); } @@ -1645,7 +1645,7 @@ get_proc_pointer_decl (gfc_symbol *sym) /* Handle threadprivate procedure pointers. */ if (sym->attr.threadprivate && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) - DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); + set_decl_tls_model (decl, decl_default_tls_model (decl)); attributes = add_attributes_to_decl (sym->attr, NULL_TREE); decl_attributes (&decl, attributes, 0); Index: lto/lto.c =================================================================== --- lto/lto.c (revision 211688) +++ lto/lto.c (working copy) @@ -1299,7 +1299,6 @@ compare_tree_sccs_1 (tree t1, tree t2, t compare_values (DECL_HARD_REGISTER); /* DECL_IN_TEXT_SECTION is set during final asm output only. */ compare_values (DECL_IN_CONSTANT_POOL); - compare_values (DECL_TLS_MODEL); } if (VAR_OR_FUNCTION_DECL_P (t1)) compare_values (DECL_INIT_PRIORITY); Index: tree-streamer-out.c =================================================================== --- tree-streamer-out.c (revision 211688) +++ tree-streamer-out.c (working copy) @@ -248,7 +248,6 @@ pack_ts_decl_with_vis_value_fields (stru bp_pack_value (bp, DECL_HARD_REGISTER (expr), 1); /* DECL_IN_TEXT_SECTION is set during final asm output only. */ bp_pack_value (bp, DECL_IN_CONSTANT_POOL (expr), 1); - bp_pack_value (bp, DECL_TLS_MODEL (expr), 3); } if (TREE_CODE (expr) == FUNCTION_DECL) Index: tree-streamer-in.c =================================================================== --- tree-streamer-in.c (revision 211688) +++ tree-streamer-in.c (working copy) @@ -280,7 +280,6 @@ unpack_ts_decl_with_vis_value_fields (st { DECL_HARD_REGISTER (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_IN_CONSTANT_POOL (expr) = (unsigned) bp_unpack_value (bp, 1); - DECL_TLS_MODEL (expr) = (enum tls_model) bp_unpack_value (bp, 3); } if (TREE_CODE (expr) == FUNCTION_DECL) Index: tree-profile.c =================================================================== --- tree-profile.c (revision 211688) +++ tree-profile.c (working copy) @@ -110,8 +110,7 @@ init_ic_make_global_vars (void) DECL_ARTIFICIAL (ic_void_ptr_var) = 1; DECL_INITIAL (ic_void_ptr_var) = NULL; if (targetm.have_tls) - DECL_TLS_MODEL (ic_void_ptr_var) = - decl_default_tls_model (ic_void_ptr_var); + set_decl_tls_model (ic_void_ptr_var, decl_default_tls_model (ic_void_ptr_var)); varpool_finalize_decl (ic_void_ptr_var); @@ -141,8 +140,7 @@ init_ic_make_global_vars (void) DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1; DECL_INITIAL (ic_gcov_type_ptr_var) = NULL; if (targetm.have_tls) - DECL_TLS_MODEL (ic_gcov_type_ptr_var) = - decl_default_tls_model (ic_gcov_type_ptr_var); + set_decl_tls_model (ic_gcov_type_ptr_var, decl_default_tls_model (ic_gcov_type_ptr_var)); varpool_finalize_decl (ic_gcov_type_ptr_var); } Index: tree-core.h =================================================================== --- tree-core.h (revision 211688) +++ tree-core.h (working copy) @@ -1455,10 +1455,9 @@ struct GTY(()) tree_decl_with_vis { unsigned seen_in_bind_expr : 1; unsigned comdat_flag : 1; + /* Used for FUNCTION_DECL, VAR_DECL and in C++ for TYPE_DECL. */ ENUM_BITFIELD(symbol_visibility) visibility : 2; unsigned visibility_specified : 1; - /* Belongs to VAR_DECL exclusively. */ - ENUM_BITFIELD(tls_model) tls_model : 3; /* Belong to FUNCTION_DECL exclusively. */ unsigned init_priority_p : 1; @@ -1470,7 +1469,7 @@ struct GTY(()) tree_decl_with_vis { unsigned cxx_destructor : 1; /* Belong to FUNCTION_DECL exclusively. */ unsigned final : 1; - /* 12 unused bits. */ + /* 15 unused bits. */ }; struct GTY(()) tree_var_decl {