+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
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"
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);
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);
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)
announce_function (decl);
node->process = 0;
gcc_assert (node->lowered);
+ cgraph_get_body (node);
/* Generate RTL for the body of DECL. */
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);
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;
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);
+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.
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. */
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);
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)
/* 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);
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)
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);