Commit 815effe1 by Jan Hubicka Committed by Jan Hubicka

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
parent 07838b13
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> 2013-08-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
* pretty-print.h (pp_underscore): New. * pretty-print.h (pp_underscore): New.
......
...@@ -371,7 +371,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *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)) if (!pointer_set_contains (body_needed_for_clonning, node->symbol.decl))
cgraph_release_function_body (node); cgraph_release_function_body (node);
else if (!node->clone_of) 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 (node->symbol.definition)
{ {
if (file) if (file)
...@@ -382,7 +382,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) ...@@ -382,7 +382,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
} }
else else
gcc_assert (node->clone_of || !cgraph_function_with_gimple_body_p (node) 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 /* Inline clones might be kept around so their materializing allows further
......
...@@ -749,6 +749,13 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder) ...@@ -749,6 +749,13 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
add_node_to (encoder, node, true); add_node_to (encoder, node, true);
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)node); lto_set_symtab_encoder_in_partition (encoder, (symtab_node)node);
add_references (encoder, &node->symbol.ref_list); 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); for (lsei = lsei_start_variable_in_partition (in_encoder);
!lsei_end_p (lsei); lsei_next_variable_in_partition (&lsei)) !lsei_end_p (lsei); lsei_next_variable_in_partition (&lsei))
...@@ -758,6 +765,13 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder) ...@@ -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_in_partition (encoder, (symtab_node)vnode);
lto_set_symtab_encoder_encode_initializer (encoder, vnode); lto_set_symtab_encoder_encode_initializer (encoder, vnode);
add_references (encoder, &vnode->symbol.ref_list); 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 /* Pickle in also the initializer of all referenced readonly variables
to help folding. Constant pool variables are not shared, so we must to help folding. Constant pool variables are not shared, so we must
......
...@@ -851,7 +851,7 @@ input_struct_function_base (struct function *fn, struct data_in *data_in, ...@@ -851,7 +851,7 @@ input_struct_function_base (struct function *fn, struct data_in *data_in,
static void static void
input_function (tree fn_decl, struct data_in *data_in, 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; struct function *fn;
enum LTO_tags tag; enum LTO_tags tag;
...@@ -859,13 +859,30 @@ input_function (tree fn_decl, struct data_in *data_in, ...@@ -859,13 +859,30 @@ input_function (tree fn_decl, struct data_in *data_in,
basic_block bb; basic_block bb;
struct cgraph_node *node; struct cgraph_node *node;
fn = DECL_STRUCT_FUNCTION (fn_decl);
tag = streamer_read_record_start (ib); tag = streamer_read_record_start (ib);
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 (); gimple_register_cfg_hooks ();
lto_tag_check (tag, LTO_function);
node = cgraph_get_create_node (fn_decl);
input_struct_function_base (fn, data_in, ib); input_struct_function_base (fn, data_in, ib);
input_cfg (ib_cfg, fn, node->count_materialization_scale);
/* Read all the SSA names. */ /* Read all the SSA names. */
input_ssa_names (ib, data_in, fn); input_ssa_names (ib, data_in, fn);
...@@ -873,11 +890,8 @@ input_function (tree fn_decl, struct data_in *data_in, ...@@ -873,11 +890,8 @@ input_function (tree fn_decl, struct data_in *data_in,
/* Read the exception handling regions in the function. */ /* Read the exception handling regions in the function. */
input_eh_regions (ib, data_in, fn); 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)); gcc_assert (DECL_INITIAL (fn_decl));
DECL_SAVED_TREE (fn_decl) = NULL_TREE; DECL_SAVED_TREE (fn_decl) = NULL_TREE;
node = cgraph_get_create_node (fn_decl);
/* Read all the basic blocks. */ /* Read all the basic blocks. */
tag = streamer_read_record_start (ib); tag = streamer_read_record_start (ib);
...@@ -987,28 +1001,21 @@ lto_read_body (struct lto_file_decl_data *file_data, tree fn_decl, ...@@ -987,28 +1001,21 @@ lto_read_body (struct lto_file_decl_data *file_data, tree fn_decl,
if (section_type == LTO_section_function_body) if (section_type == LTO_section_function_body)
{ {
struct function *fn = DECL_STRUCT_FUNCTION (fn_decl);
struct lto_in_decl_state *decl_state; struct lto_in_decl_state *decl_state;
struct cgraph_node *node = cgraph_get_node (fn_decl); struct cgraph_node *node = cgraph_get_node (fn_decl);
unsigned from; unsigned from;
gcc_checking_assert (node); 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. */ /* Use the function's decl state. */
decl_state = lto_get_function_in_decl_state (file_data, fn_decl); decl_state = lto_get_function_in_decl_state (file_data, fn_decl);
gcc_assert (decl_state); gcc_assert (decl_state);
file_data->current_decl_state = decl_state; file_data->current_decl_state = decl_state;
input_cfg (&ib_cfg, fn, node->count_materialization_scale);
/* Set up the struct function. */ /* Set up the struct function. */
from = data_in->reader_cache->nodes.length (); 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. */ /* And fixup types we streamed locally. */
{ {
struct streamer_tree_cache_d *cache = data_in->reader_cache; struct streamer_tree_cache_d *cache = data_in->reader_cache;
......
...@@ -124,8 +124,8 @@ output_type_ref (struct output_block *ob, tree node) ...@@ -124,8 +124,8 @@ output_type_ref (struct output_block *ob, tree node)
static bool static bool
tree_is_indexable (tree t) tree_is_indexable (tree t)
{ {
if (TREE_CODE (t) == PARM_DECL) if (TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
return true; return false;
else if (TREE_CODE (t) == VAR_DECL && decl_function_context (t) else if (TREE_CODE (t) == VAR_DECL && decl_function_context (t)
&& !TREE_STATIC (t)) && !TREE_STATIC (t))
return false; return false;
...@@ -506,13 +506,7 @@ DFS_write_tree_body (struct output_block *ob, ...@@ -506,13 +506,7 @@ DFS_write_tree_body (struct output_block *ob,
if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON)) if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
{ {
if (TREE_CODE (expr) == FUNCTION_DECL) if (TREE_CODE (expr) == TYPE_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)
DFS_follow_tree_edge (DECL_ORIGINAL_TYPE (expr)); DFS_follow_tree_edge (DECL_ORIGINAL_TYPE (expr));
DFS_follow_tree_edge (DECL_VINDEX (expr)); DFS_follow_tree_edge (DECL_VINDEX (expr));
} }
...@@ -936,13 +930,7 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t) ...@@ -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_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
{ {
if (code == FUNCTION_DECL) if (code == TYPE_DECL)
{
for (tree a = DECL_ARGUMENTS (t); a; a = DECL_CHAIN (a))
visit (a);
visit (DECL_RESULT (t));
}
else if (code == TYPE_DECL)
visit (DECL_ORIGINAL_TYPE (t)); visit (DECL_ORIGINAL_TYPE (t));
visit (DECL_VINDEX (t)); visit (DECL_VINDEX (t));
} }
...@@ -1772,6 +1760,19 @@ output_function (struct cgraph_node *node) ...@@ -1772,6 +1760,19 @@ output_function (struct cgraph_node *node)
streamer_write_record_start (ob, LTO_function); streamer_write_record_start (ob, LTO_function);
/* 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 also stream abstract functions where we stream only stuff needed for
debug info. */
if (gimple_has_body_p (function))
{
streamer_write_uhwi (ob, 1);
output_struct_function_base (ob, fn); output_struct_function_base (ob, fn);
/* Output all the SSA names used in the function. */ /* Output all the SSA names used in the function. */
...@@ -1780,9 +1781,6 @@ output_function (struct cgraph_node *node) ...@@ -1780,9 +1781,6 @@ output_function (struct cgraph_node *node)
/* Output any exception handling regions. */ /* Output any exception handling regions. */
output_eh_regions (ob, fn); output_eh_regions (ob, fn);
/* 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 /* 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 ordering that we use for serializing them so we can use
...@@ -1810,12 +1808,15 @@ output_function (struct cgraph_node *node) ...@@ -1810,12 +1808,15 @@ output_function (struct cgraph_node *node)
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. */ /* Create a section to hold the pickled output of this function. */
produce_asm (ob, function); produce_asm (ob, function);
destroy_output_block (ob); destroy_output_block (ob);
pop_cfun ();
} }
...@@ -1966,7 +1967,7 @@ lto_output (void) ...@@ -1966,7 +1967,7 @@ lto_output (void)
#endif #endif
decl_state = lto_new_out_decl_state (); decl_state = lto_new_out_decl_state ();
lto_push_out_decl_state (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); output_function (node);
else else
copy_function (node); copy_function (node);
...@@ -2149,9 +2150,9 @@ write_symbol (struct streamer_tree_cache_d *cache, ...@@ -2149,9 +2150,9 @@ write_symbol (struct streamer_tree_cache_d *cache,
if (!TREE_PUBLIC (t) if (!TREE_PUBLIC (t)
|| is_builtin_fn (t) || is_builtin_fn (t)
|| DECL_ABSTRACT (t) || DECL_ABSTRACT (t)
|| TREE_CODE (t) == RESULT_DECL
|| (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))) || (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t)))
return; return;
gcc_assert (TREE_CODE (t) != RESULT_DECL);
gcc_assert (TREE_CODE (t) == VAR_DECL gcc_assert (TREE_CODE (t) == VAR_DECL
|| TREE_CODE (t) == FUNCTION_DECL); || TREE_CODE (t) == FUNCTION_DECL);
...@@ -2254,7 +2255,7 @@ output_symbol_p (symtab_node node) ...@@ -2254,7 +2255,7 @@ output_symbol_p (symtab_node node)
and devirtualization. We do not want to see them in symbol table as and devirtualization. We do not want to see them in symbol table as
references unless they are really used. */ references unless they are really used. */
cnode = dyn_cast <cgraph_node> (node); 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) && cnode->callers)
return true; return true;
...@@ -2262,7 +2263,7 @@ output_symbol_p (symtab_node node) ...@@ -2262,7 +2263,7 @@ output_symbol_p (symtab_node node)
part of the compilation unit until they are used by folding. Some symbols, 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. like references to external construction vtables can not be referred to at all.
We decide this at can_refer_decl_in_current_unit_p. */ 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; int i;
struct ipa_ref *ref; struct ipa_ref *ref;
......
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> 2013-07-30 David Malcolm <dmalcolm@redhat.com>
* Make-lang.in (lto/lto.o:): Depend on CONTEXT_H and * Make-lang.in (lto/lto.o:): Depend on CONTEXT_H and
......
...@@ -56,6 +56,10 @@ get_symbol_class (symtab_node node) ...@@ -56,6 +56,10 @@ get_symbol_class (symtab_node node)
/* Inline clones are always duplicated. /* Inline clones are always duplicated.
This include external delcarations. */ This include external delcarations. */
cgraph_node *cnode = dyn_cast <cgraph_node> (node); cgraph_node *cnode = dyn_cast <cgraph_node> (node);
if (DECL_ABSTRACT (node->symbol.decl))
return SYMBOL_EXTERNAL;
if (cnode && cnode->global.inlined_to) if (cnode && cnode->global.inlined_to)
return SYMBOL_DUPLICATE; return SYMBOL_DUPLICATE;
...@@ -840,8 +844,6 @@ may_need_named_section_p (lto_symtab_encoder_t encoder, symtab_node node) ...@@ -840,8 +844,6 @@ may_need_named_section_p (lto_symtab_encoder_t encoder, symtab_node node)
return false; return false;
if (symtab_real_symbol_p (node)) if (symtab_real_symbol_p (node))
return false; return false;
if (!cnode->global.inlined_to && !cnode->clones)
return false;
return (!encoder return (!encoder
|| (lto_symtab_encoder_lookup (encoder, node) != LCC_NOT_FOUND || (lto_symtab_encoder_lookup (encoder, node) != LCC_NOT_FOUND
&& lto_symtab_encoder_encode_body_p (encoder, && lto_symtab_encoder_encode_body_p (encoder,
......
...@@ -225,7 +225,6 @@ lto_materialize_function (struct cgraph_node *node) ...@@ -225,7 +225,6 @@ lto_materialize_function (struct cgraph_node *node)
gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL); gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
push_struct_function (decl);
announce_function (decl); announce_function (decl);
lto_input_function_body (file_data, decl, data); lto_input_function_body (file_data, decl, data);
if (DECL_FUNCTION_PERSONALITY (decl) && !first_personality_decl) if (DECL_FUNCTION_PERSONALITY (decl) && !first_personality_decl)
...@@ -233,7 +232,6 @@ lto_materialize_function (struct cgraph_node *node) ...@@ -233,7 +232,6 @@ lto_materialize_function (struct cgraph_node *node)
lto_stats.num_function_bodies++; lto_stats.num_function_bodies++;
lto_free_section_data (file_data, LTO_section_function_body, name, lto_free_section_data (file_data, LTO_section_function_body, name,
data, len); data, len);
pop_cfun ();
ggc_collect (); ggc_collect ();
} }
} }
......
...@@ -678,12 +678,7 @@ static void ...@@ -678,12 +678,7 @@ static void
lto_input_ts_decl_non_common_tree_pointers (struct lto_input_block *ib, lto_input_ts_decl_non_common_tree_pointers (struct lto_input_block *ib,
struct data_in *data_in, tree expr) struct data_in *data_in, tree expr)
{ {
if (TREE_CODE (expr) == FUNCTION_DECL) if (TREE_CODE (expr) == TYPE_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)
DECL_ORIGINAL_TYPE (expr) = stream_read_tree (ib, data_in); DECL_ORIGINAL_TYPE (expr) = stream_read_tree (ib, data_in);
DECL_VINDEX (expr) = stream_read_tree (ib, data_in); DECL_VINDEX (expr) = stream_read_tree (ib, data_in);
} }
......
...@@ -606,12 +606,7 @@ static void ...@@ -606,12 +606,7 @@ static void
write_ts_decl_non_common_tree_pointers (struct output_block *ob, tree expr, write_ts_decl_non_common_tree_pointers (struct output_block *ob, tree expr,
bool ref_p) bool ref_p)
{ {
if (TREE_CODE (expr) == FUNCTION_DECL) if (TREE_CODE (expr) == TYPE_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)
stream_write_tree (ob, DECL_ORIGINAL_TYPE (expr), ref_p); stream_write_tree (ob, DECL_ORIGINAL_TYPE (expr), ref_p);
stream_write_tree (ob, DECL_VINDEX (expr), ref_p); stream_write_tree (ob, DECL_VINDEX (expr), ref_p);
} }
......
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