Richard Biener wrote:
But that means we have multiple varpool nodes for the same decl.
Can you varpool->debug () them?
It is all my fault ...
Well, it turned out that offload_handle_link_vars is simply called
multiple times. In the source code (lto/lto.cc) it is in:
do_whole_program_analysis (void)
{
...
/* Find out statics that need to be promoted
to globals with hidden visibility because they are accessed from multiple
partitions. */
lto_promote_cross_file_statics ();
offload_handle_link_vars ();
And in lto_main it is called once unconditionally and then in
the 'if' branch via above function while calling it directly
in the 'else' branch:
lto_main (void)
{
...
if (!seen_error ())
{
offload_handle_link_vars ();
/* If WPA is enabled analyze the whole call graph and create an
optimization plan. Otherwise, read in all the function
bodies and continue with optimization. */
if (flag_wpa)
do_whole_program_analysis ();
else
{
timevar_start (TV_PHASE_OPT_GEN);
materialize_cgraph ();
if (!flag_ltrans)
{
lto_promote_statics_nonwpa ();
offload_handle_link_vars ();
}
* * *
For good reasons, I added the call after the first bits of
do_whole_program_analysis
and in the else branch - which happened in commit
r12-7776-g1002a7ace111d7
LTO: Fixes for renaming issues with offload/OpenMP [PR104285]
That commit handled same-named static variables in multiple translation
units - where the original variable was mangled to avoid naming collisions.
But seemingly I missed to remove the original call to offload_handle_link_vars
and as it didn't break and just wasted resources (walk + build_decl) ...
In any case, I do not see any good reason for keeping the old call that is
first in the file.
* * *
This gives the following patch ...
Tobias
gcc/lto/lto.cc | 35 ++++++++++++++++++++---------------
1 file changed, 20 insertions(+), 15 deletions(-)
diff --git a/gcc/lto/lto.cc b/gcc/lto/lto.cc
index d22827bbcc0..cf470c73195 100644
--- a/gcc/lto/lto.cc
+++ b/gcc/lto/lto.cc
@@ -482,27 +482,32 @@ static void
offload_handle_link_vars (void)
{
#ifdef ACCEL_COMPILER
+ size_t i;
varpool_node *var;
+ auto_vec <varpool_node *>temp_link_vars;
FOR_EACH_VARIABLE (var)
if (lookup_attribute ("omp declare target link",
DECL_ATTRIBUTES (var->decl)))
- {
- if (DECL_HAS_VALUE_EXPR_P (var->decl))
- continue;
- tree type = build_pointer_type (TREE_TYPE (var->decl));
- tree link_ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
+ temp_link_vars.safe_push (var);
+ FOR_EACH_VEC_ELT (temp_link_vars, i, var)
+ {
+ /* For some reasons, the same varpool node can appear multiple times. */
+ if (DECL_HAS_VALUE_EXPR_P (var->decl))
+ continue;
+ tree type = build_pointer_type (TREE_TYPE (var->decl));
+ tree link_ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
clone_function_name (var->decl,
"linkptr"), type);
- TREE_USED (link_ptr_var) = 1;
- TREE_STATIC (link_ptr_var) = 1;
- TREE_PUBLIC (link_ptr_var) = TREE_PUBLIC (var->decl);
- DECL_ARTIFICIAL (link_ptr_var) = 1;
- SET_DECL_ASSEMBLER_NAME (link_ptr_var, DECL_NAME (link_ptr_var));
- SET_DECL_VALUE_EXPR (var->decl, build_simple_mem_ref (link_ptr_var));
- DECL_HAS_VALUE_EXPR_P (var->decl) = 1;
- varpool_node::finalize_decl (link_ptr_var);
- varpool_node::get (link_ptr_var)->force_output = var->force_output;
- }
+ TREE_USED (link_ptr_var) = 1;
+ TREE_STATIC (link_ptr_var) = 1;
+ TREE_PUBLIC (link_ptr_var) = TREE_PUBLIC (var->decl);
+ DECL_ARTIFICIAL (link_ptr_var) = 1;
+ SET_DECL_ASSEMBLER_NAME (link_ptr_var, DECL_NAME (link_ptr_var));
+ SET_DECL_VALUE_EXPR (var->decl, build_simple_mem_ref (link_ptr_var));
+ DECL_HAS_VALUE_EXPR_P (var->decl) = 1;
+ varpool_node::finalize_decl (link_ptr_var);
+ varpool_node::get (link_ptr_var)->force_output = var->force_output;
+ }
#endif
}