diff options
author | Jan Hubicka <jh@suse.cz> | 2013-08-06 18:59:49 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2013-08-06 16:59:49 +0000 |
commit | a2e2a66815796bd961250264ff32809bae478a31 (patch) | |
tree | e06c2e69d4ad72b54dff08acfb5ac74d389b8f74 | |
parent | e086adbdb433ea655c8bf0bdcd210baa5a0a63f6 (diff) | |
download | gcc-a2e2a66815796bd961250264ff32809bae478a31.tar.gz |
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
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/cgraph.c | 40 | ||||
-rw-r--r-- | gcc/cgraph.h | 1 | ||||
-rw-r--r-- | gcc/cgraphclones.c | 4 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 1 | ||||
-rw-r--r-- | gcc/ipa.c | 2 | ||||
-rw-r--r-- | gcc/lto-cgraph.c | 13 | ||||
-rw-r--r-- | gcc/lto/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/lto/lto.c | 35 | ||||
-rw-r--r-- | gcc/passes.c | 1 | ||||
-rw-r--r-- | gcc/tree-inline.c | 1 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.c | 7 |
12 files changed, 83 insertions, 39 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a28af116a7e..5dec128162d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/cgraph.c b/gcc/cgraph.c index a90e1a73ff1..bb7016f441d 100644 --- a/gcc/cgraph.c +++ b/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" diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 734f556cd9f..d681a1d65b4 100644 --- a/gcc/cgraph.h +++ b/gcc/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); diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index 04cb990cc86..21ef1f57f12 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -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) diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index cf92b1d658a..1472483342f 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -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. */ diff --git a/gcc/ipa.c b/gcc/ipa.c index 01e9bee2e28..9905ba78d66 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -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); diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index 0dde03a7b78..51dc705b28f 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -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); diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 33f3b321d81..cb10a4bf8c8 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -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. diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 42d67f1bd3d..c854589c673 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -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. */ diff --git a/gcc/passes.c b/gcc/passes.c index aa273fbe673..e3a7212ccce 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -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); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 2ebcd0d7a3e..e33e5a3a7e7 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -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) diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index a29db7f4df4..ff6babb14a3 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -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); |