This patch calls add_fake_edge for the AutoFDO+LIPO path. Bootstrapped and passed regression test and performance test.
OK for google-4_8? Thanks, Dehao
Index: gcc/auto-profile.c =================================================================== --- gcc/auto-profile.c (revision 209123) +++ gcc/auto-profile.c (working copy) @@ -190,6 +190,9 @@ class function_instance { /* Mark LOC as annotated. */ void mark_annotated (location_t loc); + /* Save all call targets under this function_instance in RET. */ + void get_all_possible_call_targets (std::set<unsigned> *ret) const; + private: function_instance (unsigned name, gcov_type head_count) : name_(name), total_count_(0), head_count_(head_count) {} @@ -555,6 +558,22 @@ void function_instance::mark_annotated (location_t iter->second.annotated = true; } +void function_instance::get_all_possible_call_targets ( + std::set<unsigned> *ret) const +{ + for (callsite_map::const_iterator iter = callsites.begin(); + iter != callsites.end(); ++iter) + { + ret->insert (iter->second->name()); + iter->second->get_all_possible_call_targets (ret); + } + for (position_count_map::const_iterator iter = pos_counts.begin(); + iter != pos_counts.end(); ++iter) + for (icall_target_map::const_iterator t_iter = iter->second.targets.begin(); + t_iter != iter->second.targets.end(); ++t_iter) + ret->insert (t_iter->first); +} + /* Read the inlinied indirect call target profile for STMT and store it in MAP, return the total count for all inlined indirect calls. */ @@ -1666,6 +1685,23 @@ afdo_callsite_hot_enough_for_early_inline (struct return false; } +/* Stores all possible call targets for NODE to RET. */ + +void get_all_possible_call_targets (struct cgraph_node *node, + std::vector<const char *> *ret) +{ + std::set<unsigned> index_set; + const autofdo::function_instance *func = + autofdo::afdo_source_profile->get_function_instance_by_decl ( + node->symbol.decl); + if (func == NULL) + return; + func->get_all_possible_call_targets (&index_set); + for (std::set<unsigned>::const_iterator iter = index_set.begin(); + iter != index_set.end(); ++iter) + ret->push_back (autofdo::afdo_function_name_map->get_name (*iter)); +} + struct simple_ipa_opt_pass pass_ipa_auto_profile = { { Index: gcc/auto-profile.h =================================================================== --- gcc/auto-profile.h (revision 209123) +++ gcc/auto-profile.h (working copy) @@ -21,6 +21,8 @@ along with GCC; see the file COPYING3. If not see #ifndef AUTO_PROFILE_H #define AUTO_PROFILE_H +#include <vector> + /* Read, process, finalize AutoFDO data structures. */ extern void init_auto_profile (void); extern void end_auto_profile (void); @@ -28,4 +30,7 @@ extern void end_auto_profile (void); /* Returns TRUE if EDGE is hot enough to be inlined early. */ extern bool afdo_callsite_hot_enough_for_early_inline (struct cgraph_edge *); +/* Stores all possible call targets for NODE to RET. */ +extern void get_all_possible_call_targets (struct cgraph_node *, + std::vector<const char *> *); #endif /* AUTO_PROFILE_H */ Index: gcc/cgraphbuild.c =================================================================== --- gcc/cgraphbuild.c (revision 209123) +++ gcc/cgraphbuild.c (working copy) @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "except.h" #include "l-ipo.h" #include "ipa-inline.h" +#include "auto-profile.h" /* Context of record_reference. */ struct record_reference_ctx @@ -244,6 +245,25 @@ add_fake_indirect_call_edges (struct cgraph_node * if (!L_IPO_COMP_MODE) return; + if (flag_auto_profile) + { + std::vector<const char *> targets; + get_all_possible_call_targets (node, &targets); + for (std::vector<const char *>::const_iterator iter = targets.begin(); + iter != targets.end(); ++iter) + { + struct cgraph_node * callee = ( + cgraph_node_for_asm (get_identifier (*iter))); + if (!callee) + continue; + if (cgraph_pre_profiling_inlining_done) + callee = cgraph_lipo_get_resolved_node (callee->symbol.decl); + if (callee) + cgraph_create_edge (node, callee, NULL, 1, 0); + } + return; + } + ic_counts = get_coverage_counts_no_warn (DECL_STRUCT_FUNCTION (node->symbol.decl), GCOV_COUNTER_ICALL_TOPNV, &n_counts);