/* Control flow graph manipulation code for GNU compiler.
- Copyright (C) 1987-2017 Free Software Foundation, Inc.
+ Copyright (C) 1987-2018 Free Software Foundation, Inc.
This file is part of GCC.
if (!the_fun->cfg)
the_fun->cfg = ggc_cleared_alloc<control_flow_graph> ();
n_edges_for_fn (the_fun) = 0;
+ the_fun->cfg->count_max = profile_count::uninitialized ();
ENTRY_BLOCK_PTR_FOR_FN (the_fun)
= alloc_block ();
ENTRY_BLOCK_PTR_FOR_FN (the_fun)->index = ENTRY_BLOCK;
= EXIT_BLOCK_PTR_FOR_FN (the_fun);
EXIT_BLOCK_PTR_FOR_FN (the_fun)->prev_bb
= ENTRY_BLOCK_PTR_FOR_FN (the_fun);
+ the_fun->cfg->edge_flags_allocated = EDGE_ALL_FLAGS;
+ the_fun->cfg->bb_flags_allocated = BB_ALL_FLAGS;
}
\f
/* Helper function for remove_edge and clear_edges. Frees edge structure
clear_bb_flags (void)
{
basic_block bb;
+ int flags_to_preserve = BB_FLAGS_TO_PRESERVE;
+ if (current_loops
+ && loops_state_satisfies_p (cfun, LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS))
+ flags_to_preserve |= BB_IRREDUCIBLE_LOOP;
FOR_ALL_BB_FN (bb, cfun)
- bb->flags &= BB_FLAGS_TO_PRESERVE;
+ bb->flags &= flags_to_preserve;
}
\f
/* Check the consistency of profile information. We can't do that
}
if (bb != ENTRY_BLOCK_PTR_FOR_FN (fun))
{
- int sum = 0;
+ profile_count sum = profile_count::zero ();
FOR_EACH_EDGE (e, ei, bb->preds)
- sum += EDGE_FREQUENCY (e);
- if (abs (sum - bb->frequency) > 100)
- fprintf (file,
- ";; %sInvalid sum of incoming frequencies %i, should be %i\n",
- s_indent, sum, bb->frequency);
+ sum += e->count ();
+ if (sum.differs_from_p (bb->count))
+ {
+ fprintf (file, ";; %sInvalid sum of incoming counts ",
+ s_indent);
+ sum.dump (file);
+ fprintf (file, ", should be ");
+ bb->count.dump (file);
+ fprintf (file, "\n");
+ }
}
if (BB_PARTITION (bb) == BB_COLD_PARTITION)
{
debug (edge_def &ref)
{
/* FIXME (crowl): Is this desireable? */
- dump_edge_info (stderr, &ref, 0, false);
- dump_edge_info (stderr, &ref, 0, true);
+ dump_edge_info (stderr, &ref, TDF_NONE, false);
+ dump_edge_info (stderr, &ref, TDF_NONE, true);
}
DEBUG_FUNCTION void
else
fprintf (stderr, "<nil>\n");
}
+
+static void
+debug_slim (edge e)
+{
+ fprintf (stderr, "<edge 0x%p (%d -> %d)>", (void *) e,
+ e->src->index, e->dest->index);
+}
+
+DEFINE_DEBUG_VEC (edge)
+DEFINE_DEBUG_HASH_SET (edge)
\f
/* Simple routines to easily allocate AUX fields of basic blocks. */
fputs (", count ", outf);
bb->count.dump (outf);
}
- fprintf (outf, ", freq %i", bb->frequency);
if (maybe_hot_bb_p (fun, bb))
fputs (", maybe hot", outf);
if (probably_never_executed_bb_p (fun, bb))
}
}
-/* An edge originally destinating BB of FREQUENCY and COUNT has been proved to
+/* An edge originally destinating BB of COUNT has been proved to
leave the block by TAKEN_EDGE. Update profile of BB such that edge E can be
redirected to destination of TAKEN_EDGE.
This function may leave the profile inconsistent in the case TAKEN_EDGE
- frequency or count is believed to be lower than FREQUENCY or COUNT
+ frequency or count is believed to be lower than COUNT
respectively. */
void
-update_bb_profile_for_threading (basic_block bb, int edge_frequency,
+update_bb_profile_for_threading (basic_block bb,
profile_count count, edge taken_edge)
{
edge c;
}
bb->count -= count;
- bb->frequency -= edge_frequency;
- if (bb->frequency < 0)
- bb->frequency = 0;
-
/* Compute the probability of TAKEN_EDGE being reached via threaded edge.
Watch for overflows. */
- if (bb->frequency)
- /* FIXME: We should get edge frequency as count. */
- prob = profile_probability::probability_in_gcov_type
- (edge_frequency, bb->frequency);
+ if (bb->count.nonzero_p ())
+ prob = count.probability_in (bb->count);
else
prob = profile_probability::never ();
if (prob > taken_edge->probability)
if (prob == profile_probability::never ())
{
if (dump_file)
- fprintf (dump_file, "Edge frequencies of bb %i has been reset, "
- "frequency of block should end up being 0, it is %i\n",
- bb->index, bb->frequency);
+ fprintf (dump_file, "Edge probabilities of bb %i has been reset, "
+ "count of block should end up being 0, it is non-zero\n",
+ bb->index);
EDGE_SUCC (bb, 0)->probability = profile_probability::guessed_always ();
ei = ei_start (bb->succs);
ei_next (&ei);
gcc_assert (bb == taken_edge->src);
}
-/* Multiply all frequencies of basic blocks in array BBS of length NBBS
- by NUM/DEN, in int arithmetic. May lose some accuracy. */
-void
-scale_bbs_frequencies_int (basic_block *bbs, int nbbs, int num, int den)
-{
- int i;
- if (num < 0)
- num = 0;
-
- /* Scale NUM and DEN to avoid overflows. Frequencies are in order of
- 10^4, if we make DEN <= 10^3, we can afford to upscale by 100
- and still safely fit in int during calculations. */
- if (den > 1000)
- {
- if (num > 1000000)
- return;
-
- num = RDIV (1000 * num, den);
- den = 1000;
- }
- if (num > 100 * den)
- return;
-
- for (i = 0; i < nbbs; i++)
- {
- bbs[i]->frequency = RDIV (bbs[i]->frequency * num, den);
- /* Make sure the frequencies do not grow over BB_FREQ_MAX. */
- if (bbs[i]->frequency > BB_FREQ_MAX)
- bbs[i]->frequency = BB_FREQ_MAX;
- bbs[i]->count = bbs[i]->count.apply_scale (num, den);
- }
-}
-
-/* numbers smaller than this value are safe to multiply without getting
- 64bit overflow. */
-#define MAX_SAFE_MULTIPLIER (1 << (sizeof (int64_t) * 4 - 1))
-
-/* Multiply all frequencies of basic blocks in array BBS of length NBBS
- by NUM/DEN, in gcov_type arithmetic. More accurate than previous
- function but considerably slower. */
-void
-scale_bbs_frequencies_gcov_type (basic_block *bbs, int nbbs, gcov_type num,
- gcov_type den)
-{
- int i;
- gcov_type fraction = RDIV (num * 65536, den);
-
- gcc_assert (fraction >= 0);
-
- if (num < MAX_SAFE_MULTIPLIER)
- for (i = 0; i < nbbs; i++)
- {
- bbs[i]->frequency = RDIV (bbs[i]->frequency * num, den);
- if (bbs[i]->count <= MAX_SAFE_MULTIPLIER)
- bbs[i]->count = bbs[i]->count.apply_scale (num, den);
- else
- bbs[i]->count = bbs[i]->count.apply_scale (fraction, 65536);
- }
- else
- for (i = 0; i < nbbs; i++)
- {
- if (sizeof (gcov_type) > sizeof (int))
- bbs[i]->frequency = RDIV (bbs[i]->frequency * num, den);
- else
- bbs[i]->frequency = RDIV (bbs[i]->frequency * fraction, 65536);
- bbs[i]->count = bbs[i]->count.apply_scale (fraction, 65536);
- }
-}
-
/* Multiply all frequencies of basic blocks in array BBS of length NBBS
by NUM/DEN, in profile_count arithmetic. More accurate than previous
function but considerably slower. */
profile_count num, profile_count den)
{
int i;
-
- for (i = 0; i < nbbs; i++)
- {
- bbs[i]->frequency = RDIV (bbs[i]->frequency * num.to_gcov_type (),
- den.to_gcov_type ());
+ if (num == profile_count::zero () || den.nonzero_p ())
+ for (i = 0; i < nbbs; i++)
bbs[i]->count = bbs[i]->count.apply_scale (num, den);
- }
}
/* Multiply all frequencies of basic blocks in array BBS of length NBBS
int i;
for (i = 0; i < nbbs; i++)
- {
- bbs[i]->frequency = p.apply (bbs[i]->frequency);
- bbs[i]->count = bbs[i]->count.apply_probability (p);
- }
+ bbs[i]->count = bbs[i]->count.apply_probability (p);
}
/* Helper types for hash tables. */