From b65312797b664375bc65ddb56483cbcb896b0f02 Mon Sep 17 00:00:00 2001 From: davidxl Date: Mon, 7 Apr 2014 23:06:36 +0000 Subject: [PATCH] port 208882 from v17 (LIPO refactoring) git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/google@209204 138bc75d-0d04-0410-961f-82ee72b054a4 --- main/gcc/cgraphbuild.c | 62 +++++++++++++++++++++++++++++++++++++++++++++---- main/gcc/l-ipo.h | 2 +- main/gcc/tree-profile.c | 28 +++------------------- main/gcc/value-prof.c | 15 ++++++++---- 4 files changed, 72 insertions(+), 35 deletions(-) diff --git a/main/gcc/cgraphbuild.c b/main/gcc/cgraphbuild.c index 6af74f2b27c..712886ef3be 100644 --- a/main/gcc/cgraphbuild.c +++ b/main/gcc/cgraphbuild.c @@ -27,6 +27,8 @@ along with GCC; see the file COPYING3. If not see #include "pointer-set.h" #include "basic-block.h" #include "tree-ssa-alias.h" +#include "tree-ssa-operands.h" +#include "tree-into-ssa.h" #include "internal-fn.h" #include "gimple-fold.h" #include "gimple-expr.h" @@ -252,9 +254,6 @@ add_fake_indirect_call_edges (struct cgraph_node *node) if (!L_IPO_COMP_MODE) return; - if (cgraph_pre_profiling_inlining_done) - return; - ic_counts = get_coverage_counts_no_warn (DECL_STRUCT_FUNCTION (node->decl), GCOV_COUNTER_ICALL_TOPNV, &n_counts); @@ -633,7 +632,7 @@ record_references_in_initializer (tree decl, bool only_vars) needs to be set to the resolved node so that ipa-inline sees the definitions. */ #include "gimple-pretty-print.h" -void +static void lipo_fixup_cgraph_edge_call_target (gimple stmt) { tree decl; @@ -659,6 +658,58 @@ lipo_fixup_cgraph_edge_call_target (gimple stmt) } } +/* Link the cgraph nodes, varpool nodes and fixup the call target to + the correct decl. Remove dead functions. */ + + +void +lipo_link_and_fixup () +{ + struct cgraph_node *node; + + cgraph_pre_profiling_inlining_done = true; + cgraph_process_module_scope_statics (); + /* Now perform link to allow cross module inlining. */ + cgraph_do_link (); + varpool_do_link (); + cgraph_unify_type_alias_sets (); + cgraph_init_gid_map (); + + FOR_EACH_DEFINED_FUNCTION (node) + { + if (!gimple_has_body_p (node->decl)) + continue; + + /* Don't profile functions produced for builtin stuff. */ + if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION) + continue; + + push_cfun (DECL_STRUCT_FUNCTION (node->decl)); + + if (L_IPO_COMP_MODE) + { + basic_block bb; + FOR_EACH_BB_FN (bb, cfun) + { + gimple_stmt_iterator gsi; + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple stmt = gsi_stmt (gsi); + if (is_gimple_call (stmt)) + lipo_fixup_cgraph_edge_call_target (stmt); + } + } + update_ssa (TODO_update_ssa); + } + rebuild_cgraph_edges (); + pop_cfun (); + } + + cgraph_add_fake_indirect_call_edges (); + symtab_remove_unreachable_nodes (true, dump_file); +} + + /* Rebuild cgraph edges for current function node. This needs to be run after passes that don't update the cgraph. */ @@ -710,7 +761,8 @@ rebuild_cgraph_edges (void) ipa_record_stmt_references (node, gsi_stmt (gsi)); } - add_fake_indirect_call_edges (node); + if (!cgraph_pre_profiling_inlining_done) + add_fake_indirect_call_edges (node); record_eh_tables (node, cfun); gcc_assert (!node->global.inlined_to); diff --git a/main/gcc/l-ipo.h b/main/gcc/l-ipo.h index 7f8b0ed4792..211f74ad07a 100644 --- a/main/gcc/l-ipo.h +++ b/main/gcc/l-ipo.h @@ -60,7 +60,7 @@ void add_decl_to_current_module_scope (tree decl, void *b); int lipo_cmp_type (tree t1, tree t2); tree get_type_or_decl_name (tree); int equivalent_struct_types_for_tbaa (const_tree t1, const_tree t2); -void lipo_fixup_cgraph_edge_call_target (gimple); +void lipo_link_and_fixup (void); extern void copy_defined_module_set (tree, tree); extern bool is_parsing_done_p (void); extern const char* get_module_name (unsigned int); diff --git a/main/gcc/tree-profile.c b/main/gcc/tree-profile.c index b72a339e070..be53fff60a3 100644 --- a/main/gcc/tree-profile.c +++ b/main/gcc/tree-profile.c @@ -1238,16 +1238,11 @@ tree_profiling (void) /* After value profile transformation, artificial edges (that keep function body from being deleted) won't be needed. */ - - cgraph_pre_profiling_inlining_done = true; - cgraph_process_module_scope_statics (); - /* Now perform link to allow cross module inlining. */ - cgraph_do_link (); - varpool_do_link (); - cgraph_unify_type_alias_sets (); - + if (L_IPO_COMP_MODE) + lipo_link_and_fixup (); init_node_map (true); + FOR_EACH_DEFINED_FUNCTION (node) { if (!gimple_has_body_p (node->decl)) @@ -1259,23 +1254,6 @@ tree_profiling (void) push_cfun (DECL_STRUCT_FUNCTION (node->decl)); - if (L_IPO_COMP_MODE) - { - basic_block bb; - FOR_EACH_BB_FN (bb, cfun) - { - gimple_stmt_iterator gsi; - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple stmt = gsi_stmt (gsi); - if (is_gimple_call (stmt)) - lipo_fixup_cgraph_edge_call_target (stmt); - } - } - update_ssa (TODO_update_ssa); - } - - /* Local pure-const may imply need to fixup the cfg. */ if (execute_fixup_cfg () & TODO_cleanup_cfg) cleanup_tree_cfg (); diff --git a/main/gcc/value-prof.c b/main/gcc/value-prof.c index 9c310c0ce6a..931b56d1939 100644 --- a/main/gcc/value-prof.c +++ b/main/gcc/value-prof.c @@ -1410,10 +1410,8 @@ init_gid_map (void) { struct cgraph_node *n; - gcc_assert (!gid_map); - - gid_map - = htab_create (10, htab_gid_hash, htab_gid_eq, htab_gid_del); + if (!gid_map) + gid_map = htab_create (10, htab_gid_hash, htab_gid_eq, htab_gid_del); FOR_EACH_FUNCTION (n) { @@ -1441,6 +1439,15 @@ init_gid_map (void) entp->node = n; entp->gid = ent.gid; } + else if (cgraph_pre_profiling_inlining_done) + { + (*slot)->node = cgraph_lipo_get_resolved_node (n->decl); + (*slot)->gid = ent.gid; + } + else + { + gcc_assert ((*slot)->gid == ent.gid && (*slot)->node == n); + } } } -- 2.11.4.GIT