Commit c5d1f058 by Jan Hubicka Committed by Jan Hubicka

lto-streamer.c (write_symbol_vec): Rename to ...


	* lto-streamer.c (write_symbol_vec): Rename to ...
	(write_symbol) ... this one; write only symbol given and when
	present in cache. Sanity check that what is defined is present
	in cgraph/varpool with body/finalized decl.
	(write_symbols_of_kind): Remove.
	(produce_symtab): Take outputblock and sets; use cgraph/varpool/alias
	pairs to produce symtab.
	(produce_asm_for_decls): Update call of produce_symtab; don't do so
	when doing WPA streaming.

From-SVN: r161868
parent d414dde9
2010-07-05 Jan Hubicka <jh@suse.cz> 2010-07-05 Jan Hubicka <jh@suse.cz>
* lto-streamer.c (write_symbol_vec): Rename to ...
(write_symbol) ... this one; write only symbol given and when
present in cache. Sanity check that what is defined is present
in cgraph/varpool with body/finalized decl.
(write_symbols_of_kind): Remove.
(produce_symtab): Take outputblock and sets; use cgraph/varpool/alias
pairs to produce symtab.
(produce_asm_for_decls): Update call of produce_symtab; don't do so
when doing WPA streaming.
2010-07-05 Jan Hubicka <jh@suse.cz>
* gimple-fold.c (gimple_fold_obj_type_ref_known_binfo): Check that * gimple-fold.c (gimple_fold_obj_type_ref_known_binfo): Check that
function is still available to fold into. function is still available to fold into.
......
...@@ -1368,7 +1368,7 @@ gimple_fold_obj_type_ref_known_binfo (HOST_WIDE_INT token, tree known_binfo) ...@@ -1368,7 +1368,7 @@ gimple_fold_obj_type_ref_known_binfo (HOST_WIDE_INT token, tree known_binfo)
devirtualize. This can happen in WHOPR when the actual method devirtualize. This can happen in WHOPR when the actual method
ends up in other partition, because we found devirtualization ends up in other partition, because we found devirtualization
possibility too late. */ possibility too late. */
if ((!node || !node->analyzed) if ((!node || (!node->analyzed && !node->in_other_partition))
&& (!TREE_PUBLIC (fndecl) || DECL_COMDAT (fndecl))) && (!TREE_PUBLIC (fndecl) || DECL_COMDAT (fndecl)))
return NULL; return NULL;
return build_fold_addr_expr (fndecl); return build_fold_addr_expr (fndecl);
......
...@@ -2266,155 +2266,159 @@ lto_out_decl_state_written_size (struct lto_out_decl_state *state) ...@@ -2266,155 +2266,159 @@ lto_out_decl_state_written_size (struct lto_out_decl_state *state)
} }
/* Helper function of write_symbols_of_kind. CACHE is the streamer /* Write symbol T into STREAM in CACHE. SEEN specify symbols we wrote so
cache with all the pickled nodes. STREAM is the stream where to far. */
write the table. V is a vector with the DECLs that should be on
the table. SEEN is a bitmap of symbols written so far. */ static void
write_symbol (struct lto_streamer_cache_d *cache,
static void struct lto_output_stream *stream,
write_symbol_vec (struct lto_streamer_cache_d *cache, tree t, bitmap seen, bool alias)
struct lto_output_stream *stream, {
VEC(tree,heap) *v, bitmap seen) const char *name;
{ enum gcc_plugin_symbol_kind kind;
tree t; enum gcc_plugin_symbol_visibility visibility;
int index; int slot_num;
uint64_t size;
const char *comdat;
/* None of the following kinds of symbols are needed in the
symbol table. */
if (!TREE_PUBLIC (t)
|| is_builtin_fn (t)
|| DECL_ABSTRACT (t)
|| TREE_CODE (t) == RESULT_DECL)
return;
gcc_assert (TREE_CODE (t) == VAR_DECL
|| TREE_CODE (t) == FUNCTION_DECL);
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));
/* FIXME lto: this is from assemble_name_raw in varasm.c. For some
architectures we might have to do the same name manipulations that
ASM_OUTPUT_LABELREF does. */
if (name[0] == '*')
name = &name[1];
lto_streamer_cache_lookup (cache, t, &slot_num);
gcc_assert (slot_num >= 0);
/* Avoid duplicate symbols. */
if (bitmap_bit_p (seen, slot_num))
return;
else
bitmap_set_bit (seen, slot_num);
for (index = 0; VEC_iterate(tree, v, index, t); index++) if (DECL_EXTERNAL (t))
{ {
const char *name; if (DECL_WEAK (t))
enum gcc_plugin_symbol_kind kind; kind = GCCPK_WEAKUNDEF;
enum gcc_plugin_symbol_visibility visibility;
int slot_num;
uint64_t size;
const char *comdat;
/* None of the following kinds of symbols are needed in the
symbol table. */
if (!TREE_PUBLIC (t)
|| is_builtin_fn (t)
|| DECL_ABSTRACT (t)
|| TREE_CODE (t) == RESULT_DECL)
continue;
gcc_assert (TREE_CODE (t) == VAR_DECL
|| TREE_CODE (t) == FUNCTION_DECL);
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));
/* FIXME lto: this is from assemble_name_raw in varasm.c. For some
architectures we might have to do the same name manipulations that
ASM_OUTPUT_LABELREF does. */
if (name[0] == '*')
name = &name[1];
lto_streamer_cache_lookup (cache, t, &slot_num);
gcc_assert (slot_num >= 0);
/* Avoid duplicate symbols. */
if (bitmap_bit_p (seen, slot_num))
continue;
else
bitmap_set_bit (seen, slot_num);
if (DECL_EXTERNAL (t))
{
if (DECL_WEAK (t))
kind = GCCPK_WEAKUNDEF;
else
kind = GCCPK_UNDEF;
}
else
{
if (DECL_WEAK (t))
kind = GCCPK_WEAKDEF;
else if (DECL_COMMON (t))
kind = GCCPK_COMMON;
else
kind = GCCPK_DEF;
}
switch (DECL_VISIBILITY(t))
{
case VISIBILITY_DEFAULT:
visibility = GCCPV_DEFAULT;
break;
case VISIBILITY_PROTECTED:
visibility = GCCPV_PROTECTED;
break;
case VISIBILITY_HIDDEN:
visibility = GCCPV_HIDDEN;
break;
case VISIBILITY_INTERNAL:
visibility = GCCPV_INTERNAL;
break;
}
if (kind == GCCPK_COMMON
&& DECL_SIZE (t)
&& TREE_CODE (DECL_SIZE (t)) == INTEGER_CST)
size = (((uint64_t) TREE_INT_CST_HIGH (DECL_SIZE (t))) << 32)
| TREE_INT_CST_LOW (DECL_SIZE (t));
else else
size = 0; kind = GCCPK_UNDEF;
}
if (DECL_ONE_ONLY (t)) else
comdat = IDENTIFIER_POINTER (DECL_COMDAT_GROUP (t)); {
if (DECL_WEAK (t))
kind = GCCPK_WEAKDEF;
else if (DECL_COMMON (t))
kind = GCCPK_COMMON;
else else
comdat = ""; kind = GCCPK_DEF;
lto_output_data_stream (stream, name, strlen (name) + 1); /* When something is defined, it should have a node attached.
lto_output_data_stream (stream, comdat, strlen (comdat) + 1); FIXME: For fortran this is still not the case since wrapup global
lto_output_data_stream (stream, &kind, 1); decls is done after streaming. */
lto_output_data_stream (stream, &visibility, 1); gcc_assert (alias || TREE_CODE (t) != FUNCTION_DECL
lto_output_data_stream (stream, &size, 8); || (cgraph_get_node (t)
lto_output_data_stream (stream, &slot_num, 4); && cgraph_get_node (t)->analyzed));
} }
}
/* Write IL symbols of KIND. CACHE is the streamer cache with all the switch (DECL_VISIBILITY(t))
pickled nodes. SEEN is a bitmap of symbols written so far. */
static void
write_symbols_of_kind (lto_decl_stream_e_t kind,
struct lto_streamer_cache_d *cache, bitmap seen)
{
struct lto_out_decl_state *out_state;
struct lto_output_stream stream;
unsigned num_fns =
VEC_length (lto_out_decl_state_ptr, lto_function_decl_states);
unsigned idx;
memset (&stream, 0, sizeof (stream));
out_state = lto_get_out_decl_state ();
write_symbol_vec (cache, &stream, out_state->streams[kind].trees, seen);
for (idx = 0; idx < num_fns; idx++)
{ {
out_state = case VISIBILITY_DEFAULT:
VEC_index (lto_out_decl_state_ptr, lto_function_decl_states, idx); visibility = GCCPV_DEFAULT;
write_symbol_vec (cache, &stream, out_state->streams[kind].trees, seen); break;
case VISIBILITY_PROTECTED:
visibility = GCCPV_PROTECTED;
break;
case VISIBILITY_HIDDEN:
visibility = GCCPV_HIDDEN;
break;
case VISIBILITY_INTERNAL:
visibility = GCCPV_INTERNAL;
break;
} }
lto_write_stream (&stream); if (kind == GCCPK_COMMON
&& DECL_SIZE (t)
&& TREE_CODE (DECL_SIZE (t)) == INTEGER_CST)
size = (((uint64_t) TREE_INT_CST_HIGH (DECL_SIZE (t))) << 32)
| TREE_INT_CST_LOW (DECL_SIZE (t));
else
size = 0;
if (DECL_ONE_ONLY (t))
comdat = IDENTIFIER_POINTER (DECL_COMDAT_GROUP (t));
else
comdat = "";
lto_output_data_stream (stream, name, strlen (name) + 1);
lto_output_data_stream (stream, comdat, strlen (comdat) + 1);
lto_output_data_stream (stream, &kind, 1);
lto_output_data_stream (stream, &visibility, 1);
lto_output_data_stream (stream, &size, 8);
lto_output_data_stream (stream, &slot_num, 4);
} }
/* Write an IL symbol table. CACHE is the streamer cache with all the /* Write an IL symbol table to OB.
pickled nodes. */ SET and VSET are cgraph/varpool node sets we are outputting. */
static void static void
produce_symtab (struct lto_streamer_cache_d *cache) produce_symtab (struct output_block *ob,
cgraph_node_set set, varpool_node_set vset)
{ {
struct lto_streamer_cache_d *cache = ob->writer_cache;
char *section_name = lto_get_section_name (LTO_section_symtab, NULL); char *section_name = lto_get_section_name (LTO_section_symtab, NULL);
bitmap seen; bitmap seen;
struct cgraph_node *node, *alias;
struct varpool_node *vnode, *valias;
struct lto_output_stream stream;
lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder;
lto_cgraph_encoder_t encoder = ob->decl_state->cgraph_node_encoder;
int i;
alias_pair *p;
lto_begin_section (section_name, false); lto_begin_section (section_name, false);
free (section_name); free (section_name);
seen = lto_bitmap_alloc (); seen = lto_bitmap_alloc ();
write_symbols_of_kind (LTO_DECL_STREAM_FN_DECL, cache, seen); memset (&stream, 0, sizeof (stream));
write_symbols_of_kind (LTO_DECL_STREAM_VAR_DECL, cache, seen);
/* Write all functions. */
for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
{
node = lto_cgraph_encoder_deref (encoder, i);
write_symbol (cache, &stream, node->decl, seen, false);
for (alias = node->same_body; alias; alias = alias->next)
write_symbol (cache, &stream, alias->decl, seen, true);
}
/* Write all variables. */
for (i = 0; i < lto_varpool_encoder_size (varpool_encoder); i++)
{
vnode = lto_varpool_encoder_deref (varpool_encoder, i);
write_symbol (cache, &stream, vnode->decl, seen, false);
for (valias = vnode->extra_name; valias; valias = valias->next)
write_symbol (cache, &stream, valias->decl, seen, true);
}
/* Write all aliases. */
for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); i++)
if (output_alias_pair_p (p, set, vset))
write_symbol (cache, &stream, p->decl, seen, true);
lto_write_stream (&stream);
lto_bitmap_free (seen); lto_bitmap_free (seen);
lto_end_section (); lto_end_section ();
...@@ -2517,8 +2521,10 @@ produce_asm_for_decls (cgraph_node_set set, varpool_node_set vset) ...@@ -2517,8 +2521,10 @@ produce_asm_for_decls (cgraph_node_set set, varpool_node_set vset)
lto_end_section (); lto_end_section ();
/* Write the symbol table. */ /* Write the symbol table. It is used by linker to determine dependencies
produce_symtab (ob->writer_cache); and thus we can skip it for WPA. */
if (!flag_wpa)
produce_symtab (ob, set, vset);
/* Write command line opts. */ /* Write command line opts. */
lto_write_options (); lto_write_options ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment