re PR middle-end/49500 (gcc.dg/tls/alias-1.c)
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. From-SVN: r177483
This commit is contained in:
parent
f791d33387
commit
75d3e6e372
@ -1,3 +1,11 @@
|
|||||||
|
2011-08-05 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
2011-08-05 Jan Hubicka <jh@suse.cz>
|
2011-08-05 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
PR middle-end/49735
|
PR middle-end/49735
|
||||||
|
@ -269,7 +269,7 @@ get_emutls_init_templ_addr (tree decl)
|
|||||||
/* Create and return the control variable for the TLS variable DECL. */
|
/* Create and return the control variable for the TLS variable DECL. */
|
||||||
|
|
||||||
static tree
|
static tree
|
||||||
new_emutls_decl (tree decl)
|
new_emutls_decl (tree decl, tree alias_of)
|
||||||
{
|
{
|
||||||
tree name, to;
|
tree name, to;
|
||||||
|
|
||||||
@ -333,8 +333,12 @@ new_emutls_decl (tree decl)
|
|||||||
not external one. */
|
not external one. */
|
||||||
if (DECL_EXTERNAL (to))
|
if (DECL_EXTERNAL (to))
|
||||||
varpool_node (to);
|
varpool_node (to);
|
||||||
else
|
else if (!alias_of)
|
||||||
varpool_finalize_decl (to);
|
varpool_finalize_decl (to);
|
||||||
|
else
|
||||||
|
varpool_create_variable_alias (to,
|
||||||
|
varpool_node_for_asm
|
||||||
|
(DECL_ASSEMBLER_NAME (alias_of))->decl);
|
||||||
return to;
|
return to;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -688,6 +692,40 @@ lower_emutls_function_body (struct cgraph_node *node)
|
|||||||
current_function_decl = NULL;
|
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. */
|
/* Main entry point to the tls lowering pass. */
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
@ -708,6 +746,8 @@ ipa_lower_emutls (void)
|
|||||||
gcc_checking_assert (TREE_STATIC (var->decl)
|
gcc_checking_assert (TREE_STATIC (var->decl)
|
||||||
|| DECL_EXTERNAL (var->decl));
|
|| DECL_EXTERNAL (var->decl));
|
||||||
varpool_node_set_add (tls_vars, var);
|
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. */
|
/* 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. */
|
/* Create the control variables for each TLS variable. */
|
||||||
FOR_EACH_VEC_ELT (varpool_node_ptr, tls_vars->nodes, i, var)
|
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);
|
var = VEC_index (varpool_node_ptr, tls_vars->nodes, i);
|
||||||
cdecl = new_emutls_decl (var->decl);
|
|
||||||
|
|
||||||
cvar = varpool_get_node (cdecl);
|
if (var->alias && !var->alias_of)
|
||||||
VEC_quick_push (varpool_node_ptr, control_vars, cvar);
|
any_aliases = true;
|
||||||
|
else if (!var->alias)
|
||||||
if (var->alias)
|
varpool_for_node_and_aliases (var, create_emultls_var, &ctor_body, true);
|
||||||
{
|
|
||||||
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 there were any aliases, then frob the alias_pairs vector. */
|
/* If there were any aliases, then frob the alias_pairs vector. */
|
||||||
|
Loading…
Reference in New Issue
Block a user