aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2013-08-10 00:53:00 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2013-08-09 22:53:00 +0000
commit634ab819546e358bae26a7f798652f1271ae099d (patch)
tree8a4fa2cb049df6b6085971ee7b7c3615601cc693 /gcc/ipa.c
parent537a6f7b4752b04a5ce4cb1fb96f1f1e9c407402 (diff)
downloadgcc-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.c84
1 files changed, 82 insertions, 2 deletions
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 9905ba7..c870a6f 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -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++)