diff options
author | Jan Hubicka <jh@suse.cz> | 2013-08-10 00:53:00 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2013-08-09 22:53:00 +0000 |
commit | 634ab819546e358bae26a7f798652f1271ae099d (patch) | |
tree | 8a4fa2cb049df6b6085971ee7b7c3615601cc693 /gcc/ipa.c | |
parent | 537a6f7b4752b04a5ce4cb1fb96f1f1e9c407402 (diff) | |
download | gcc-634ab819546e358bae26a7f798652f1271ae099d.zip gcc-634ab819546e358bae26a7f798652f1271ae099d.tar.gz gcc-634ab819546e358bae26a7f798652f1271ae099d.tar.bz2 |
cgraph.c (cgraph_resolve_speculation): Cut frequency to CGRAPH_FREQ_MAX.
* cgraph.c (cgraph_resolve_speculation): Cut frequency to
CGRAPH_FREQ_MAX.
(dump_cgraph_node): Dump profile-id.
* cgraph.h (cgraph_indirect_call_info): Add common_target_id
and common_target_probability.
* lto-cgraph.c (lto_output_edge): Stream common targets.
(lto_output_node): Stream profile ids.
(input_node): Stream profile ids.
(input_edge): Stream common targets.
* lto-streamer-in.c (fixup_call_stmt_edges_1): Fix formatting.
* ipa.c: Include value-prof.h
(ipa_profile_generate_summary): Turn indirect call statement histograms
into common targets.
(ipa_profile): Turn common targets into speculative edges.
* gcc.dg/tree-prof/crossmodule-indircall-1.c: New testcase.
* gcc.dg/tree-prof/crossmodule-indircall-1a.c: New testcase.
From-SVN: r201639
Diffstat (limited to 'gcc/ipa.c')
-rw-r--r-- | gcc/ipa.c | 84 |
1 files changed, 82 insertions, 2 deletions
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see #include "params.h" #include "lto-streamer.h" #include "data-streamer.h" +#include "value-prof.h" /* Return true when NODE can not be local. Worker for cgraph_local_node_p. */ @@ -1291,8 +1292,40 @@ ipa_profile_generate_summary (void) int size = 0; for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { - time += estimate_num_insns (gsi_stmt (gsi), &eni_time_weights); - size += estimate_num_insns (gsi_stmt (gsi), &eni_size_weights); + gimple stmt = gsi_stmt (gsi); + if (gimple_code (stmt) == GIMPLE_CALL + && !gimple_call_fndecl (stmt)) + { + histogram_value h; + h = gimple_histogram_value_of_type + (DECL_STRUCT_FUNCTION (node->symbol.decl), + stmt, HIST_TYPE_INDIR_CALL); + /* No need to do sanity check: gimple_ic_transform already + takes away bad histograms. */ + if (h) + { + /* counter 0 is target, counter 1 is number of execution we called target, + counter 2 is total number of executions. */ + if (h->hvalue.counters[2]) + { + struct cgraph_edge * e = cgraph_edge (node, stmt); + e->indirect_info->common_target_id + = h->hvalue.counters [0]; + e->indirect_info->common_target_probability + = GCOV_COMPUTE_SCALE (h->hvalue.counters [1], h->hvalue.counters [2]); + if (e->indirect_info->common_target_probability > REG_BR_PROB_BASE) + { + if (dump_file) + fprintf (dump_file, "Probability capped to 1\n"); + e->indirect_info->common_target_probability = REG_BR_PROB_BASE; + } + } + gimple_remove_histogram_value (DECL_STRUCT_FUNCTION (node->symbol.decl), + stmt, h); + } + } + time += estimate_num_insns (stmt, &eni_time_weights); + size += estimate_num_insns (stmt, &eni_size_weights); } account_time_size (hashtable, histogram, bb->count, time, size); } @@ -1375,6 +1408,53 @@ ipa_profile (void) int i; gcov_type overall_time = 0, cutoff = 0, cumulated = 0, overall_size = 0; + /* Produce speculative calls: we saved common traget from porfiling into + e->common_target_id. Now, at link time, we can look up corresponding + function node and produce speculative call. */ + if (in_lto_p) + { + struct cgraph_edge *e; + struct cgraph_node *n,*n2; + + init_node_map (false); + FOR_EACH_DEFINED_FUNCTION (n) + { + bool update = false; + + for (e = n->indirect_calls; e; e = e->next_callee) + if (e->indirect_info->common_target_id) + { + n2 = find_func_by_profile_id (e->indirect_info->common_target_id); + if (n2) + { + if (dump_file) + { + fprintf (dump_file, "Indirect call -> direct call from" + " other module %s/%i => %s/%i, prob %3.2f\n", + xstrdup (cgraph_node_name (n)), n->symbol.order, + xstrdup (cgraph_node_name (n2)), n2->symbol.order, + e->indirect_info->common_target_probability + / (float)REG_BR_PROB_BASE); + } + cgraph_turn_edge_to_speculative + (e, n2, + apply_scale (e->count, + e->indirect_info->common_target_probability), + apply_scale (e->frequency, + e->indirect_info->common_target_probability)); + update = true; + } + else + if (dump_file) + fprintf (dump_file, "Function with profile-id %i not found.\n", + e->indirect_info->common_target_id); + } + if (update) + inline_update_overall_summary (n); + } + del_node_map (); + } + if (dump_file) dump_histogram (dump_file, histogram); for (i = 0; i < (int)histogram.length (); i++) |