On February 6, 2018 2:29:42 PM GMT+01:00, Jan Hubicka <[email protected]> wrote:
>>
>> 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.
After some soaking, yes.
>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)
> {