OSDN Git Service

First phase of unifying the computation of profile scale factors/probabilities
authortejohnson <tejohnson@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Apr 2013 17:39:10 +0000 (17:39 +0000)
committertejohnson <tejohnson@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Apr 2013 17:39:10 +0000 (17:39 +0000)
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

22 files changed:
gcc/ChangeLog
gcc/basic-block.h
gcc/cfg.c
gcc/cfgbuild.c
gcc/cfgcleanup.c
gcc/cfgloopmanip.c
gcc/cfgrtl.c
gcc/cgraphclones.c
gcc/gimple-streamer-in.c
gcc/ipa-cp.c
gcc/ipa-inline-analysis.c
gcc/loop-unswitch.c
gcc/lto-cgraph.c
gcc/lto-streamer-in.c
gcc/profile.c
gcc/sched-rgn.c
gcc/stmt.c
gcc/tree-inline.c
gcc/tree-optimize.c
gcc/tree-vect-loop-manip.c
gcc/tree-vect-loop.c
gcc/value-prof.c

index efe75f0..a7ca045 100644 (file)
@@ -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
index d837730..9b5192e 100644 (file)
@@ -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)
index 0c1e425..2bcd790 100644 (file)
--- 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;
index 1e0121d..ac6aefb 100644 (file)
@@ -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
index 471d293..2fcefc6 100644 (file)
@@ -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
            {
index 3e53aa0..13efb75 100644 (file)
@@ -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);
index f0ec70c..6e8a31d 100644 (file)
@@ -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;
        }
index 3a2e3d6..fa6a911 100644 (file)
@@ -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
index cedacb6..a27f0d6 100644 (file)
@@ -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);
 
index aac21ce..0ca25d2 100644 (file)
@@ -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
index 5343933..138433c 100644 (file)
@@ -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;
index 6a12952..e5f1bdc 100644 (file)
@@ -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)
index ac92e90..69f5e3a 100644 (file)
@@ -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);
       }
 }
 
index 0e128fd..982d357 100644 (file)
@@ -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);
index 4b8be44..6f05581 100644 (file)
@@ -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)
index e8d32fd..02a6705 100644 (file)
@@ -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);
        }
index 5a6138b..bada27c 100644 (file)
@@ -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)
index a41dd5a..978db6e 100644 (file)
@@ -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);
 
index 3f69fb3..a72369e 100644 (file)
@@ -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
index a158c62..bff5c22 100644 (file)
@@ -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);
index 6874b65..2fc20f3 100644 (file)
@@ -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),
index 39bbdbf..3348d7f 100644 (file)
@@ -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);