/* Hooks for cfg representation specific functions.
- Copyright (C) 2003-2017 Free Software Foundation, Inc.
+ Copyright (C) 2003-2019 Free Software Foundation, Inc.
Contributed by Sebastian Pop <s.pop@laposte.net>
This file is part of GCC.
#include "tree-ssa.h"
#include "cfgloop.h"
+/* Disable warnings about missing quoting in GCC diagnostics. */
+#if __GNUC__ >= 10
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wformat-diag"
+#endif
+
/* A pointer to one of the hooks containers. */
static struct cfg_hooks *cfg_hooks;
error ("verify_flow_info: Wrong count of block %i", bb->index);
err = 1;
}
- if (bb->frequency < 0)
+ /* FIXME: Graphite and SLJL and target code still tends to produce
+ edges with no probablity. */
+ if (profile_status_for_fn (cfun) >= PROFILE_GUESSED
+ && !bb->count.initialized_p () && !flag_graphite && 0)
{
- error ("verify_flow_info: Wrong frequency of block %i %i",
- bb->index, bb->frequency);
+ error ("verify_flow_info: Missing count of block %i", bb->index);
err = 1;
}
/* FIXME: Graphite and SLJL and target code still tends to produce
edges with no probablity. */
if (profile_status_for_fn (cfun) >= PROFILE_GUESSED
- && !e->probability.initialized_p () && 0)
+ && !e->probability.initialized_p () && !flag_graphite && 0)
{
error ("Uninitialized probability of edge %i->%i", e->src->index,
e->dest->index);
e->src->index, e->dest->index);
err = 1;
}
- if (!e->count.verify ())
- {
- error ("verify_flow_info: Wrong count of edge %i->%i",
- e->src->index, e->dest->index);
- err = 1;
- }
last_visited [e->dest->index] = bb;
DEBUG_FUNCTION void
debug (basic_block_def &ref)
{
- dump_bb (stderr, &ref, 0, 0);
+ dump_bb (stderr, &ref, 0, TDF_NONE);
}
DEBUG_FUNCTION void
fprintf (stderr, "<nil>\n");
}
+static void
+debug_slim (basic_block ptr)
+{
+ fprintf (stderr, "<basic_block %p (%d)>", (void *) ptr, ptr->index);
+}
+
+DEFINE_DEBUG_VEC (basic_block_def *)
+DEFINE_DEBUG_HASH_SET (basic_block_def *)
/* Dumps basic block BB to pretty-printer PP, for use as a label of
a DOT graph record-node. The implementation of this hook is
/* TODO: Add pretty printer for counter. */
if (bb->count.initialized_p ())
pp_printf (pp, "COUNT:" "%" PRId64, bb->count.to_gcov_type ());
- pp_printf (pp, " FREQ:%i |", bb->frequency);
pp_write_text_to_stream (pp);
if (!(dump_flags & TDF_SLIM))
cfg_hooks->dump_bb_for_graph (pp, bb);
{
s->flags |= e->flags;
s->probability += e->probability;
- s->count += e->count;
/* FIXME: This should be called via a hook and only for IR_GIMPLE. */
redirect_edge_var_map_dup (s, e);
remove_edge (e);
return NULL;
new_bb->count = bb->count;
- new_bb->frequency = bb->frequency;
new_bb->discriminator = bb->discriminator;
if (dom_info_available_p (CDI_DOMINATORS))
split_edge (edge e)
{
basic_block ret;
- profile_count count = e->count;
- int freq = EDGE_FREQUENCY (e);
+ profile_count count = e->count ();
edge f;
bool irr = (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0;
struct loop *loop;
ret = cfg_hooks->split_edge (e);
ret->count = count;
- ret->frequency = freq;
single_succ_edge (ret)->probability = profile_probability::always ();
- single_succ_edge (ret)->count = count;
if (irr)
{
fallthru = split_block_after_labels (bb);
dummy = fallthru->src;
dummy->count = profile_count::zero ();
- dummy->frequency = 0;
- fallthru->count = profile_count::zero ();
bb = fallthru->dest;
/* Redirect back edges we want to keep. */
if (redirect_edge_p (e))
{
- dummy->frequency += EDGE_FREQUENCY (e);
- if (dummy->frequency > BB_FREQ_MAX)
- dummy->frequency = BB_FREQ_MAX;
-
- dummy->count += e->count;
- fallthru->count += e->count;
+ dummy->count += e->count ();
ei_next (&ei);
continue;
}
AFTER. */
basic_block
-duplicate_block (basic_block bb, edge e, basic_block after)
+duplicate_block (basic_block bb, edge e, basic_block after, copy_bb_data *id)
{
edge s, n;
basic_block new_bb;
- profile_count new_count = e ? e->count : profile_count::uninitialized ();
+ profile_count new_count = e ? e->count (): profile_count::uninitialized ();
edge_iterator ei;
if (!cfg_hooks->duplicate_block)
gcc_checking_assert (can_duplicate_block_p (bb));
- new_bb = cfg_hooks->duplicate_block (bb);
+ new_bb = cfg_hooks->duplicate_block (bb, id);
if (after)
move_block_after (new_bb, after);
is no need to actually check for duplicated edges. */
n = unchecked_make_edge (new_bb, s->dest, s->flags);
n->probability = s->probability;
- if (e && bb->count > profile_count::zero ())
- {
- n->count = s->count.apply_scale (new_count, bb->count);
- s->count -= n->count;
- }
- else
- n->count = s->count;
n->aux = s->aux;
}
new_bb->count = new_count;
bb->count -= new_count;
- new_bb->frequency = EDGE_FREQUENCY (e);
- bb->frequency -= EDGE_FREQUENCY (e);
-
redirect_edge_and_branch_force (e, new_bb);
-
- if (bb->frequency < 0)
- bb->frequency = 0;
}
else
- {
- new_bb->count = bb->count;
- new_bb->frequency = bb->frequency;
- }
+ new_bb->count = bb->count;
set_bb_original (new_bb, bb);
set_bb_copy (bb, new_bb);
unsigned i, j;
basic_block bb, new_bb, dom_bb;
edge e;
+ copy_bb_data id;
/* Mark the blocks to be copied. This is used by edge creation hooks
to decide whether to reallocate PHI nodes capacity to avoid reallocating
{
/* Duplicate. */
bb = bbs[i];
- new_bb = new_bbs[i] = duplicate_block (bb, NULL, after);
+ new_bb = new_bbs[i] = duplicate_block (bb, NULL, after, &id);
after = new_bb;
if (bb->loop_father)
{
/* Work-horse for passes.c:check_profile_consistency.
Do book-keeping of the CFG for the profile consistency checker.
- If AFTER_PASS is 0, do pre-pass accounting, or if AFTER_PASS is 1
- then do post-pass accounting. Store the counting in RECORD. */
+ Store the counting in RECORD. */
void
-account_profile_record (struct profile_record *record, int after_pass)
+profile_record_check_consistency (profile_record *record)
{
basic_block bb;
edge_iterator ei;
sum += e->probability;
if (EDGE_COUNT (bb->succs)
&& sum.differs_from_p (profile_probability::always ()))
- record->num_mismatched_freq_out[after_pass]++;
+ record->num_mismatched_freq_out++;
profile_count lsum = profile_count::zero ();
FOR_EACH_EDGE (e, ei, bb->succs)
- lsum += e->count;
+ lsum += e->count ();
if (EDGE_COUNT (bb->succs) && (lsum.differs_from_p (bb->count)))
- record->num_mismatched_count_out[after_pass]++;
+ record->num_mismatched_count_out++;
}
if (bb != ENTRY_BLOCK_PTR_FOR_FN (cfun)
&& profile_status_for_fn (cfun) != PROFILE_ABSENT)
{
- int sum = 0;
- FOR_EACH_EDGE (e, ei, bb->preds)
- sum += EDGE_FREQUENCY (e);
- if (abs (sum - bb->frequency) > 100
- || (MAX (sum, bb->frequency) > 10
- && abs ((sum - bb->frequency) * 100 / (MAX (sum, bb->frequency) + 1)) > 10))
- record->num_mismatched_freq_in[after_pass]++;
+ profile_probability sum = profile_probability::never ();
profile_count lsum = profile_count::zero ();
FOR_EACH_EDGE (e, ei, bb->preds)
- lsum += e->count;
+ {
+ sum += e->probability;
+ lsum += e->count ();
+ }
+ if (EDGE_COUNT (bb->preds)
+ && sum.differs_from_p (profile_probability::always ()))
+ record->num_mismatched_freq_in++;
if (lsum.differs_from_p (bb->count))
- record->num_mismatched_count_in[after_pass]++;
+ record->num_mismatched_count_in++;
}
if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)
|| bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
continue;
gcc_assert (cfg_hooks->account_profile_record);
- cfg_hooks->account_profile_record (bb, after_pass, record);
+ cfg_hooks->account_profile_record (bb, record);
+ }
+}
+
+/* Work-horse for passes.c:acount_profile.
+ Do book-keeping of the CFG for the profile accounting.
+ Store the counting in RECORD. */
+
+void
+profile_record_account_profile (profile_record *record)
+{
+ basic_block bb;
+
+ FOR_ALL_BB_FN (bb, cfun)
+ {
+ gcc_assert (cfg_hooks->account_profile_record);
+ cfg_hooks->account_profile_record (bb, record);
}
}
+
+#if __GNUC__ >= 10
+# pragma GCC diagnostic pop
+#endif