Tobias Burnus wrote:
Richard Biener wrote:

But that means we have multiple varpool nodes for the same decl.
Can you varpool->debug () them?

[...]  Well, it turned out that offload_handle_link_vars is simply called
multiple times. In the source code (lto/lto.cc) it is in:

Any final comments about this? - Needing time to ponder about it?

Or should I just keep claiming that it is OpenMP maintaining stuff,
given that

  offload_handle_link_vars ()

is only doing something on (OpenMP) offload-side compiler and then
also only when the 'omp declare target link' attr is set?

Tobias

Namely:


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