/* Calculate branch probabilities, and basic block execution counts.
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2015 Free Software Foundation, Inc.
Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
based on some ideas from Dain Samples of UC Berkeley.
Further mangling by Bob Manson, Cygnus Support.
#include "rtl.h"
#include "flags.h"
#include "regs.h"
-#include "expr.h"
+#include "symtab.h"
+#include "hard-reg-set.h"
#include "function.h"
+#include "alias.h"
+#include "tree.h"
+#include "insn-config.h"
+#include "expmed.h"
+#include "dojump.h"
+#include "explow.h"
+#include "calls.h"
+#include "emit-rtl.h"
+#include "varasm.h"
+#include "stmt.h"
+#include "expr.h"
+#include "predict.h"
+#include "dominance.h"
+#include "cfg.h"
+#include "cfganal.h"
#include "basic-block.h"
#include "diagnostic-core.h"
#include "coverage.h"
#include "value-prof.h"
-#include "tree.h"
+#include "fold-const.h"
#include "tree-ssa-alias.h"
#include "internal-fn.h"
#include "gimple-expr.h"
-#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "profile.h"
-struct bb_info {
+struct bb_profile_info {
unsigned int count_valid : 1;
/* Number of successor and predecessor edges. */
gcov_type pred_count;
};
-#define BB_INFO(b) ((struct bb_info *) (b)->aux)
+#define BB_INFO(b) ((struct bb_profile_info *) (b)->aux)
/* Counter summary from the last set of coverage counts read. */
static int total_hist_br_prob[20];
static int total_num_branches;
+/* Helper function to update gcov_working_sets. */
+
+void add_working_set (gcov_working_set_t *set) {
+ int i = 0;
+ for (; i < NUM_GCOV_WORKING_SETS; i++)
+ gcov_working_sets[i] = set[i];
+}
+
/* Forward declarations. */
static void find_spanning_tree (struct edge_list *);
FOR_EACH_EDGE (e, ei, bb->succs)
{
- struct edge_info *inf = EDGE_INFO (e);
+ struct edge_profile_info *inf = EDGE_INFO (e);
if (!inf->ignore && !inf->on_tree)
{
break;
case HIST_TYPE_INDIR_CALL:
+ case HIST_TYPE_INDIR_CALL_TOPN:
gimple_gen_ic_profiler (hist, t, 0);
break;
ws_info = &gcov_working_sets[ws_ix];
/* Print out the percentage using int arithmatic to avoid float. */
fprintf (dump_file, "\t\t%u.%02u%%: num counts=%u, min counter="
- HOST_WIDEST_INT_PRINT_DEC "\n",
+ "%" PRId64 "\n",
pct / 100, pct - (pct / 100 * 100),
ws_info->num_counters,
- (HOST_WIDEST_INT)ws_info->min_counter);
+ (int64_t)ws_info->min_counter);
}
}
}
if (dump_file)
{
fprintf (dump_file,
- "Edge %i->%i is inconsistent, count"HOST_WIDEST_INT_PRINT_DEC,
+ "Edge %i->%i is inconsistent, count%" PRId64,
e->src->index, e->dest->index, e->count);
dump_bb (dump_file, e->src, 0, TDF_DETAILS);
dump_bb (dump_file, e->dest, 0, TDF_DETAILS);
if (dump_file)
{
fprintf (dump_file, "BB %i count is negative "
- HOST_WIDEST_INT_PRINT_DEC,
+ "%" PRId64,
bb->index,
bb->count);
dump_bb (dump_file, bb, 0, TDF_DETAILS);
if (dump_file)
{
fprintf (dump_file, "BB %i count does not match sum of incoming edges "
- HOST_WIDEST_INT_PRINT_DEC" should be " HOST_WIDEST_INT_PRINT_DEC,
+ "%" PRId64" should be %" PRId64,
bb->index,
bb->count,
sum_edge_counts (bb->preds));
if (dump_file)
{
fprintf (dump_file, "BB %i count does not match sum of outgoing edges "
- HOST_WIDEST_INT_PRINT_DEC" should be " HOST_WIDEST_INT_PRINT_DEC,
+ "%" PRId64" should be %" PRId64,
bb->index,
bb->count,
sum_edge_counts (bb->succs));
{
fprintf (dump_file, "\nRead edge from %i to %i, count:",
bb->index, e->dest->index);
- fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
- (HOST_WIDEST_INT) e->count);
+ fprintf (dump_file, "%" PRId64,
+ (int64_t) e->count);
}
}
}
}
/* Attach extra info block to each bb. */
- alloc_aux_for_blocks (sizeof (struct bb_info));
+ alloc_aux_for_blocks (sizeof (struct bb_profile_info));
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
{
edge e;
changes = 0;
FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), NULL, prev_bb)
{
- struct bb_info *bi = BB_INFO (bb);
+ struct bb_profile_info *bi = BB_INFO (bb);
if (! bi->count_valid)
{
if (bi->succ_count == 0)
the corresponding call graph node. */
if (hist->type == HIST_TYPE_TIME_PROFILE)
{
- node = cgraph_get_node (hist->fun->decl);
-
- node->tp_first_run = hist->hvalue.counters[0];
+ node = cgraph_node::get (hist->fun->decl);
+ node->tp_first_run = hist->hvalue.counters[0];
if (dump_file)
fprintf (dump_file, "Read tp_first_run: %d\n", node->tp_first_run);
{
gimple_stmt_iterator gsi;
gimple first;
- tree fndecl;
- gsi = gsi_after_labels (bb);
+ gsi = gsi_start_nondebug_after_labels_bb (bb);
gcc_checking_assert (!gsi_end_p (gsi));
first = gsi_stmt (gsi);
- if (is_gimple_debug (first))
- {
- gsi_next_nondebug (&gsi);
- gcc_checking_assert (!gsi_end_p (gsi));
- first = gsi_stmt (gsi);
- }
/* Don't split the bbs containing __builtin_setjmp_receiver
- or __builtin_setjmp_dispatcher calls. These are very
+ or ABNORMAL_DISPATCHER calls. These are very
special and don't expect anything to be inserted before
them. */
if (is_gimple_call (first)
- && (((fndecl = gimple_call_fndecl (first)) != NULL
- && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
- && (DECL_FUNCTION_CODE (fndecl)
- == BUILT_IN_SETJMP_RECEIVER
- || (DECL_FUNCTION_CODE (fndecl)
- == BUILT_IN_SETJMP_DISPATCHER)))
- || gimple_call_flags (first) & ECF_RETURNS_TWICE))
+ && (gimple_call_builtin_p (first, BUILT_IN_SETJMP_RECEIVER)
+ || (gimple_call_flags (first) & ECF_RETURNS_TWICE)
+ || (gimple_call_internal_p (first)
+ && (gimple_call_internal_fn (first)
+ == IFN_ABNORMAL_DISPATCHER))))
continue;
if (dump_file)
el = create_edge_list ();
num_edges = NUM_EDGES (el);
- alloc_aux_for_edges (sizeof (struct edge_info));
+ alloc_aux_for_edges (sizeof (struct edge_profile_info));
/* The basic blocks are expected to be numbered sequentially. */
compact_blocks ();
for (num_instrumented = i = 0; i < num_edges; i++)
{
edge e = INDEX_EDGE (el, i);
- struct edge_info *inf = EDGE_INFO (e);
+ struct edge_profile_info *inf = EDGE_INFO (e);
if (inf->ignore || inf->on_tree)
/*NOP*/;
the checksum in only once place, since it depends on the shape
of the control flow which can change during
various transformations. */
- cfg_checksum = coverage_compute_cfg_checksum ();
+ cfg_checksum = coverage_compute_cfg_checksum (cfun);
lineno_checksum = coverage_compute_lineno_checksum ();
/* Write the data from which gcov can reconstruct the basic block
FOR_EACH_EDGE (e, ei, bb->succs)
{
- struct edge_info *i = EDGE_INFO (e);
+ struct edge_profile_info *i = EDGE_INFO (e);
if (!i->ignore)
{
unsigned flag_bits = 0;