lto-cgraph.c (compute_ltrans_boundary): Add abstract origins into boundaries.

* lto-cgraph.c (compute_ltrans_boundary): Add abstract origins into
	boundaries.
	* lto-streamer-out.c (tree_is_indexable): Results decls and
	parm decls are not indexable.
	(DFS_write_tree_body): Do not follow args and results.
	(hash_tree): Likewise.
	(output_functions): Rearrange so struct function is needed
	only when real body is output; be able to also ouptut abstract
	functions; output DECL_ARGUMENTS and DECL_RESULT.
	(lto_output): When not in WPA, ale store abstract functions.
	(write_symbol): Do not care about RESULT_DECL.
	(output_symbol_p): Handle correctly sbtract decls.
	* lto-streamer-in.c (input_function): Rearrange so struct
	function can be NULL at entry; allow streaming of
	functions w/o body; store DECL_ARGUMENTS and DECL_RESULT.
	* ipa.c (symtab_remove_unreachable_nodes): Silence confused
	sanity check during LTO.
	* tree-streamer-out.c (write_ts_decl_non_common_tree_pointers): Skip
	RESULT_DECl and DECL_ARGUMENTS.
	* tree-streamer-in.c (lto_input_ts_decl_non_common_tree_pointers):
	Likewise.

	* lto.c (lto_materialize_function): Do not push struct function.
	* lto-partition.c (get_symbol_class): Handle abstracts correctly.
	(may_need_named_section_p): Even abstract origins may need
	named section.

From-SVN: r201468
This commit is contained in:
Jan Hubicka 2013-08-03 21:54:18 +02:00 committed by Jan Hubicka
parent 07838b1363
commit 815effe155
10 changed files with 124 additions and 81 deletions

View File

@ -1,3 +1,27 @@
2013-08-02 Jan Hubicka <jh@suse.cz>
* lto-cgraph.c (compute_ltrans_boundary): Add abstract origins into
boundaries.
* lto-streamer-out.c (tree_is_indexable): Results decls and
parm decls are not indexable.
(DFS_write_tree_body): Do not follow args and results.
(hash_tree): Likewise.
(output_functions): Rearrange so struct function is needed
only when real body is output; be able to also ouptut abstract
functions; output DECL_ARGUMENTS and DECL_RESULT.
(lto_output): When not in WPA, ale store abstract functions.
(write_symbol): Do not care about RESULT_DECL.
(output_symbol_p): Handle correctly sbtract decls.
* lto-streamer-in.c (input_function): Rearrange so struct
function can be NULL at entry; allow streaming of
functions w/o body; store DECL_ARGUMENTS and DECL_RESULT.
* ipa.c (symtab_remove_unreachable_nodes): Silence confused
sanity check during LTO.
* tree-streamer-out.c (write_ts_decl_non_common_tree_pointers): Skip
RESULT_DECl and DECL_ARGUMENTS.
* tree-streamer-in.c (lto_input_ts_decl_non_common_tree_pointers):
Likewise.
2013-08-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
* pretty-print.h (pp_underscore): New.

View File

@ -371,7 +371,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
if (!pointer_set_contains (body_needed_for_clonning, node->symbol.decl))
cgraph_release_function_body (node);
else if (!node->clone_of)
gcc_assert (DECL_RESULT (node->symbol.decl));
gcc_assert (in_lto_p || DECL_RESULT (node->symbol.decl));
if (node->symbol.definition)
{
if (file)
@ -382,7 +382,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
}
else
gcc_assert (node->clone_of || !cgraph_function_with_gimple_body_p (node)
|| DECL_RESULT (node->symbol.decl));
|| in_lto_p || DECL_RESULT (node->symbol.decl));
}
/* Inline clones might be kept around so their materializing allows further

View File

@ -749,6 +749,13 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
add_node_to (encoder, node, true);
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)node);
add_references (encoder, &node->symbol.ref_list);
/* For proper debug info, we need to ship the origins, too. */
if (DECL_ABSTRACT_ORIGIN (node->symbol.decl))
{
struct cgraph_node *origin_node
= cgraph_get_node (DECL_ABSTRACT_ORIGIN (node->symbol.decl));
add_node_to (encoder, origin_node, true);
}
}
for (lsei = lsei_start_variable_in_partition (in_encoder);
!lsei_end_p (lsei); lsei_next_variable_in_partition (&lsei))
@ -758,6 +765,13 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)vnode);
lto_set_symtab_encoder_encode_initializer (encoder, vnode);
add_references (encoder, &vnode->symbol.ref_list);
/* For proper debug info, we need to ship the origins, too. */
if (DECL_ABSTRACT_ORIGIN (vnode->symbol.decl))
{
struct varpool_node *origin_node
= varpool_get_node (DECL_ABSTRACT_ORIGIN (node->symbol.decl));
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)origin_node);
}
}
/* Pickle in also the initializer of all referenced readonly variables
to help folding. Constant pool variables are not shared, so we must

View File

@ -851,7 +851,7 @@ input_struct_function_base (struct function *fn, struct data_in *data_in,
static void
input_function (tree fn_decl, struct data_in *data_in,
struct lto_input_block *ib)
struct lto_input_block *ib, struct lto_input_block *ib_cfg)
{
struct function *fn;
enum LTO_tags tag;
@ -859,13 +859,30 @@ input_function (tree fn_decl, struct data_in *data_in,
basic_block bb;
struct cgraph_node *node;
fn = DECL_STRUCT_FUNCTION (fn_decl);
tag = streamer_read_record_start (ib);
gimple_register_cfg_hooks ();
lto_tag_check (tag, LTO_function);
/* Read decls for parameters and args. */
DECL_RESULT (fn_decl) = stream_read_tree (ib, data_in);
DECL_ARGUMENTS (fn_decl) = streamer_read_chain (ib, data_in);
/* Read the tree of lexical scopes for the function. */
DECL_INITIAL (fn_decl) = stream_read_tree (ib, data_in);
if (!streamer_read_uhwi (ib))
return;
push_struct_function (fn_decl);
fn = DECL_STRUCT_FUNCTION (fn_decl);
init_tree_ssa (fn);
/* We input IL in SSA form. */
cfun->gimple_df->in_ssa_p = true;
gimple_register_cfg_hooks ();
node = cgraph_get_create_node (fn_decl);
input_struct_function_base (fn, data_in, ib);
input_cfg (ib_cfg, fn, node->count_materialization_scale);
/* Read all the SSA names. */
input_ssa_names (ib, data_in, fn);
@ -873,11 +890,8 @@ input_function (tree fn_decl, struct data_in *data_in,
/* Read the exception handling regions in the function. */
input_eh_regions (ib, data_in, fn);
/* Read the tree of lexical scopes for the function. */
DECL_INITIAL (fn_decl) = stream_read_tree (ib, data_in);
gcc_assert (DECL_INITIAL (fn_decl));
DECL_SAVED_TREE (fn_decl) = NULL_TREE;
node = cgraph_get_create_node (fn_decl);
/* Read all the basic blocks. */
tag = streamer_read_record_start (ib);
@ -987,28 +1001,21 @@ lto_read_body (struct lto_file_decl_data *file_data, tree fn_decl,
if (section_type == LTO_section_function_body)
{
struct function *fn = DECL_STRUCT_FUNCTION (fn_decl);
struct lto_in_decl_state *decl_state;
struct cgraph_node *node = cgraph_get_node (fn_decl);
unsigned from;
gcc_checking_assert (node);
push_cfun (fn);
init_tree_ssa (fn);
/* We input IL in SSA form. */
cfun->gimple_df->in_ssa_p = true;
/* Use the function's decl state. */
decl_state = lto_get_function_in_decl_state (file_data, fn_decl);
gcc_assert (decl_state);
file_data->current_decl_state = decl_state;
input_cfg (&ib_cfg, fn, node->count_materialization_scale);
/* Set up the struct function. */
from = data_in->reader_cache->nodes.length ();
input_function (fn_decl, data_in, &ib_main);
input_function (fn_decl, data_in, &ib_main, &ib_cfg);
/* And fixup types we streamed locally. */
{
struct streamer_tree_cache_d *cache = data_in->reader_cache;

View File

@ -124,8 +124,8 @@ output_type_ref (struct output_block *ob, tree node)
static bool
tree_is_indexable (tree t)
{
if (TREE_CODE (t) == PARM_DECL)
return true;
if (TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
return false;
else if (TREE_CODE (t) == VAR_DECL && decl_function_context (t)
&& !TREE_STATIC (t))
return false;
@ -506,13 +506,7 @@ DFS_write_tree_body (struct output_block *ob,
if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
{
if (TREE_CODE (expr) == FUNCTION_DECL)
{
for (tree t = DECL_ARGUMENTS (expr); t; t = TREE_CHAIN (t))
DFS_follow_tree_edge (t);
DFS_follow_tree_edge (DECL_RESULT (expr));
}
else if (TREE_CODE (expr) == TYPE_DECL)
if (TREE_CODE (expr) == TYPE_DECL)
DFS_follow_tree_edge (DECL_ORIGINAL_TYPE (expr));
DFS_follow_tree_edge (DECL_VINDEX (expr));
}
@ -936,13 +930,7 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
{
if (code == FUNCTION_DECL)
{
for (tree a = DECL_ARGUMENTS (t); a; a = DECL_CHAIN (a))
visit (a);
visit (DECL_RESULT (t));
}
else if (code == TYPE_DECL)
if (code == TYPE_DECL)
visit (DECL_ORIGINAL_TYPE (t));
visit (DECL_VINDEX (t));
}
@ -1772,50 +1760,63 @@ output_function (struct cgraph_node *node)
streamer_write_record_start (ob, LTO_function);
output_struct_function_base (ob, fn);
/* Output all the SSA names used in the function. */
output_ssa_names (ob, fn);
/* Output any exception handling regions. */
output_eh_regions (ob, fn);
/* Output decls for parameters and args. */
stream_write_tree (ob, DECL_RESULT (function), true);
streamer_write_chain (ob, DECL_ARGUMENTS (function), true);
/* Output DECL_INITIAL for the function, which contains the tree of
lexical scopes. */
stream_write_tree (ob, DECL_INITIAL (function), true);
/* We will renumber the statements. The code that does this uses
the same ordering that we use for serializing them so we can use
the same code on the other end and not have to write out the
statement numbers. We do not assign UIDs to PHIs here because
virtual PHIs get re-computed on-the-fly which would make numbers
inconsistent. */
set_gimple_stmt_max_uid (cfun, 0);
FOR_ALL_BB (bb)
/* We also stream abstract functions where we stream only stuff needed for
debug info. */
if (gimple_has_body_p (function))
{
gimple_stmt_iterator gsi;
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
streamer_write_uhwi (ob, 1);
output_struct_function_base (ob, fn);
/* Output all the SSA names used in the function. */
output_ssa_names (ob, fn);
/* Output any exception handling regions. */
output_eh_regions (ob, fn);
/* We will renumber the statements. The code that does this uses
the same ordering that we use for serializing them so we can use
the same code on the other end and not have to write out the
statement numbers. We do not assign UIDs to PHIs here because
virtual PHIs get re-computed on-the-fly which would make numbers
inconsistent. */
set_gimple_stmt_max_uid (cfun, 0);
FOR_ALL_BB (bb)
{
gimple stmt = gsi_stmt (gsi);
gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
gimple_stmt_iterator gsi;
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple stmt = gsi_stmt (gsi);
gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
}
}
}
/* Output the code for the function. */
FOR_ALL_BB_FN (bb, fn)
output_bb (ob, bb, fn);
/* Output the code for the function. */
FOR_ALL_BB_FN (bb, fn)
output_bb (ob, bb, fn);
/* The terminator for this function. */
streamer_write_record_start (ob, LTO_null);
/* The terminator for this function. */
streamer_write_record_start (ob, LTO_null);
output_cfg (ob, fn);
output_cfg (ob, fn);
pop_cfun ();
}
else
streamer_write_uhwi (ob, 0);
/* Create a section to hold the pickled output of this function. */
produce_asm (ob, function);
destroy_output_block (ob);
pop_cfun ();
}
@ -1966,7 +1967,7 @@ lto_output (void)
#endif
decl_state = lto_new_out_decl_state ();
lto_push_out_decl_state (decl_state);
if (gimple_has_body_p (node->symbol.decl))
if (gimple_has_body_p (node->symbol.decl) || !flag_wpa)
output_function (node);
else
copy_function (node);
@ -2149,9 +2150,9 @@ write_symbol (struct streamer_tree_cache_d *cache,
if (!TREE_PUBLIC (t)
|| is_builtin_fn (t)
|| DECL_ABSTRACT (t)
|| TREE_CODE (t) == RESULT_DECL
|| (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t)))
return;
gcc_assert (TREE_CODE (t) != RESULT_DECL);
gcc_assert (TREE_CODE (t) == VAR_DECL
|| TREE_CODE (t) == FUNCTION_DECL);
@ -2254,7 +2255,7 @@ output_symbol_p (symtab_node node)
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 && DECL_EXTERNAL (cnode->symbol.decl)
if (cnode && (!node->symbol.definition || DECL_EXTERNAL (cnode->symbol.decl))
&& cnode->callers)
return true;
@ -2262,7 +2263,7 @@ output_symbol_p (symtab_node node)
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 (DECL_EXTERNAL (node->symbol.decl))
if (!node->symbol.definition || DECL_EXTERNAL (node->symbol.decl))
{
int i;
struct ipa_ref *ref;

View File

@ -1,3 +1,10 @@
2013-08-02 Jan Hubicka <jh@suse.cz>
* lto.c (lto_materialize_function): Do not push struct function.
* lto-partition.c (get_symbol_class): Handle abstracts correctly.
(may_need_named_section_p): Even abstract origins may need
named section.
2013-07-30 David Malcolm <dmalcolm@redhat.com>
* Make-lang.in (lto/lto.o:): Depend on CONTEXT_H and

View File

@ -56,6 +56,10 @@ get_symbol_class (symtab_node node)
/* Inline clones are always duplicated.
This include external delcarations. */
cgraph_node *cnode = dyn_cast <cgraph_node> (node);
if (DECL_ABSTRACT (node->symbol.decl))
return SYMBOL_EXTERNAL;
if (cnode && cnode->global.inlined_to)
return SYMBOL_DUPLICATE;
@ -840,8 +844,6 @@ may_need_named_section_p (lto_symtab_encoder_t encoder, symtab_node node)
return false;
if (symtab_real_symbol_p (node))
return false;
if (!cnode->global.inlined_to && !cnode->clones)
return false;
return (!encoder
|| (lto_symtab_encoder_lookup (encoder, node) != LCC_NOT_FOUND
&& lto_symtab_encoder_encode_body_p (encoder,

View File

@ -225,7 +225,6 @@ lto_materialize_function (struct cgraph_node *node)
gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
push_struct_function (decl);
announce_function (decl);
lto_input_function_body (file_data, decl, data);
if (DECL_FUNCTION_PERSONALITY (decl) && !first_personality_decl)
@ -233,7 +232,6 @@ lto_materialize_function (struct cgraph_node *node)
lto_stats.num_function_bodies++;
lto_free_section_data (file_data, LTO_section_function_body, name,
data, len);
pop_cfun ();
ggc_collect ();
}
}

View File

@ -678,12 +678,7 @@ static void
lto_input_ts_decl_non_common_tree_pointers (struct lto_input_block *ib,
struct data_in *data_in, tree expr)
{
if (TREE_CODE (expr) == FUNCTION_DECL)
{
DECL_ARGUMENTS (expr) = streamer_read_chain (ib, data_in);
DECL_RESULT (expr) = stream_read_tree (ib, data_in);
}
else if (TREE_CODE (expr) == TYPE_DECL)
if (TREE_CODE (expr) == TYPE_DECL)
DECL_ORIGINAL_TYPE (expr) = stream_read_tree (ib, data_in);
DECL_VINDEX (expr) = stream_read_tree (ib, data_in);
}

View File

@ -606,12 +606,7 @@ static void
write_ts_decl_non_common_tree_pointers (struct output_block *ob, tree expr,
bool ref_p)
{
if (TREE_CODE (expr) == FUNCTION_DECL)
{
streamer_write_chain (ob, DECL_ARGUMENTS (expr), ref_p);
stream_write_tree (ob, DECL_RESULT (expr), ref_p);
}
else if (TREE_CODE (expr) == TYPE_DECL)
if (TREE_CODE (expr) == TYPE_DECL)
stream_write_tree (ob, DECL_ORIGINAL_TYPE (expr), ref_p);
stream_write_tree (ob, DECL_VINDEX (expr), ref_p);
}