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:
parent
e086adbdb4
commit
a2e2a66815
12 changed files with 83 additions and 39 deletions
|
@ -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
|
||||
|
|
40
gcc/cgraph.c
40
gcc/cgraph.c
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue