diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-08-05 20:52:03 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-08-05 20:52:03 +0000 |
commit | 478e80e0ce2ae7ed02283aa6336151befb77bc14 (patch) | |
tree | 02153d0b45e4c8f7e24b2a64ad2e65578c699730 /gcc/tree-emutls.c | |
parent | 67baa302b86dcf75345e547e8ce14b04b8ad4a67 (diff) | |
download | gcc-478e80e0ce2ae7ed02283aa6336151befb77bc14.tar.gz |
PR middle-end/49500
* tree-emultls.c (new_emutls_decl):Add alias_of parameter;
handle aliases.
(create_emultls_var):New function.
(ipa_lower_emutls): Handle aliases correctly.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@177483 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-emutls.c')
-rw-r--r-- | gcc/tree-emutls.c | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c index e1a1c1d56cc..c8203f05752 100644 --- a/gcc/tree-emutls.c +++ b/gcc/tree-emutls.c @@ -269,7 +269,7 @@ get_emutls_init_templ_addr (tree decl) /* Create and return the control variable for the TLS variable DECL. */ static tree -new_emutls_decl (tree decl) +new_emutls_decl (tree decl, tree alias_of) { tree name, to; @@ -333,8 +333,12 @@ new_emutls_decl (tree decl) not external one. */ if (DECL_EXTERNAL (to)) varpool_node (to); - else + else if (!alias_of) varpool_finalize_decl (to); + else + varpool_create_variable_alias (to, + varpool_node_for_asm + (DECL_ASSEMBLER_NAME (alias_of))->decl); return to; } @@ -688,6 +692,40 @@ lower_emutls_function_body (struct cgraph_node *node) current_function_decl = NULL; } +/* Create emutls variable for VAR, DATA is pointer to static + ctor body we can add constructors to. + Callback for varpool_for_variable_and_aliases. */ + +static bool +create_emultls_var (struct varpool_node *var, void *data) +{ + tree cdecl; + struct varpool_node *cvar; + + cdecl = new_emutls_decl (var->decl, var->alias_of); + + cvar = varpool_get_node (cdecl); + VEC_quick_push (varpool_node_ptr, control_vars, cvar); + + if (!var->alias) + { + /* Make sure the COMMON block control variable gets initialized. + Note that there's no point in doing this for aliases; we only + need to do this once for the main variable. */ + emutls_common_1 (var->decl, cdecl, (tree *)data); + } + if (var->alias && !var->alias_of) + cvar->alias = true; + + /* Indicate that the value of the TLS variable may be found elsewhere, + preventing the variable from re-appearing in the GIMPLE. We cheat + and use the control variable here (rather than a full call_expr), + which is special-cased inside the DWARF2 output routines. */ + SET_DECL_VALUE_EXPR (var->decl, cdecl); + DECL_HAS_VALUE_EXPR_P (var->decl) = 1; + return false; +} + /* Main entry point to the tls lowering pass. */ static unsigned int @@ -708,6 +746,8 @@ ipa_lower_emutls (void) gcc_checking_assert (TREE_STATIC (var->decl) || DECL_EXTERNAL (var->decl)); varpool_node_set_add (tls_vars, var); + if (var->alias && var->analyzed) + varpool_node_set_add (tls_vars, varpool_variable_node (var, NULL)); } /* If we found no TLS variables, then there is no further work to do. */ @@ -728,34 +768,12 @@ ipa_lower_emutls (void) /* Create the control variables for each TLS variable. */ FOR_EACH_VEC_ELT (varpool_node_ptr, tls_vars->nodes, i, var) { - tree cdecl; - struct varpool_node *cvar; - var = VEC_index (varpool_node_ptr, tls_vars->nodes, i); - cdecl = new_emutls_decl (var->decl); - - cvar = varpool_get_node (cdecl); - VEC_quick_push (varpool_node_ptr, control_vars, cvar); - - if (var->alias) - { - any_aliases = true; - cvar->alias = true; - } - else - { - /* Make sure the COMMON block control variable gets initialized. - Note that there's no point in doing this for aliases; we only - need to do this once for the main variable. */ - emutls_common_1 (var->decl, cdecl, &ctor_body); - } - /* Indicate that the value of the TLS variable may be found elsewhere, - preventing the variable from re-appearing in the GIMPLE. We cheat - and use the control variable here (rather than a full call_expr), - which is special-cased inside the DWARF2 output routines. */ - SET_DECL_VALUE_EXPR (var->decl, cdecl); - DECL_HAS_VALUE_EXPR_P (var->decl) = 1; + if (var->alias && !var->alias_of) + any_aliases = true; + else if (!var->alias) + varpool_for_node_and_aliases (var, create_emultls_var, &ctor_body, true); } /* If there were any aliases, then frob the alias_pairs vector. */ |