re PR lto/81004 (linking failed with -flto and static libboost_program_options)
authorJan Hubicka <hubicka@ucw.cz>
Tue, 6 Feb 2018 13:27:04 +0000 (14:27 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 6 Feb 2018 13:27:04 +0000 (13:27 +0000)
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.

From-SVN: r257412

gcc/lto/ChangeLog
gcc/lto/lto.c

index e51fa1c..4862ea9 100644 (file)
@@ -1,3 +1,15 @@
+2018-01-30  Jan Hubicka  <hubicka@ucw.cz>
+
+       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.
+
 2018-02-02  Eric Botcazou  <ebotcazou@adacore.com>
 
        PR lto/83954
index a8707d4..0ac8b1e 100644 (file)
@@ -54,6 +54,7 @@ along with GCC; see the file COPYING3.  If not see
 #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 (struct data_in *data_in, tree decl,
                         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, unsigned from,
          /* 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, unsigned from,
                {
                  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_data *decl_data, const void *data,
                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, const char **fnames)
 
   /* 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)
       {