> 
> I think unify_scc is only ever called from WPA so you can elide the 
> flag_ltrans checks. 
> 
> Otherwise OK. 

Thanks, I have updated this and also dropped the sanity check from symtab.c
because, well, it finds another bugs in target versioning I will handle
incrementally.  I also noticed I need to rule out the check for register
variables and builtins because we do not stream those into the lto symtab.  I
would say that real_symbol_p should return false for register variable and we
should stream bulitins but that is for independent change, too.

I suppose we should backport this to all release branches.

Honza

        PR lto/81004
        * lto.c: Include builtins.h
        (register_resolution): Merge resolutions in case trees was
        merged across units.
        (lto_maybe_register_decl): Break out from ...
        (lto_read_decls): ... here.
        (unify_scc): Also register decls here.
        (read_cgraph_and_symbols): Sanity check that all resolutions was
        read.
Index: lto.c
===================================================================
--- lto.c       (revision 257382)
+++ lto.c       (working copy)
@@ -54,6 +54,7 @@ along with GCC; see the file COPYING3.
 #include "stringpool.h"
 #include "fold-const.h"
 #include "attribs.h"
+#include "builtins.h"
 
 
 /* Number of parallel tasks to run, -1 if we want to use GNU Make jobserver.  
*/
@@ -830,12 +831,20 @@ static void
 register_resolution (struct lto_file_decl_data *file_data, tree decl,
                     enum ld_plugin_symbol_resolution resolution)
 {
+  bool existed;
   if (resolution == LDPR_UNKNOWN)
     return;
   if (!file_data->resolution_map)
     file_data->resolution_map
       = new hash_map<tree, ld_plugin_symbol_resolution>;
-  file_data->resolution_map->put (decl, resolution);
+  ld_plugin_symbol_resolution_t &res
+     = file_data->resolution_map->get_or_insert (decl, &existed);
+  gcc_assert (!existed || res == resolution);
+  if (!existed
+      || resolution == LDPR_PREVAILING_DEF_IRONLY
+      || resolution == LDPR_PREVAILING_DEF
+      || resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
+    res = resolution;
 }
 
 /* Register DECL with the global symbol table and change its
@@ -878,6 +887,18 @@ lto_register_function_decl_in_symtab (st
                         decl, get_resolution (data_in, ix));
 }
 
+/* Check if T is a decl and needs register its resolution info.  */
+
+static void
+lto_maybe_register_decl (struct data_in *data_in, tree t, unsigned ix)
+{
+  if (TREE_CODE (t) == VAR_DECL)
+    lto_register_var_decl_in_symtab (data_in, t, ix);
+  else if (TREE_CODE (t) == FUNCTION_DECL
+          && !DECL_BUILT_IN (t))
+    lto_register_function_decl_in_symtab (data_in, t, ix);
+}
+
 
 /* For the type T re-materialize it in the type variant list and
    the pointer/reference-to chains.  */
@@ -1617,7 +1638,10 @@ unify_scc (struct data_in *data_in, unsi
          /* Fixup the streamer cache with the prevailing nodes according
             to the tree node mapping computed by compare_tree_sccs.  */
          if (len == 1)
-           streamer_tree_cache_replace_tree (cache, pscc->entries[0], from);
+           {
+             lto_maybe_register_decl (data_in, pscc->entries[0], from);
+             streamer_tree_cache_replace_tree (cache, pscc->entries[0], from);
+           }
          else
            {
              tree *map2 = XALLOCAVEC (tree, 2 * len);
@@ -1625,6 +1649,7 @@ unify_scc (struct data_in *data_in, unsi
                {
                  map2[i*2] = (tree)(uintptr_t)(from + i);
                  map2[i*2+1] = scc->entries[i];
+                 lto_maybe_register_decl (data_in, scc->entries[i], from + i);
                }
              qsort (map2, len, 2 * sizeof (tree), cmp_tree);
              qsort (map, len, 2 * sizeof (tree), cmp_tree);
@@ -1761,13 +1786,7 @@ lto_read_decls (struct lto_file_decl_dat
                cache_integer_cst (t);
              if (!flag_ltrans)
                {
-                 /* Register variables and functions with the
-                    symbol table.  */
-                 if (TREE_CODE (t) == VAR_DECL)
-                   lto_register_var_decl_in_symtab (data_in, t, from + i);
-                 else if (TREE_CODE (t) == FUNCTION_DECL
-                          && !DECL_BUILT_IN (t))
-                   lto_register_function_decl_in_symtab (data_in, t, from + i);
+                 lto_maybe_register_decl (data_in, t, from + i);
                  /* Scan the tree for references to global functions or
                     variables and record those for later fixup.  */
                  if (mentions_vars_p (t))
@@ -2873,13 +2892,21 @@ read_cgraph_and_symbols (unsigned nfiles
 
   /* Store resolutions into the symbol table.  */
 
-  ld_plugin_symbol_resolution_t *res;
   FOR_EACH_SYMBOL (snode)
-    if (snode->real_symbol_p ()
-       && snode->lto_file_data
-       && snode->lto_file_data->resolution_map
-       && (res = snode->lto_file_data->resolution_map->get (snode->decl)))
-      snode->resolution = *res;
+    if (snode->externally_visible && snode->real_symbol_p ()
+       && snode->lto_file_data && snode->lto_file_data->resolution_map
+       && !is_builtin_fn (snode->decl)
+       && !(VAR_P (snode->decl) && DECL_HARD_REGISTER (snode->decl)))
+      {
+       ld_plugin_symbol_resolution_t *res;
+
+       res = snode->lto_file_data->resolution_map->get (snode->decl);
+       if (!res || *res == LDPR_UNKNOWN)
+         fatal_error (input_location, "missing resolution data for %s",
+                      IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (snode->decl)));
+       else
+          snode->resolution = *res;
+      }
   for (i = 0; all_file_decl_data[i]; i++)
     if (all_file_decl_data[i]->resolution_map)
       {

Reply via email to