};
/* Maximum frequency and count of one of the entry blocks. */
-static int max_entry_frequency;
static profile_count max_entry_count;
/* Local function prototypes. */
-static void find_traces (int *, struct trace *);
-static basic_block rotate_loop (edge, struct trace *, int);
-static void mark_bb_visited (basic_block, int);
-static void find_traces_1_round (int, int, gcov_type, struct trace *, int *,
+static void find_traces_1_round (int, profile_count, struct trace *, int *,
int, bb_heap_t **, int);
static basic_block copy_bb (basic_block, edge, basic_block, int);
static long bb_to_key (basic_block);
static bool better_edge_p (const_basic_block, const_edge, profile_probability,
int, profile_probability, int, const_edge);
-static bool connect_better_edge_p (const_edge, bool, int, const_edge,
- struct trace *);
-static void connect_traces (int, struct trace *);
static bool copy_bb_p (const_basic_block, int);
-static bool push_to_next_round_p (const_basic_block, int, int, int, gcov_type);
\f
/* Return the trace number in which BB was visited. */
static bool
push_to_next_round_p (const_basic_block bb, int round, int number_of_rounds,
- int exec_th, gcov_type count_th)
+ profile_count count_th)
{
bool there_exists_another_round;
bool block_not_hot_enough;
there_exists_another_round = round < number_of_rounds - 1;
- block_not_hot_enough = (bb->count.to_frequency (cfun) < exec_th
- || bb->count.ipa () < count_th
+ block_not_hot_enough = (bb->count < count_th
|| probably_never_executed_bb_p (cfun, bb));
if (there_exists_another_round
number_of_rounds = N_ROUNDS - 1;
/* Insert entry points of function into heap. */
- max_entry_frequency = 0;
max_entry_count = profile_count::zero ();
FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
{
bbd[e->dest->index].heap = heap;
bbd[e->dest->index].node = heap->insert (bb_to_key (e->dest), e->dest);
- if (e->dest->count.to_frequency (cfun) > max_entry_frequency)
- max_entry_frequency = e->dest->count.to_frequency (cfun);
- if (e->dest->count.ipa_p () && e->dest->count > max_entry_count)
+ if (e->dest->count > max_entry_count)
max_entry_count = e->dest->count;
}
/* Find the traces. */
for (i = 0; i < number_of_rounds; i++)
{
- gcov_type count_threshold;
+ profile_count count_threshold;
if (dump_file)
fprintf (dump_file, "STC - round %d\n", i + 1);
- if (max_entry_count < INT_MAX / 1000)
- count_threshold = max_entry_count.to_gcov_type () * exec_threshold[i] / 1000;
- else
- count_threshold = max_entry_count.to_gcov_type () / 1000 * exec_threshold[i];
+ count_threshold = max_entry_count.apply_scale (exec_threshold[i], 1000);
find_traces_1_round (REG_BR_PROB_BASE * branch_threshold[i] / 1000,
- max_entry_frequency * exec_threshold[i] / 1000,
count_threshold, traces, n_traces, i, &heap,
number_of_rounds);
}
/* Information about the best end (end after rotation) of the loop. */
basic_block best_bb = NULL;
edge best_edge = NULL;
- int best_freq = -1;
profile_count best_count = profile_count::uninitialized ();
/* The best edge is preferred when its destination is not visited yet
or is a start block of some trace. */
|| bbd[e->dest->index].start_of_trace >= 0)
{
/* The current edge E is also preferred. */
- int freq = EDGE_FREQUENCY (e);
- if (freq > best_freq || e->count () > best_count)
+ if (e->count () > best_count)
{
- best_freq = freq;
- if (e->count ().initialized_p ())
- best_count = e->count ();
+ best_count = e->count ();
best_edge = e;
best_bb = bb;
}
{
/* The current edge E is preferred. */
is_preferred = true;
- best_freq = EDGE_FREQUENCY (e);
best_count = e->count ();
best_edge = e;
best_bb = bb;
}
else
{
- int freq = EDGE_FREQUENCY (e);
- if (!best_edge || freq > best_freq || e->count () > best_count)
+ if (!best_edge || e->count () > best_count)
{
- best_freq = freq;
best_count = e->count ();
best_edge = e;
best_bb = bb;
*HEAP and store starting points for the next round into new *HEAP. */
static void
-find_traces_1_round (int branch_th, int exec_th, gcov_type count_th,
+find_traces_1_round (int branch_th, profile_count count_th,
struct trace *traces, int *n_traces, int round,
bb_heap_t **heap, int number_of_rounds)
{
round. When optimizing for size, do not push to next round. */
if (!for_size
- && push_to_next_round_p (bb, round, number_of_rounds, exec_th,
+ && push_to_next_round_p (bb, round, number_of_rounds,
count_th))
{
int key = bb_to_key (bb);
if (!(e->flags & EDGE_CAN_FALLTHRU) || (e->flags & EDGE_COMPLEX)
|| !prob.initialized_p ()
|| ((prob.to_reg_br_prob_base () < branch_th
- || EDGE_FREQUENCY (e) < exec_th
- || e->count ().ipa () < count_th) && (!for_size)))
+ || e->count () < count_th) && (!for_size)))
continue;
if (better_edge_p (bb, e, prob, freq, best_prob, best_freq,
bb_heap_t *which_heap = *heap;
prob = e->probability;
- freq = EDGE_FREQUENCY (e);
if (!(e->flags & EDGE_CAN_FALLTHRU)
|| (e->flags & EDGE_COMPLEX)
|| !prob.initialized_p ()
|| prob.to_reg_br_prob_base () < branch_th
- || freq < exec_th
- || e->count ().ipa () < count_th)
+ || e->count () < count_th)
{
/* When partitioning hot/cold basic blocks, make sure
the cold blocks (and only the cold blocks) all get
if (!for_size && push_to_next_round_p (e->dest, round,
number_of_rounds,
- exec_th, count_th))
+ count_th))
which_heap = new_heap;
}
/* We do nothing with one basic block loops. */
if (best_edge->dest != bb)
{
- if (EDGE_FREQUENCY (best_edge)
- > 4 * best_edge->dest->count.to_frequency (cfun) / 5)
+ if (best_edge->count ()
+ > best_edge->dest->count.apply_scale (4, 5))
{
/* The loop has at least 4 iterations. If the loop
header is not the first block of the function
C
where
- EDGE_FREQUENCY (AB) + EDGE_FREQUENCY (BC)
- >= EDGE_FREQUENCY (AC).
- (i.e. 2 * B->frequency >= EDGE_FREQUENCY (AC) )
+ AB->count () + BC->count () >= AC->count ().
+ (i.e. 2 * B->count >= AC->count )
Best ordering is then A B C.
When optimizing for size, A B C is always the best order.
& EDGE_CAN_FALLTHRU)
&& !(single_succ_edge (e->dest)->flags & EDGE_COMPLEX)
&& single_succ (e->dest) == best_edge->dest
- && (2 * e->dest->count.to_frequency (cfun)
- >= EDGE_FREQUENCY (best_edge) || for_size))
+ && (e->dest->count.apply_scale (2, 1)
+ >= best_edge->count () || for_size))
{
best_edge = e;
if (dump_file)
int last_trace;
int current_pass;
int current_partition;
- int freq_threshold;
- gcov_type count_threshold;
+ profile_count count_threshold;
bool for_size = optimize_function_for_size_p (cfun);
- freq_threshold = max_entry_frequency * DUPLICATION_THRESHOLD / 1000;
- if (max_entry_count.to_gcov_type () < INT_MAX / 1000)
- count_threshold = max_entry_count.to_gcov_type () * DUPLICATION_THRESHOLD / 1000;
- else
- count_threshold = max_entry_count.to_gcov_type () / 1000 * DUPLICATION_THRESHOLD;
+ count_threshold = max_entry_count.apply_scale (DUPLICATION_THRESHOLD, 1000);
connected = XCNEWVEC (bool, n_traces);
last_trace = -1;
&& bbd[di].start_of_trace >= 0
&& !connected[bbd[di].start_of_trace]
&& BB_PARTITION (e2->dest) == current_partition
- && EDGE_FREQUENCY (e2) >= freq_threshold
- && e2->count ().ipa () >= count_threshold
+ && e2->count () >= count_threshold
&& (!best2
|| e2->probability > best2->probability
|| (e2->probability == best2->probability
&& BB_PARTITION (best->src) == BB_PARTITION (best->dest)
&& copy_bb_p (best->dest,
optimize_edge_for_speed_p (best)
- && EDGE_FREQUENCY (best) >= freq_threshold
&& (!best->count ().initialized_p ()
- || best->count ().ipa () >= count_threshold)))
+ || best->count () >= count_threshold)))
{
basic_block new_bb;
static bool
edge_order (edge e1, edge e2)
{
- return EDGE_FREQUENCY (e1) > EDGE_FREQUENCY (e2);
+ return e1->count () > e2->count ();
}
/* Reorder basic blocks using the "simple" algorithm. This tries to