re PR ipa/81360 (ice in estimate_edge_growth, at ipa-inline.h:86)

PR ipa/81360
	* cgraph.h (symtab_node::output_to_lto_symbol_table_p): Declare
	* symtab.c: Include builtins.h
	(symtab_node::output_to_lto_symbol_table_p): Move here
	from lto-streamer-out.c:output_symbol_p.
	* lto-streamer-out.c (write_symbol): Turn early exit to assert.
	(output_symbol_p): Move all logic to symtab.c
	(produce_symtab): Update.

	* lto.c (unify_scc): Register prevailing trees, not trees to be freed.
	(read_cgraph_and_symbols): Use
	symtab_node::output_to_lto_symbol_table_p.

From-SVN: r257490
This commit is contained in:
Jan Hubicka 2018-02-08 15:51:51 +01:00 committed by Jan Hubicka
parent 84b4c7b593
commit 39aa9b2369
7 changed files with 105 additions and 53 deletions

View File

@ -1,3 +1,14 @@
2018-02-08 Jan Hubicka <hubicka@ucw.cz>
PR ipa/81360
* cgraph.h (symtab_node::output_to_lto_symbol_table_p): Declare
* symtab.c: Include builtins.h
(symtab_node::output_to_lto_symbol_table_p): Move here
from lto-streamer-out.c:output_symbol_p.
* lto-streamer-out.c (write_symbol): Turn early exit to assert.
(output_symbol_p): Move all logic to symtab.c
(produce_symtab): Update.
2018-02-08 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* config/s390/s390-opts.h (enum indirect_branch): Define.

View File

@ -328,6 +328,9 @@ public:
or abstract function kept for debug info purposes only. */
bool real_symbol_p (void);
/* Return true when the symbol needs to be output to the LTO symbol table. */
bool output_to_lto_symbol_table_p (void);
/* Determine if symbol declaration is needed. That is, visible to something
either outside this translation unit, something magic in the system
configury. This function is used just during symbol creation. */

View File

@ -2598,13 +2598,10 @@ write_symbol (struct streamer_tree_cache_d *cache,
const char *comdat;
unsigned char c;
/* None of the following kinds of symbols are needed in the
symbol table. */
if (!TREE_PUBLIC (t)
|| is_builtin_fn (t)
|| DECL_ABSTRACT_P (t)
|| (VAR_P (t) && DECL_HARD_REGISTER (t)))
return;
gcc_checking_assert (TREE_PUBLIC (t)
&& !is_builtin_fn (t)
&& !DECL_ABSTRACT_P (t)
&& (!VAR_P (t) || !DECL_HARD_REGISTER (t)));
gcc_assert (VAR_OR_FUNCTION_DECL_P (t));
@ -2692,45 +2689,6 @@ write_symbol (struct streamer_tree_cache_d *cache,
lto_write_data (&slot_num, 4);
}
/* Return true if NODE should appear in the plugin symbol table. */
bool
output_symbol_p (symtab_node *node)
{
struct cgraph_node *cnode;
if (!node->real_symbol_p ())
return false;
/* We keep external functions in symtab for sake of inlining
and devirtualization. We do not want to see them in symbol table as
references unless they are really used. */
cnode = dyn_cast <cgraph_node *> (node);
if (cnode && (!node->definition || DECL_EXTERNAL (cnode->decl))
&& cnode->callers)
return true;
/* Ignore all references from external vars initializers - they are not really
part of the compilation unit until they are used by folding. Some symbols,
like references to external construction vtables can not be referred to at all.
We decide this at can_refer_decl_in_current_unit_p. */
if (!node->definition || DECL_EXTERNAL (node->decl))
{
int i;
struct ipa_ref *ref;
for (i = 0; node->iterate_referring (i, ref); i++)
{
if (ref->use == IPA_REF_ALIAS)
continue;
if (is_a <cgraph_node *> (ref->referring))
return true;
if (!DECL_EXTERNAL (ref->referring->decl))
return true;
}
return false;
}
return true;
}
/* Write an IL symbol table to OB.
SET and VSET are cgraph/varpool node sets we are outputting. */
@ -2755,7 +2713,7 @@ produce_symtab (struct output_block *ob)
{
symtab_node *node = lsei_node (lsei);
if (!output_symbol_p (node) || DECL_EXTERNAL (node->decl))
if (DECL_EXTERNAL (node->decl) || !node->output_to_lto_symbol_table_p ())
continue;
write_symbol (cache, node->decl, &seen, false);
}
@ -2764,7 +2722,7 @@ produce_symtab (struct output_block *ob)
{
symtab_node *node = lsei_node (lsei);
if (!output_symbol_p (node) || !DECL_EXTERNAL (node->decl))
if (!DECL_EXTERNAL (node->decl) || !node->output_to_lto_symbol_table_p ())
continue;
write_symbol (cache, node->decl, &seen, false);
}

View File

@ -1,3 +1,10 @@
2018-02-08 Jan Hubicka <hubicka@ucw.cz>
PR ipa/81360
* lto.c (unify_scc): Register prevailing trees, not trees to be freed.
(read_cgraph_and_symbols): Use
symtab_node::output_to_lto_symbol_table_p.
2018-01-30 Jan Hubicka <hubicka@ucw.cz>
* lto.c (register_resolution): Remove forgotten sanity check.

View File

@ -1648,13 +1648,16 @@ 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);
for (unsigned i = 0; i < len; ++i)
streamer_tree_cache_replace_tree (cache, map[2*i],
(uintptr_t)map2[2*i]);
{
lto_maybe_register_decl (data_in, map[2*i],
(uintptr_t)map2[2*i]);
streamer_tree_cache_replace_tree (cache, map[2*i],
(uintptr_t)map2[2*i]);
}
}
/* Free the tree nodes from the read SCC. */
@ -2901,8 +2904,12 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
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)));
{
if (snode->output_to_lto_symbol_table_p ())
fatal_error (input_location, "missing resolution data for %s",
IDENTIFIER_POINTER
(DECL_ASSEMBLER_NAME (snode->decl)));
}
else
snode->resolution = *res;
}

View File

@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "calls.h"
#include "stringpool.h"
#include "attribs.h"
#include "builtins.h"
static const char *ipa_ref_use_name[] = {"read","write","addr","alias","chkp"};
@ -2292,3 +2293,58 @@ symtab_node::binds_to_current_def_p (symtab_node *ref)
return false;
}
/* Return true if symbol should be output to the symbol table. */
bool
symtab_node::output_to_lto_symbol_table_p (void)
{
/* Only externally visible symbols matter. */
if (!TREE_PUBLIC (decl))
return false;
if (!real_symbol_p ())
return false;
/* FIXME: variables probably should not be considered as real symbols at
first place. */
if (VAR_P (decl) && DECL_HARD_REGISTER (decl))
return false;
/* FIXME: Builtins corresponding to real functions probably should have
symbol table entries. */
if (is_builtin_fn (decl))
return false;
/* We have real symbol that should be in symbol table. However try to trim
down the refernces to libraries bit more because linker will otherwise
bring unnecesary object files into the final link.
FIXME: The following checks can easily be confused i.e. by self recursive
function or self-referring variable. */
/* We keep external functions in symtab for sake of inlining
and devirtualization. We do not want to see them in symbol table as
references unless they are really used. */
cgraph_node *cnode = dyn_cast <cgraph_node *> (this);
if (cnode && (!definition || DECL_EXTERNAL (decl))
&& cnode->callers)
return true;
/* Ignore all references from external vars initializers - they are not really
part of the compilation unit until they are used by folding. Some symbols,
like references to external construction vtables can not be referred to at
all. We decide this at can_refer_decl_in_current_unit_p. */
if (!definition || DECL_EXTERNAL (decl))
{
int i;
struct ipa_ref *ref;
for (i = 0; iterate_referring (i, ref); i++)
{
if (ref->use == IPA_REF_ALIAS)
continue;
if (is_a <cgraph_node *> (ref->referring))
return true;
if (!DECL_EXTERNAL (ref->referring->decl))
return true;
}
return false;
}
return true;
}

View File

@ -5329,6 +5329,16 @@ free_lang_data_in_decl (tree decl)
At this point, it is not needed anymore. */
DECL_SAVED_TREE (decl) = NULL_TREE;
/* Clear the abstract origin if it refers to a method.
Otherwise dwarf2out.c will ICE as we splice functions out of
TYPE_FIELDS and thus the origin will not be output
correctly. */
if (DECL_ABSTRACT_ORIGIN (decl)
&& DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl))
&& RECORD_OR_UNION_TYPE_P
(DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl))))
DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE;
/* Sometimes the C++ frontend doesn't manage to transform a temporary
DECL_VINDEX referring to itself into a vtable slot number as it
should. Happens with functions that are copied and then forgotten