On February 5, 2018 3:49:25 PM GMT+01:00, Jan Hubicka <hubi...@ucw.cz> wrote:
>Hi,
>in the testcase of PR81004 we produce wrong code (reference to
>optimized out
>comdat symbol) due to strange sequence of events that is initiated by
>fact
>that after streaming in a comdat group we sed one of resolution infos
>to
>LDPR_UNKNOWN.
>
>This is because of tree merging with earlier unit that streams the
>symbol for
>debug info but does not use it and thus there is no symtab entry.
>
>Currently resolutions are streamed in a funny way - they are indexed by
>decls
>and passed through plugin to be read back as array and later attached
>into hash
>to tree nodes to be later written into symtab node (where they belong).
>This is quite crazy design but I do not see how to easy clean it up, so
>this
>fixes the problem and I will add cleanup to my todo for next stage1.
>
>patch also adds sanity checking so we error out on missing relocation
>info.
>I have checked this works with non-plugin path.
>I did not add testcase because it is very fragile (depends on what we
>stream)
>and it already does not reproduce on mainline without Jakub's patch to
>clear
>abstract origins in free_lang_data reverted.
>
>Bootstrapped/regtested x86_64-linux, ltobootstrap in progress (passing
>stage2)
>OK?

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

Otherwise OK. 

Thanks, 
Richard. 

>Honza
>       PR lto/81004
>       * lto.c (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.
>       * symtab.c (symtab_node::verify_base): Verify that externaly visible
>       symbol has PUBLIC decl.
>Index: lto/lto.c
>===================================================================
>--- lto/lto.c  (revision 257382)
>+++ lto/lto.c  (working copy)
>@@ -830,12 +830,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 +886,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 +1637,11 @@ 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);
>+          {
>+            if (!flag_ltrans)
>+              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,8 @@ unify_scc (struct data_in *data_in, unsi
>               {
>                 map2[i*2] = (tree)(uintptr_t)(from + i);
>                 map2[i*2+1] = scc->entries[i];
>+                if (!flag_ltrans)
>+                  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 +1787,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 +2893,19 @@ 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)
>+      {
>+      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)
>       {
>Index: symtab.c
>===================================================================
>--- symtab.c   (revision 257382)
>+++ symtab.c   (working copy)
>@@ -1056,6 +1056,11 @@ symtab_node::verify_base (void)
>       error ("node has body_removed but is definition");
>       error_found = true;
>     }
>+  if (externally_visible && !TREE_PUBLIC (decl))
>+    {
>+      error ("node is externally visible but decl has no PUBLIC
>flag");
>+      error_found = true;
>+    }
>   if (analyzed && !definition)
>     {
>       error ("node is analyzed but it is not a definition");

Reply via email to