diff options
author | tejohnson <tejohnson@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-04-08 17:39:10 +0000 |
---|---|---|
committer | tejohnson <tejohnson@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-04-08 17:39:10 +0000 |
commit | f9d4b7f4943df04e4362f7cde1fb6c6de22283ef (patch) | |
tree | ffb943825496db918422c6ebe357dcdcc5207a4b /gcc | |
parent | 3f4737cd41c1ae5451f9bd34414d33b3214d6dec (diff) | |
download | gcc-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/ChangeLog | 46 | ||||
-rw-r--r-- | gcc/basic-block.h | 5 | ||||
-rw-r--r-- | gcc/cfg.c | 1 | ||||
-rw-r--r-- | gcc/cfgbuild.c | 6 | ||||
-rw-r--r-- | gcc/cfgcleanup.c | 4 | ||||
-rw-r--r-- | gcc/cfgloopmanip.c | 35 | ||||
-rw-r--r-- | gcc/cfgrtl.c | 2 | ||||
-rw-r--r-- | gcc/cgraphclones.c | 2 | ||||
-rw-r--r-- | gcc/gimple-streamer-in.c | 4 | ||||
-rw-r--r-- | gcc/ipa-cp.c | 19 | ||||
-rw-r--r-- | gcc/ipa-inline-analysis.c | 12 | ||||
-rw-r--r-- | gcc/loop-unswitch.c | 2 | ||||
-rw-r--r-- | gcc/lto-cgraph.c | 29 | ||||
-rw-r--r-- | gcc/lto-streamer-in.c | 4 | ||||
-rw-r--r-- | gcc/profile.c | 2 | ||||
-rw-r--r-- | gcc/sched-rgn.c | 2 | ||||
-rw-r--r-- | gcc/stmt.c | 4 | ||||
-rw-r--r-- | gcc/tree-inline.c | 8 | ||||
-rw-r--r-- | gcc/tree-optimize.c | 22 | ||||
-rw-r--r-- | gcc/tree-vect-loop-manip.c | 4 | ||||
-rw-r--r-- | gcc/tree-vect-loop.c | 2 | ||||
-rw-r--r-- | gcc/value-prof.c | 12 |
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); |