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
 }
 

Reply via email to