cgraph.c (cgraph_get_body): New function based on lto.c implementation.

* cgraph.c (cgraph_get_body): New function based on lto.c
	implementation.
	* cgraph.h (cgraph_get_body): Declare.
	* cgraphclones.c (cgraph_create_virtual_clone): Commonize WPA and LTO paths.
	* cgraphunit.c (expand_function): Get body prior expanding.
	* ipa.c (function_and_variable_visibility): Use gimple_has_body_p test.
	* lto-cgraph.c (lto_output_node): Do not stream bodies we don't really need.
	* passes.c (do_per_function_toporder): Get body.
	* tree-inline.c (expand_call_inline): Get body prior inlining it.
	* tree-ssa-structalias.c (ipa_pta_execute): Get body; skip clones.

	* lto.c (lto_materialize_function): Do not read body anymore.

From-SVN: r201537
This commit is contained in:
Jan Hubicka 2013-08-06 18:59:49 +02:00 committed by Jan Hubicka
parent e086adbdb4
commit a2e2a66815
12 changed files with 83 additions and 39 deletions

View file

@ -1,3 +1,16 @@
2013-08-06 Jan Hubicka <jh@suse.cz>
* cgraph.c (cgraph_get_body): New function based on lto.c
implementation.
* cgraph.h (cgraph_get_body): Declare.
* cgraphclones.c (cgraph_create_virtual_clone): Commonize WPA and LTO paths.
* cgraphunit.c (expand_function): Get body prior expanding.
* ipa.c (function_and_variable_visibility): Use gimple_has_body_p test.
* lto-cgraph.c (lto_output_node): Do not stream bodies we don't really need.
* passes.c (do_per_function_toporder): Get body.
* tree-inline.c (expand_call_inline): Get body prior inlining it.
* tree-ssa-structalias.c (ipa_pta_execute): Get body; skip clones.
2013-08-06 Martin Jambor <mjambor@suse.cz>
PR fortran/57987

View file

@ -2707,4 +2707,44 @@ cgraph_function_node (struct cgraph_node *node, enum availability *availability)
return node;
}
/* When doing LTO, read NODE's body from disk if it is not already present. */
bool
cgraph_get_body (struct cgraph_node *node)
{
struct lto_file_decl_data *file_data;
const char *data, *name;
size_t len;
tree decl = node->symbol.decl;
if (DECL_RESULT (decl))
return false;
gcc_assert (in_lto_p);
file_data = node->symbol.lto_file_data;
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
/* We may have renamed the declaration, e.g., a static function. */
name = lto_get_decl_name_mapping (file_data, name);
data = lto_get_section_data (file_data, LTO_section_function_body,
name, &len);
if (!data)
{
dump_cgraph_node (stderr, node);
fatal_error ("%s: section %s is missing",
file_data->file_name,
name);
}
gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
lto_input_function_body (file_data, decl, data);
lto_stats.num_function_bodies++;
lto_free_section_data (file_data, LTO_section_function_body, name,
data, len);
return true;
}
#include "gt-cgraph.h"

View file

@ -701,6 +701,7 @@ gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *);
bool cgraph_propagate_frequency (struct cgraph_node *node);
struct cgraph_node * cgraph_function_node (struct cgraph_node *,
enum availability *avail = NULL);
bool cgraph_get_body (struct cgraph_node *node);
/* In cgraphunit.c */
struct asm_node *add_asm_node (tree);

View file

@ -295,7 +295,7 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
size_t i;
struct ipa_replace_map *map;
if (!flag_wpa)
if (!in_lto_p)
gcc_checking_assert (tree_versionable_function_p (old_decl));
gcc_assert (old_node->local.can_change_signature || !args_to_skip);
@ -829,6 +829,8 @@ cgraph_materialize_all_clones (void)
if (node->clone_of && node->symbol.decl != node->clone_of->symbol.decl
&& !gimple_has_body_p (node->symbol.decl))
{
if (!node->clone_of->clone_of)
cgraph_get_body (node->clone_of);
if (gimple_has_body_p (node->clone_of->symbol.decl))
{
if (cgraph_dump_file)

View file

@ -1581,6 +1581,7 @@ expand_function (struct cgraph_node *node)
announce_function (decl);
node->process = 0;
gcc_assert (node->lowered);
cgraph_get_body (node);
/* Generate RTL for the body of DECL. */

View file

@ -915,7 +915,7 @@ function_and_variable_visibility (bool whole_program)
struct cgraph_edge *e = node->callers;
cgraph_redirect_edge_callee (e, alias);
if (!flag_wpa)
if (gimple_has_body_p (e->caller->symbol.decl))
{
push_cfun (DECL_STRUCT_FUNCTION (e->caller->symbol.decl));
cgraph_redirect_edge_call_stmt_to_callee (e);

View file

@ -376,7 +376,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
bool boundary_p;
intptr_t ref;
bool in_other_partition = false;
struct cgraph_node *clone_of;
struct cgraph_node *clone_of, *ultimate_clone_of;
struct ipa_opt_pass_d *pass;
int i;
bool alias_p;
@ -423,7 +423,16 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
else
clone_of = clone_of->clone_of;
if (LTO_symtab_analyzed_node)
/* See if body of the master function is output. If not, we are seeing only
an declaration and we do not need to pass down clone tree. */
ultimate_clone_of = clone_of;
while (ultimate_clone_of && ultimate_clone_of->clone_of)
ultimate_clone_of = ultimate_clone_of->clone_of;
if (clone_of && !lto_symtab_encoder_encode_body_p (encoder, ultimate_clone_of))
clone_of = NULL;
if (tag == LTO_symtab_analyzed_node)
gcc_assert (clone_of || !node->clone_of);
if (!clone_of)
streamer_write_hwi_stream (ob->main_stream, LCC_NOT_FOUND);

View file

@ -1,3 +1,7 @@
2013-08-06 Jan Hubicka <jh@suse.cz>
* lto.c (lto_materialize_function): Do not read body anymore.
2013-08-02 Jan Hubicka <jh@suse.cz>
* lto.c (lto_materialize_function): Do not push struct function.

View file

@ -192,48 +192,19 @@ static void
lto_materialize_function (struct cgraph_node *node)
{
tree decl;
struct lto_file_decl_data *file_data;
const char *data, *name;
size_t len;
decl = node->symbol.decl;
/* Read in functions with body (analyzed nodes)
and also functions that are needed to produce virtual clones. */
if ((cgraph_function_with_gimple_body_p (node) && node->symbol.analyzed)
|| node->used_as_abstract_origin
|| has_analyzed_clone_p (node))
{
/* Clones don't need to be read. */
if (node->clone_of)
return;
/* Load the function body only if not operating in WPA mode. In
WPA mode, the body of the function is not needed. */
if (!flag_wpa)
{
file_data = node->symbol.lto_file_data;
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
/* We may have renamed the declaration, e.g., a static function. */
name = lto_get_decl_name_mapping (file_data, name);
data = lto_get_section_data (file_data, LTO_section_function_body,
name, &len);
if (!data)
fatal_error ("%s: section %s is missing",
file_data->file_name,
name);
gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
announce_function (decl);
lto_input_function_body (file_data, decl, data);
if (DECL_FUNCTION_PERSONALITY (decl) && !first_personality_decl)
first_personality_decl = DECL_FUNCTION_PERSONALITY (decl);
lto_stats.num_function_bodies++;
lto_free_section_data (file_data, LTO_section_function_body, name,
data, len);
ggc_collect ();
}
if (DECL_FUNCTION_PERSONALITY (decl) && !first_personality_decl)
first_personality_decl = DECL_FUNCTION_PERSONALITY (decl);
}
/* Let the middle end know about the function. */

View file

@ -1597,6 +1597,7 @@ do_per_function_toporder (void (*callback) (void *data), void *data)
node->process = 0;
if (cgraph_function_with_gimple_body_p (node))
{
cgraph_get_body (node);
push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
callback (data);
free_dominance_info (CDI_DOMINATORS);

View file

@ -3939,6 +3939,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
goto egress;
}
fn = cg_edge->callee->symbol.decl;
cgraph_get_body (cg_edge->callee);
#ifdef ENABLE_CHECKING
if (cg_edge->callee->symbol.decl != id->dst_node->symbol.decl)

View file

@ -7088,8 +7088,9 @@ ipa_pta_execute (void)
/* Nodes without a body are not interesting. Especially do not
visit clones at this point for now - we get duplicate decls
there for inline clones at least. */
if (!cgraph_function_with_gimple_body_p (node))
if (!cgraph_function_with_gimple_body_p (node) || node->clone_of)
continue;
cgraph_get_body (node);
gcc_assert (!node->clone_of);
@ -7122,7 +7123,7 @@ ipa_pta_execute (void)
basic_block bb;
/* Nodes without a body are not interesting. */
if (!cgraph_function_with_gimple_body_p (node))
if (!cgraph_function_with_gimple_body_p (node) || node->clone_of)
continue;
if (dump_file)
@ -7231,7 +7232,7 @@ ipa_pta_execute (void)
struct cgraph_edge *e;
/* Nodes without a body are not interesting. */
if (!cgraph_function_with_gimple_body_p (node))
if (!cgraph_function_with_gimple_body_p (node) || node->clone_of)
continue;
fn = DECL_STRUCT_FUNCTION (node->symbol.decl);