summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authortejohnson <tejohnson@138bc75d-0d04-0410-961f-82ee72b054a4>2013-04-08 17:39:10 +0000
committertejohnson <tejohnson@138bc75d-0d04-0410-961f-82ee72b054a4>2013-04-08 17:39:10 +0000
commitf9d4b7f4943df04e4362f7cde1fb6c6de22283ef (patch)
treeffb943825496db918422c6ebe357dcdcc5207a4b /gcc
parent3f4737cd41c1ae5451f9bd34414d33b3214d6dec (diff)
downloadgcc-f9d4b7f4943df04e4362f7cde1fb6c6de22283ef.tar.gz
First phase of unifying the computation of profile scale factors/probabilities
and the actual scaling to use rounding divides: - Add new macro GCOV_COMPUTE_SCALE to basic-block.h to compute the scale factor/probability via a rounding divide. - Change all locations that already perform rounding divides (inline or via RDIV) to use the appropriate helper: GCOV_COMPUTE_SCALE, apply_probability or combine_probabilities. - Change ipa-cp.c truncating divides to use rounding divides. - Add comments to all other locations (currently using truncating divides) to switch them to one of the helpers so they use a rounding divide. Next phase will be to replace the locations using truncating divides, marked with a comment here, into rounding divides via the helper methods. 2013-04-08 Teresa Johnson <tejohnson@google.com> * basic-block.h (GCOV_COMPUTE_SCALE): Define. * ipa-inline-analysis.c (param_change_prob): Use helper rounding divide methods. (estimate_edge_size_and_time): Add comment to suggest using rounding methods. (estimate_node_size_and_time): Ditto. (remap_edge_change_prob): Use helper rounding divide methods. * value-prof.c (gimple_divmod_fixed_value_transform): Ditto. (gimple_mod_pow2_value_transform): Ditto. (gimple_mod_subtract_transform): Ditto. (gimple_ic_transform): Ditto. (gimple_stringops_transform): Ditto. * stmt.c (conditional_probability): Ditto. (emit_case_dispatch_table): Ditto. * lto-cgraph.c (merge_profile_summaries): Ditto. * tree-optimize.c (execute_fixup_cfg): Ditto. * cfgcleanup.c (try_forward_edges): Ditto. * cfgloopmanip.c (scale_loop_profile): Ditto. (loopify): Ditto. (duplicate_loop_to_header_edge): Ditto. (lv_adjust_loop_entry_edge): Ditto. * tree-vect-loop.c (vect_transform_loop): Ditto. * profile.c (compute_branch_probabilities): Ditto. * cfgbuild.c (compute_outgoing_frequencies): Ditto. * lto-streamer-in.c (input_cfg): Ditto. * gimple-streamer-in.c (input_bb): Ditto. * ipa-cp.c (update_profiling_info): Ditto. (update_specialized_profile): Ditto. * tree-vect-loop-manip.c (slpeel_tree_peel_loop_to_edge): Ditto. * cfg.c (update_bb_profile_for_threading): Add comment to suggest using rounding methods. * sched-rgn.c (compute_dom_prob_ps): Ditto. (compute_trg_info): Ditto. * cfgrtl.c (force_nonfallthru_and_redirect): Ditto. (purge_dead_edges): Ditto. * loop-unswitch.c (unswitch_loop): Ditto. * cgraphclones.c (cgraph_clone_edge): Ditto. (cgraph_clone_node): Ditto. * tree-inline.c (copy_bb): Ditto. (copy_edges_for_bb): Ditto. (initialize_cfun): Ditto. (copy_cfg_body): Ditto. (expand_call_inline): Ditto. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@197595 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog46
-rw-r--r--gcc/basic-block.h5
-rw-r--r--gcc/cfg.c1
-rw-r--r--gcc/cfgbuild.c6
-rw-r--r--gcc/cfgcleanup.c4
-rw-r--r--gcc/cfgloopmanip.c35
-rw-r--r--gcc/cfgrtl.c2
-rw-r--r--gcc/cgraphclones.c2
-rw-r--r--gcc/gimple-streamer-in.c4
-rw-r--r--gcc/ipa-cp.c19
-rw-r--r--gcc/ipa-inline-analysis.c12
-rw-r--r--gcc/loop-unswitch.c2
-rw-r--r--gcc/lto-cgraph.c29
-rw-r--r--gcc/lto-streamer-in.c4
-rw-r--r--gcc/profile.c2
-rw-r--r--gcc/sched-rgn.c2
-rw-r--r--gcc/stmt.c4
-rw-r--r--gcc/tree-inline.c8
-rw-r--r--gcc/tree-optimize.c22
-rw-r--r--gcc/tree-vect-loop-manip.c4
-rw-r--r--gcc/tree-vect-loop.c2
-rw-r--r--gcc/value-prof.c12
22 files changed, 147 insertions, 80 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index efe75f0870b..a7ca0455c5c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,49 @@
+2013-04-08 Teresa Johnson <tejohnson@google.com>
+
+ * basic-block.h (GCOV_COMPUTE_SCALE): Define.
+ * ipa-inline-analysis.c (param_change_prob): Use helper rounding divide
+ methods.
+ (estimate_edge_size_and_time): Add comment to suggest using rounding
+ methods.
+ (estimate_node_size_and_time): Ditto.
+ (remap_edge_change_prob): Use helper rounding divide methods.
+ * value-prof.c (gimple_divmod_fixed_value_transform): Ditto.
+ (gimple_mod_pow2_value_transform): Ditto.
+ (gimple_mod_subtract_transform): Ditto.
+ (gimple_ic_transform): Ditto.
+ (gimple_stringops_transform): Ditto.
+ * stmt.c (conditional_probability): Ditto.
+ (emit_case_dispatch_table): Ditto.
+ * lto-cgraph.c (merge_profile_summaries): Ditto.
+ * tree-optimize.c (execute_fixup_cfg): Ditto.
+ * cfgcleanup.c (try_forward_edges): Ditto.
+ * cfgloopmanip.c (scale_loop_profile): Ditto.
+ (loopify): Ditto.
+ (duplicate_loop_to_header_edge): Ditto.
+ (lv_adjust_loop_entry_edge): Ditto.
+ * tree-vect-loop.c (vect_transform_loop): Ditto.
+ * profile.c (compute_branch_probabilities): Ditto.
+ * cfgbuild.c (compute_outgoing_frequencies): Ditto.
+ * lto-streamer-in.c (input_cfg): Ditto.
+ * gimple-streamer-in.c (input_bb): Ditto.
+ * ipa-cp.c (update_profiling_info): Ditto.
+ (update_specialized_profile): Ditto.
+ * tree-vect-loop-manip.c (slpeel_tree_peel_loop_to_edge): Ditto.
+ * cfg.c (update_bb_profile_for_threading): Add comment to suggest using
+ rounding methods.
+ * sched-rgn.c (compute_dom_prob_ps): Ditto.
+ (compute_trg_info): Ditto.
+ * cfgrtl.c (force_nonfallthru_and_redirect): Ditto.
+ (purge_dead_edges): Ditto.
+ * loop-unswitch.c (unswitch_loop): Ditto.
+ * cgraphclones.c (cgraph_clone_edge): Ditto.
+ (cgraph_clone_node): Ditto.
+ * tree-inline.c (copy_bb): Ditto.
+ (copy_edges_for_bb): Ditto.
+ (initialize_cfun): Ditto.
+ (copy_cfg_body): Ditto.
+ (expand_call_inline): Ditto.
+
2013-04-08 Kai Tietz <ktietz@redhat.com>
* config/i386/cygwin.h (EXTRA_OS_CPP_BUILTINS): Replaced
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index d8377308b7f..9b5192eb877 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -499,6 +499,11 @@ struct edge_list
#define EDGE_FREQUENCY(e) RDIV ((e)->src->frequency * (e)->probability, \
REG_BR_PROB_BASE)
+/* Compute a scale factor (or probability) suitable for scaling of
+ gcov_type values via apply_probability(). */
+#define GCOV_COMPUTE_SCALE(num,den) \
+ ((den) ? RDIV ((num) * REG_BR_PROB_BASE, (den)) : REG_BR_PROB_BASE)
+
/* Return nonzero if edge is critical. */
#define EDGE_CRITICAL_P(e) (EDGE_COUNT ((e)->src->succs) >= 2 \
&& EDGE_COUNT ((e)->dest->preds) >= 2)
diff --git a/gcc/cfg.c b/gcc/cfg.c
index 0c1e425a00d..2bcd790d306 100644
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -848,6 +848,7 @@ update_bb_profile_for_threading (basic_block bb, int edge_frequency,
/* Compute the probability of TAKEN_EDGE being reached via threaded edge.
Watch for overflows. */
if (bb->frequency)
+ /* Update to use GCOV_COMPUTE_SCALE. */
prob = edge_frequency * REG_BR_PROB_BASE / bb->frequency;
else
prob = 0;
diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c
index 1e0121dbc02..ac6aefb86df 100644
--- a/gcc/cfgbuild.c
+++ b/gcc/cfgbuild.c
@@ -545,8 +545,7 @@ compute_outgoing_frequencies (basic_block b)
probability = INTVAL (XEXP (note, 0));
e = BRANCH_EDGE (b);
e->probability = probability;
- e->count = ((b->count * probability + REG_BR_PROB_BASE / 2)
- / REG_BR_PROB_BASE);
+ e->count = apply_probability (b->count, probability);
f = FALLTHRU_EDGE (b);
f->probability = REG_BR_PROB_BASE - probability;
f->count = b->count - e->count;
@@ -583,8 +582,7 @@ compute_outgoing_frequencies (basic_block b)
if (b->count)
FOR_EACH_EDGE (e, ei, b->succs)
- e->count = ((b->count * e->probability + REG_BR_PROB_BASE / 2)
- / REG_BR_PROB_BASE);
+ e->count = apply_probability (b->count, e->probability);
}
/* Assume that some pass has inserted labels or control flow
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 471d293f12f..2fcefc60b23 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -595,9 +595,7 @@ try_forward_edges (int mode, basic_block b)
/* We successfully forwarded the edge. Now update profile
data: for each edge we traversed in the chain, remove
the original edge's execution count. */
- edge_frequency = ((edge_probability * b->frequency
- + REG_BR_PROB_BASE / 2)
- / REG_BR_PROB_BASE);
+ edge_frequency = apply_probability (b->frequency, edge_probability);
do
{
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 3e53aa0dddf..13efb7515f9 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -502,7 +502,7 @@ scale_loop_profile (struct loop *loop, int scale, gcov_type iteration_bound)
/* See if loop is predicted to iterate too many times. */
if (iteration_bound && iterations > 0
- && RDIV (iterations * scale, REG_BR_PROB_BASE) > iteration_bound)
+ && apply_probability (iterations, scale) > iteration_bound)
{
/* Fixing loop profile for different trip count is not trivial; the exit
probabilities has to be updated to match and frequencies propagated down
@@ -563,7 +563,8 @@ scale_loop_profile (struct loop *loop, int scale, gcov_type iteration_bound)
count_in += e->count;
if (count_in != 0)
- scale = RDIV (count_in * iteration_bound * REG_BR_PROB_BASE, loop->header->count);
+ scale = GCOV_COMPUTE_SCALE (count_in * iteration_bound,
+ loop->header->count);
}
else if (loop->header->frequency)
{
@@ -574,7 +575,8 @@ scale_loop_profile (struct loop *loop, int scale, gcov_type iteration_bound)
freq_in += EDGE_FREQUENCY (e);
if (freq_in != 0)
- scale = RDIV (freq_in * iteration_bound * REG_BR_PROB_BASE, loop->header->frequency);
+ scale = GCOV_COMPUTE_SCALE (freq_in * iteration_bound,
+ loop->header->frequency);
}
if (!scale)
scale = 1;
@@ -890,7 +892,7 @@ loopify (edge latch_edge, edge header_edge,
switch_bb->count = cnt;
FOR_EACH_EDGE (e, ei, switch_bb->succs)
{
- e->count = RDIV (switch_bb->count * e->probability, REG_BR_PROB_BASE);
+ e->count = apply_probability (switch_bb->count, e->probability);
}
}
scale_loop_frequencies (loop, false_scale, REG_BR_PROB_BASE);
@@ -1199,8 +1201,9 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e,
{
/* The blocks that are dominated by a removed exit edge ORIG have
frequencies scaled by this. */
- scale_after_exit = RDIV (REG_BR_PROB_BASE * REG_BR_PROB_BASE,
- REG_BR_PROB_BASE - orig->probability);
+ scale_after_exit
+ = GCOV_COMPUTE_SCALE (REG_BR_PROB_BASE,
+ REG_BR_PROB_BASE - orig->probability);
bbs_to_scale = BITMAP_ALLOC (NULL);
for (i = 0; i < n; i++)
{
@@ -1231,12 +1234,12 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e,
frequency should be reduced by prob_pass_wont_exit. Caller
should've managed the flags so all except for original loop
has won't exist set. */
- scale_act = RDIV (wanted_freq * REG_BR_PROB_BASE, freq_in);
+ scale_act = GCOV_COMPUTE_SCALE (wanted_freq, freq_in);
/* Now simulate the duplication adjustments and compute header
frequency of the last copy. */
for (i = 0; i < ndupl; i++)
- wanted_freq = RDIV (wanted_freq * scale_step[i], REG_BR_PROB_BASE);
- scale_main = RDIV (wanted_freq * REG_BR_PROB_BASE, freq_in);
+ wanted_freq = combine_probabilities (wanted_freq, scale_step[i]);
+ scale_main = GCOV_COMPUTE_SCALE (wanted_freq, freq_in);
}
else if (is_latch)
{
@@ -1248,16 +1251,16 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e,
for (i = 0; i < ndupl; i++)
{
scale_main += p;
- p = RDIV (p * scale_step[i], REG_BR_PROB_BASE);
+ p = combine_probabilities (p, scale_step[i]);
}
- scale_main = RDIV (REG_BR_PROB_BASE * REG_BR_PROB_BASE, scale_main);
- scale_act = RDIV (scale_main * prob_pass_main, REG_BR_PROB_BASE);
+ scale_main = GCOV_COMPUTE_SCALE (REG_BR_PROB_BASE, scale_main);
+ scale_act = combine_probabilities (scale_main, prob_pass_main);
}
else
{
scale_main = REG_BR_PROB_BASE;
for (i = 0; i < ndupl; i++)
- scale_main = RDIV (scale_main * scale_step[i], REG_BR_PROB_BASE);
+ scale_main = combine_probabilities (scale_main, scale_step[i]);
scale_act = REG_BR_PROB_BASE - prob_pass_thru;
}
for (i = 0; i < ndupl; i++)
@@ -1378,7 +1381,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e,
if (flags & DLTHE_FLAG_UPDATE_FREQ)
{
scale_bbs_frequencies_int (new_bbs, n, scale_act, REG_BR_PROB_BASE);
- scale_act = RDIV (scale_act * scale_step[j], REG_BR_PROB_BASE);
+ scale_act = combine_probabilities (scale_act, scale_step[j]);
}
}
free (new_bbs);
@@ -1638,8 +1641,8 @@ lv_adjust_loop_entry_edge (basic_block first_head, basic_block second_head,
current_ir_type () == IR_GIMPLE ? EDGE_TRUE_VALUE : 0);
e1->probability = then_prob;
e->probability = REG_BR_PROB_BASE - then_prob;
- e1->count = RDIV (e->count * e1->probability, REG_BR_PROB_BASE);
- e->count = RDIV (e->count * e->probability, REG_BR_PROB_BASE);
+ e1->count = apply_probability (e->count, e1->probability);
+ e->count = apply_probability (e->count, e->probability);
set_immediate_dominator (CDI_DOMINATORS, first_head, new_head);
set_immediate_dominator (CDI_DOMINATORS, second_head, new_head);
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index f0ec70c41da..6e8a31d95da 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -1362,6 +1362,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)
int prob = INTVAL (XEXP (note, 0));
b->probability = prob;
+ /* Update this to use GCOV_COMPUTE_SCALE. */
b->count = e->count * prob / REG_BR_PROB_BASE;
e->probability -= e->probability;
e->count -= b->count;
@@ -2675,6 +2676,7 @@ purge_dead_edges (basic_block bb)
f = FALLTHRU_EDGE (bb);
b->probability = INTVAL (XEXP (note, 0));
f->probability = REG_BR_PROB_BASE - b->probability;
+ /* Update these to use GCOV_COMPUTE_SCALE. */
b->count = bb->count * b->probability / REG_BR_PROB_BASE;
f->count = bb->count * f->probability / REG_BR_PROB_BASE;
}
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index 3a2e3d679e2..fa6a9113a1e 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -102,6 +102,7 @@ cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
int freq_scale, bool update_original)
{
struct cgraph_edge *new_edge;
+ /* Update this to use GCOV_COMPUTE_SCALE. */
gcov_type count = e->count * count_scale / REG_BR_PROB_BASE;
gcov_type freq;
@@ -204,6 +205,7 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
if (new_node->count > n->count)
count_scale = REG_BR_PROB_BASE;
else
+ /* Update to use GCOV_COMPUTE_SCALE. */
count_scale = new_node->count * REG_BR_PROB_BASE / n->count;
}
else
diff --git a/gcc/gimple-streamer-in.c b/gcc/gimple-streamer-in.c
index cedacb6642c..a27f0d6d62f 100644
--- a/gcc/gimple-streamer-in.c
+++ b/gcc/gimple-streamer-in.c
@@ -329,8 +329,8 @@ input_bb (struct lto_input_block *ib, enum LTO_tags tag,
index = streamer_read_uhwi (ib);
bb = BASIC_BLOCK_FOR_FUNCTION (fn, index);
- bb->count = (streamer_read_gcov_count (ib) * count_materialization_scale
- + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
+ bb->count = apply_probability (streamer_read_gcov_count (ib),
+ count_materialization_scale);
bb->frequency = streamer_read_hwi (ib);
bb->flags = streamer_read_hwi (ib);
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index aac21ceb6fa..0ca25d286f4 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -2572,14 +2572,16 @@ update_profiling_info (struct cgraph_node *orig_node,
for (cs = new_node->callees; cs ; cs = cs->next_callee)
if (cs->frequency)
- cs->count = cs->count * (new_sum * REG_BR_PROB_BASE
- / orig_node_count) / REG_BR_PROB_BASE;
+ cs->count = apply_probability (cs->count,
+ GCOV_COMPUTE_SCALE (new_sum,
+ orig_node_count));
else
cs->count = 0;
for (cs = orig_node->callees; cs ; cs = cs->next_callee)
- cs->count = cs->count * (remainder * REG_BR_PROB_BASE
- / orig_node_count) / REG_BR_PROB_BASE;
+ cs->count = apply_probability (cs->count,
+ GCOV_COMPUTE_SCALE (remainder,
+ orig_node_count));
if (dump_file)
dump_profile_updates (orig_node, new_node);
@@ -2611,14 +2613,17 @@ update_specialized_profile (struct cgraph_node *new_node,
for (cs = new_node->callees; cs ; cs = cs->next_callee)
if (cs->frequency)
- cs->count += cs->count * redirected_sum / new_node_count;
+ cs->count += apply_probability (cs->count,
+ GCOV_COMPUTE_SCALE (redirected_sum,
+ new_node_count));
else
cs->count = 0;
for (cs = orig_node->callees; cs ; cs = cs->next_callee)
{
- gcov_type dec = cs->count * (redirected_sum * REG_BR_PROB_BASE
- / orig_node_count) / REG_BR_PROB_BASE;
+ gcov_type dec = apply_probability (cs->count,
+ GCOV_COMPUTE_SCALE (redirected_sum,
+ orig_node_count));
if (dec < cs->count)
cs->count -= dec;
else
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 53439333c90..138433cdf1a 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -2093,8 +2093,7 @@ param_change_prob (gimple stmt, int i)
if (!init_freq)
init_freq = 1;
if (init_freq < bb->frequency)
- return MAX ((init_freq * REG_BR_PROB_BASE +
- bb->frequency / 2) / bb->frequency, 1);
+ return MAX (GCOV_COMPUTE_SCALE (init_freq, bb->frequency), 1);
else
return REG_BR_PROB_BASE;
}
@@ -2136,8 +2135,7 @@ param_change_prob (gimple stmt, int i)
BITMAP_FREE (info.bb_set);
if (max < bb->frequency)
- return MAX ((max * REG_BR_PROB_BASE +
- bb->frequency / 2) / bb->frequency, 1);
+ return MAX (GCOV_COMPUTE_SCALE (max, bb->frequency), 1);
else
return REG_BR_PROB_BASE;
}
@@ -2792,6 +2790,7 @@ estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *time,
&& hints && cgraph_maybe_hot_edge_p (e))
*hints |= INLINE_HINT_indirect_call;
*size += call_size * INLINE_SIZE_SCALE;
+ /* Update to use apply_probability(). */
*time += call_time * prob / REG_BR_PROB_BASE
* e->frequency * (INLINE_TIME_SCALE / CGRAPH_FREQ_BASE);
if (*time > MAX_TIME * INLINE_TIME_SCALE)
@@ -2902,6 +2901,7 @@ estimate_node_size_and_time (struct cgraph_node *node,
inline_param_summary);
gcc_checking_assert (prob >= 0);
gcc_checking_assert (prob <= REG_BR_PROB_BASE);
+ /* Update to use apply_probability(). */
time += ((gcov_type) e->time * prob) / REG_BR_PROB_BASE;
}
if (time > MAX_TIME * INLINE_TIME_SCALE)
@@ -3120,8 +3120,7 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge,
int jf_formal_id = ipa_get_jf_pass_through_formal_id (jfunc);
int prob1 = es->param[i].change_prob;
int prob2 = inlined_es->param[jf_formal_id].change_prob;
- int prob = ((prob1 * prob2 + REG_BR_PROB_BASE / 2)
- / REG_BR_PROB_BASE);
+ int prob = combine_probabilities (prob1, prob2);
if (prob1 && prob2 && !prob)
prob = 1;
@@ -3312,6 +3311,7 @@ inline_merge_summary (struct cgraph_edge *edge)
int prob = predicate_probability (callee_info->conds,
&e->predicate,
clause, es->param);
+ /* Update to use apply_probability(). */
add_time = ((gcov_type) add_time * prob) / REG_BR_PROB_BASE;
if (add_time > MAX_TIME * INLINE_TIME_SCALE)
add_time = MAX_TIME * INLINE_TIME_SCALE;
diff --git a/gcc/loop-unswitch.c b/gcc/loop-unswitch.c
index 6a12952cc99..e5f1bdc190b 100644
--- a/gcc/loop-unswitch.c
+++ b/gcc/loop-unswitch.c
@@ -436,9 +436,11 @@ unswitch_loop (struct loop *loop, basic_block unswitch_on, rtx cond, rtx cinsn)
emit_insn_after (seq, BB_END (switch_bb));
e = make_edge (switch_bb, true_edge->dest, 0);
e->probability = prob;
+ /* Update to use apply_probability(). */
e->count = latch_edge->count * prob / REG_BR_PROB_BASE;
e = make_edge (switch_bb, FALLTHRU_EDGE (unswitch_on)->dest, EDGE_FALLTHRU);
e->probability = false_edge->probability;
+ /* Update to use apply_probability(). */
e->count = latch_edge->count * (false_edge->probability) / REG_BR_PROB_BASE;
if (irred_flag)
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index ac92e90d7b5..69f5e3a659f 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -1343,14 +1343,14 @@ merge_profile_summaries (struct lto_file_decl_data **file_data_vec)
for (j = 0; (file_data = file_data_vec[j]) != NULL; j++)
if (file_data->profile_info.runs)
{
- int scale = RDIV (REG_BR_PROB_BASE * max_runs,
- file_data->profile_info.runs);
- lto_gcov_summary.sum_max = MAX (lto_gcov_summary.sum_max,
- RDIV (file_data->profile_info.sum_max
- * scale, REG_BR_PROB_BASE));
- lto_gcov_summary.sum_all = MAX (lto_gcov_summary.sum_all,
- RDIV (file_data->profile_info.sum_all
- * scale, REG_BR_PROB_BASE));
+ int scale = GCOV_COMPUTE_SCALE (max_runs,
+ file_data->profile_info.runs);
+ lto_gcov_summary.sum_max
+ = MAX (lto_gcov_summary.sum_max,
+ apply_probability (file_data->profile_info.sum_max, scale));
+ lto_gcov_summary.sum_all
+ = MAX (lto_gcov_summary.sum_all,
+ apply_probability (file_data->profile_info.sum_all, scale));
/* Save a pointer to the profile_info with the largest
scaled sum_all and the scale for use in merging the
histogram. */
@@ -1371,8 +1371,9 @@ merge_profile_summaries (struct lto_file_decl_data **file_data_vec)
{
/* Scale up the min value as we did the corresponding sum_all
above. Use that to find the new histogram index. */
- gcov_type scaled_min = RDIV (saved_profile_info->histogram[h_ix].min_value
- * saved_scale, REG_BR_PROB_BASE);
+ gcov_type scaled_min
+ = apply_probability (saved_profile_info->histogram[h_ix].min_value,
+ saved_scale);
/* The new index may be shared with another scaled histogram entry,
so we need to account for a non-zero histogram entry at new_ix. */
unsigned new_ix = gcov_histo_index (scaled_min);
@@ -1385,8 +1386,8 @@ merge_profile_summaries (struct lto_file_decl_data **file_data_vec)
here and place the scaled cumulative counter value in the bucket
corresponding to the scaled minimum counter value. */
lto_gcov_summary.histogram[new_ix].cum_value
- += RDIV (saved_profile_info->histogram[h_ix].cum_value
- * saved_scale, REG_BR_PROB_BASE);
+ += apply_probability (saved_profile_info->histogram[h_ix].cum_value,
+ saved_scale);
lto_gcov_summary.histogram[new_ix].num_counters
+= saved_profile_info->histogram[h_ix].num_counters;
}
@@ -1418,8 +1419,8 @@ merge_profile_summaries (struct lto_file_decl_data **file_data_vec)
if (scale == REG_BR_PROB_BASE)
continue;
for (edge = node->callees; edge; edge = edge->next_callee)
- edge->count = RDIV (edge->count * scale, REG_BR_PROB_BASE);
- node->count = RDIV (node->count * scale, REG_BR_PROB_BASE);
+ edge->count = apply_probability (edge->count, scale);
+ node->count = apply_probability (node->count, scale);
}
}
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 0e128fddd78..982d3574ee8 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -622,8 +622,8 @@ input_cfg (struct lto_input_block *ib, struct function *fn,
dest_index = streamer_read_uhwi (ib);
probability = (int) streamer_read_hwi (ib);
- count = ((gcov_type) streamer_read_gcov_count (ib) * count_materialization_scale
- + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
+ count = apply_probability ((gcov_type) streamer_read_gcov_count (ib),
+ count_materialization_scale);
edge_flags = streamer_read_uhwi (ib);
dest = BASIC_BLOCK_FOR_FUNCTION (fn, dest_index);
diff --git a/gcc/profile.c b/gcc/profile.c
index 4b8be4483c1..6f05581711c 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -752,7 +752,7 @@ compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum)
if (bb->count)
{
FOR_EACH_EDGE (e, ei, bb->succs)
- e->probability = (e->count * REG_BR_PROB_BASE + bb->count / 2) / bb->count;
+ e->probability = GCOV_COMPUTE_SCALE (e->count, bb->count);
if (bb->index >= NUM_FIXED_BLOCKS
&& block_ends_with_condjump_p (bb)
&& EDGE_COUNT (bb->succs) >= 2)
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index e8d32fd7eba..02a6705afc4 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -1441,6 +1441,7 @@ compute_dom_prob_ps (int bb)
FOR_EACH_EDGE (out_edge, out_ei, in_edge->src->succs)
bitmap_set_bit (pot_split[bb], EDGE_TO_BIT (out_edge));
+ /* Update to use apply_probability(). */
prob[bb] += ((prob[pred_bb] * in_edge->probability) / REG_BR_PROB_BASE);
}
@@ -1514,6 +1515,7 @@ compute_trg_info (int trg)
int tf = prob[trg], cf = prob[i];
/* In CFGs with low probability edges TF can possibly be zero. */
+ /* Update to use GCOV_COMPUTE_SCALE. */
sp->src_prob = (tf ? ((cf * REG_BR_PROB_BASE) / tf) : 0);
sp->is_valid = (sp->src_prob >= min_spec_prob);
}
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 5a6138bdd32..bada27cea04 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -1890,7 +1890,7 @@ conditional_probability (int target_prob, int base_prob)
{
gcc_assert (target_prob >= 0);
gcc_assert (target_prob <= base_prob);
- return RDIV (target_prob * REG_BR_PROB_BASE, base_prob);
+ return GCOV_COMPUTE_SCALE (target_prob, base_prob);
}
return -1;
}
@@ -2012,7 +2012,7 @@ emit_case_dispatch_table (tree index_expr, tree index_type,
edge e;
edge_iterator ei;
FOR_EACH_EDGE (e, ei, stmt_bb->succs)
- e->probability = RDIV (e->probability * REG_BR_PROB_BASE, base);
+ e->probability = GCOV_COMPUTE_SCALE (e->probability, base);
}
if (try_with_tablejump)
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index a41dd5aeb82..978db6ea006 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1521,10 +1521,12 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
basic_block_info automatically. */
copy_basic_block = create_basic_block (NULL, (void *) 0,
(basic_block) prev->aux);
+ /* Update to use apply_probability(). */
copy_basic_block->count = bb->count * count_scale / REG_BR_PROB_BASE;
/* We are going to rebuild frequencies from scratch. These values
have just small importance to drive canonicalize_loop_headers. */
+ /* Update to use EDGE_FREQUENCY. */
freq = ((gcov_type)bb->frequency * frequency_scale / REG_BR_PROB_BASE);
/* We recompute frequencies after inlining, so this is quite safe. */
@@ -1890,6 +1892,7 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb)
&& old_edge->dest->aux != EXIT_BLOCK_PTR)
flags |= EDGE_FALLTHRU;
new_edge = make_edge (new_bb, (basic_block) old_edge->dest->aux, flags);
+ /* Update to use apply_probability(). */
new_edge->count = old_edge->count * count_scale / REG_BR_PROB_BASE;
new_edge->probability = old_edge->probability;
}
@@ -2060,6 +2063,7 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count)
struct function *src_cfun = DECL_STRUCT_FUNCTION (callee_fndecl);
gcov_type count_scale;
+ /* Update to use GCOV_COMPUTE_SCALE. */
if (ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count)
count_scale = (REG_BR_PROB_BASE * count
/ ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count);
@@ -2207,6 +2211,7 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
int incoming_frequency = 0;
gcov_type incoming_count = 0;
+ /* Update to use GCOV_COMPUTE_SCALE. */
if (ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count)
count_scale = (REG_BR_PROB_BASE * count
/ ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count);
@@ -2231,7 +2236,9 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
incoming_frequency += EDGE_FREQUENCY (e);
incoming_count += e->count;
}
+ /* Update to use apply_probability(). */
incoming_count = incoming_count * count_scale / REG_BR_PROB_BASE;
+ /* Update to use EDGE_FREQUENCY. */
incoming_frequency
= incoming_frequency * frequency_scale / REG_BR_PROB_BASE;
ENTRY_BLOCK_PTR->count = incoming_count;
@@ -4051,6 +4058,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
a self-referential call; if we're calling ourselves, we need to
duplicate our body before altering anything. */
copy_body (id, bb->count,
+ /* Update to use GCOV_COMPUTE_SCALE. */
cg_edge->frequency * REG_BR_PROB_BASE / CGRAPH_FREQ_BASE,
bb, return_block, NULL, NULL);
diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c
index 3f69fb31094..a72369eb59e 100644
--- a/gcc/tree-optimize.c
+++ b/gcc/tree-optimize.c
@@ -126,25 +126,20 @@ execute_fixup_cfg (void)
edge e;
edge_iterator ei;
- if (ENTRY_BLOCK_PTR->count)
- count_scale = ((cgraph_get_node (current_function_decl)->count
- * REG_BR_PROB_BASE + ENTRY_BLOCK_PTR->count / 2)
- / ENTRY_BLOCK_PTR->count);
- else
- count_scale = REG_BR_PROB_BASE;
+ count_scale
+ = GCOV_COMPUTE_SCALE (cgraph_get_node (current_function_decl)->count,
+ ENTRY_BLOCK_PTR->count);
ENTRY_BLOCK_PTR->count = cgraph_get_node (current_function_decl)->count;
- EXIT_BLOCK_PTR->count = (EXIT_BLOCK_PTR->count * count_scale
- + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
+ EXIT_BLOCK_PTR->count = apply_probability (EXIT_BLOCK_PTR->count,
+ count_scale);
FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
- e->count = (e->count * count_scale
- + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
+ e->count = apply_probability (e->count, count_scale);
FOR_EACH_BB (bb)
{
- bb->count = (bb->count * count_scale
- + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
+ bb->count = apply_probability (bb->count, count_scale);
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple stmt = gsi_stmt (gsi);
@@ -177,8 +172,7 @@ execute_fixup_cfg (void)
}
FOR_EACH_EDGE (e, ei, bb->succs)
- e->count = (e->count * count_scale
- + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
+ e->count = apply_probability (e->count, count_scale);
/* If we have a basic block with no successors that does not
end with a control statement or a noreturn call end it with
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index a158c62112c..bff5c22130e 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -1236,8 +1236,8 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop,
same frequencies. Loop exit probablities are however easy to get wrong.
It is safer to copy value from original loop entry. */
bb_before_second_loop->frequency
- = apply_probability (bb_before_first_loop->frequency,
- probability_of_second_loop);
+ = combine_probabilities (bb_before_first_loop->frequency,
+ probability_of_second_loop);
bb_before_second_loop->count
= apply_probability (bb_before_first_loop->count,
probability_of_second_loop);
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 6874b65a67d..2fc20f38cfb 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -5761,7 +5761,7 @@ vect_transform_loop (loop_vec_info loop_vinfo)
slpeel_make_loop_iterate_ntimes (loop, ratio);
/* Reduce loop iterations by the vectorization factor. */
- scale_loop_profile (loop, RDIV (REG_BR_PROB_BASE , vectorization_factor),
+ scale_loop_profile (loop, GCOV_COMPUTE_SCALE (1, vectorization_factor),
expected_iterations / vectorization_factor);
loop->nb_iterations_upper_bound
= loop->nb_iterations_upper_bound.udiv (double_int::from_uhwi (vectorization_factor),
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 39bbdbf02e7..3348d7f58c8 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -802,7 +802,7 @@ gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si)
/* Compute probability of taking the optimal path. */
if (all > 0)
- prob = (count * REG_BR_PROB_BASE + all / 2) / all;
+ prob = GCOV_COMPUTE_SCALE (count, all);
else
prob = 0;
@@ -962,7 +962,7 @@ gimple_mod_pow2_value_transform (gimple_stmt_iterator *si)
return false;
if (all > 0)
- prob = (count * REG_BR_PROB_BASE + all / 2) / all;
+ prob = GCOV_COMPUTE_SCALE (count, all);
else
prob = 0;
@@ -1156,8 +1156,8 @@ gimple_mod_subtract_transform (gimple_stmt_iterator *si)
/* Compute probability of taking the optimal path(s). */
if (all > 0)
{
- prob1 = (count1 * REG_BR_PROB_BASE + all / 2) / all;
- prob2 = (count2 * REG_BR_PROB_BASE + all / 2) / all;
+ prob1 = GCOV_COMPUTE_SCALE (count1, all);
+ prob2 = GCOV_COMPUTE_SCALE (count2, all);
}
else
{
@@ -1430,7 +1430,7 @@ gimple_ic_transform (gimple_stmt_iterator *gsi)
return false;
if (all > 0)
- prob = (count * REG_BR_PROB_BASE + all / 2) / all;
+ prob = GCOV_COMPUTE_SCALE (count, all);
else
prob = 0;
direct_call = find_func_by_funcdef_no ((int)val);
@@ -1636,7 +1636,7 @@ gimple_stringops_transform (gimple_stmt_iterator *gsi)
if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count))
return false;
if (all > 0)
- prob = (count * REG_BR_PROB_BASE + all / 2) / all;
+ prob = GCOV_COMPUTE_SCALE (count, all);
else
prob = 0;
dest = gimple_call_arg (stmt, 0);