]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/ipa-cp.c
2017-05-23 Jan Hubicka <hubicka@ucw.cz>
[thirdparty/gcc.git] / gcc / ipa-cp.c
index f5e023e748812d6b61945dd416f081fb34edea90..3c9c3f29ee0eb8895e295a1371448bf3a184e028 100644 (file)
@@ -360,7 +360,7 @@ object_allocator<ipcp_agg_lattice> ipcp_agg_lattice_pool
 
 /* Maximal count found in program.  */
 
-static gcov_type max_count;
+static profile_count max_count;
 
 /* Original overall size of the program.  */
 
@@ -640,7 +640,7 @@ ipcp_versionable_function_p (struct cgraph_node *node)
 
 struct caller_statistics
 {
-  gcov_type count_sum;
+  profile_count count_sum;
   int n_calls, n_hot_calls, freq_sum;
 };
 
@@ -649,7 +649,7 @@ struct caller_statistics
 static inline void
 init_caller_stats (struct caller_statistics *stats)
 {
-  stats->count_sum = 0;
+  stats->count_sum = profile_count::zero ();
   stats->n_calls = 0;
   stats->n_hot_calls = 0;
   stats->freq_sum = 0;
@@ -667,7 +667,8 @@ gather_caller_stats (struct cgraph_node *node, void *data)
   for (cs = node->callers; cs; cs = cs->next_caller)
     if (!cs->caller->thunk.thunk_p)
       {
-       stats->count_sum += cs->count;
+        if (cs->count.initialized_p ())
+         stats->count_sum += cs->count;
        stats->freq_sum += cs->frequency;
        stats->n_calls++;
        if (cs->maybe_hot_p ())
@@ -718,9 +719,9 @@ ipcp_cloning_candidate_p (struct cgraph_node *node)
   /* When profile is available and function is hot, propagate into it even if
      calls seems cold; constant propagation can improve function's speed
      significantly.  */
-  if (max_count)
+  if (max_count > profile_count::zero ())
     {
-      if (stats.count_sum > node->count * 90 / 100)
+      if (stats.count_sum > node->count.apply_scale (90, 100))
        {
          if (dump_file)
            fprintf (dump_file, "Considering %s for cloning; "
@@ -2611,7 +2612,7 @@ incorporate_penalties (ipa_node_params *info, int64_t evaluation)
 
 static bool
 good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
-                           int freq_sum, gcov_type count_sum, int size_cost)
+                           int freq_sum, profile_count count_sum, int size_cost)
 {
   if (time_benefit == 0
       || !opt_for_fn (node->decl, flag_ipa_cp_clone)
@@ -2621,22 +2622,25 @@ good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
   gcc_assert (size_cost > 0);
 
   struct ipa_node_params *info = IPA_NODE_REF (node);
-  if (max_count)
+  if (max_count > profile_count::zero ())
     {
-      int factor = (count_sum * 1000) / max_count;
+      int factor = RDIV (count_sum.probability_in (max_count)
+                        * 1000, REG_BR_PROB_BASE);
       int64_t evaluation = (((int64_t) time_benefit * factor)
                                    / size_cost);
       evaluation = incorporate_penalties (info, evaluation);
 
       if (dump_file && (dump_flags & TDF_DETAILS))
-       fprintf (dump_file, "     good_cloning_opportunity_p (time: %i, "
-                "size: %i, count_sum: " HOST_WIDE_INT_PRINT_DEC
-                "%s%s) -> evaluation: " "%" PRId64
+       {
+         fprintf (dump_file, "     good_cloning_opportunity_p (time: %i, "
+                  "size: %i, count_sum: ", time_benefit, size_cost);
+         count_sum.dump (dump_file);
+         fprintf (dump_file, "%s%s) -> evaluation: " "%" PRId64
                 ", threshold: %i\n",
-                time_benefit, size_cost, (HOST_WIDE_INT) count_sum,
                 info->node_within_scc ? ", scc" : "",
                 info->node_calling_single_call ? ", single_call" : "",
                 evaluation, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD));
+       }
 
       return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);
     }
@@ -3520,11 +3524,11 @@ template <typename valtype>
 static bool
 get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest,
                                int *freq_sum,
-                               gcov_type *count_sum, int *caller_count)
+                               profile_count *count_sum, int *caller_count)
 {
   ipcp_value_source<valtype> *src;
   int freq = 0, count = 0;
-  gcov_type cnt = 0;
+  profile_count cnt = profile_count::zero ();
   bool hot = false;
 
   for (src = val->sources; src; src = src->next)
@@ -3536,7 +3540,8 @@ get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest,
            {
              count++;
              freq += cs->frequency;
-             cnt += cs->count;
+             if (cs->count.initialized_p ())
+               cnt += cs->count;
              hot |= cs->maybe_hot_p ();
            }
          cs = get_next_cgraph_edge_clone (cs);
@@ -3611,19 +3616,27 @@ dump_profile_updates (struct cgraph_node *orig_node,
 {
   struct cgraph_edge *cs;
 
-  fprintf (dump_file, "    setting count of the specialized node to "
-          HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) new_node->count);
+  fprintf (dump_file, "    setting count of the specialized node to ");
+  new_node->count.dump (dump_file);
+  fprintf (dump_file, "\n");
   for (cs = new_node->callees; cs; cs = cs->next_callee)
-    fprintf (dump_file, "      edge to %s has count "
-            HOST_WIDE_INT_PRINT_DEC "\n",
-            cs->callee->name (), (HOST_WIDE_INT) cs->count);
+    {
+      fprintf (dump_file, "      edge to %s has count ",
+              cs->callee->name ());
+      cs->count.dump (dump_file);
+      fprintf (dump_file, "\n");
+    }
 
-  fprintf (dump_file, "    setting count of the original node to "
-          HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) orig_node->count);
+  fprintf (dump_file, "    setting count of the original node to ");
+  orig_node->count.dump (dump_file);
+  fprintf (dump_file, "\n");
   for (cs = orig_node->callees; cs; cs = cs->next_callee)
-    fprintf (dump_file, "      edge to %s is left with "
-            HOST_WIDE_INT_PRINT_DEC "\n",
-            cs->callee->name (), (HOST_WIDE_INT) cs->count);
+    {
+      fprintf (dump_file, "      edge to %s is left with ",
+              cs->callee->name ());
+      cs->count.dump (dump_file);
+      fprintf (dump_file, "\n");
+    }
 }
 
 /* After a specialized NEW_NODE version of ORIG_NODE has been created, update
@@ -3635,10 +3648,10 @@ update_profiling_info (struct cgraph_node *orig_node,
 {
   struct cgraph_edge *cs;
   struct caller_statistics stats;
-  gcov_type new_sum, orig_sum;
-  gcov_type remainder, orig_node_count = orig_node->count;
+  profile_count new_sum, orig_sum;
+  profile_count remainder, orig_node_count = orig_node->count;
 
-  if (orig_node_count == 0)
+  if (!(orig_node_count > profile_count::zero ()))
     return;
 
   init_caller_stats (&stats);
@@ -3653,18 +3666,22 @@ update_profiling_info (struct cgraph_node *orig_node,
   if (orig_node_count < orig_sum + new_sum)
     {
       if (dump_file)
-       fprintf (dump_file, "    Problem: node %s has too low count "
-                HOST_WIDE_INT_PRINT_DEC " while the sum of incoming "
-                "counts is " HOST_WIDE_INT_PRINT_DEC "\n",
-                orig_node->dump_name (),
-                (HOST_WIDE_INT) orig_node_count,
-                (HOST_WIDE_INT) (orig_sum + new_sum));
-
-      orig_node_count = (orig_sum + new_sum) * 12 / 10;
+       {
+         fprintf (dump_file, "    Problem: node %s has too low count ",
+                  orig_node->dump_name ());
+         orig_node_count.dump (dump_file);
+         fprintf (dump_file, "while the sum of incoming count is ");
+         (orig_sum + new_sum).dump (dump_file);
+         fprintf (dump_file, "\n");
+       }
+
+      orig_node_count = (orig_sum + new_sum).apply_scale (12, 10);
       if (dump_file)
-       fprintf (dump_file, "      proceeding by pretending it was "
-                HOST_WIDE_INT_PRINT_DEC "\n",
-                (HOST_WIDE_INT) orig_node_count);
+       {
+         fprintf (dump_file, "      proceeding by pretending it was ");
+         orig_node_count.dump (dump_file);
+         fprintf (dump_file, "\n");
+       }
     }
 
   new_node->count = new_sum;
@@ -3672,17 +3689,14 @@ update_profiling_info (struct cgraph_node *orig_node,
   orig_node->count = remainder;
 
   for (cs = new_node->callees; cs; cs = cs->next_callee)
+    /* FIXME: why we care about non-zero frequency here?  */
     if (cs->frequency)
-      cs->count = apply_probability (cs->count,
-                                    GCOV_COMPUTE_SCALE (new_sum,
-                                                        orig_node_count));
+      cs->count = cs->count.apply_scale (new_sum, orig_node_count);
     else
-      cs->count = 0;
+      cs->count = profile_count::zero ();
 
   for (cs = orig_node->callees; cs; cs = cs->next_callee)
-    cs->count = apply_probability (cs->count,
-                                  GCOV_COMPUTE_SCALE (remainder,
-                                                      orig_node_count));
+    cs->count = cs->count.apply_scale (remainder, orig_node_count);
 
   if (dump_file)
     dump_profile_updates (orig_node, new_node);
@@ -3695,15 +3709,18 @@ update_profiling_info (struct cgraph_node *orig_node,
 static void
 update_specialized_profile (struct cgraph_node *new_node,
                            struct cgraph_node *orig_node,
-                           gcov_type redirected_sum)
+                           profile_count redirected_sum)
 {
   struct cgraph_edge *cs;
-  gcov_type new_node_count, orig_node_count = orig_node->count;
+  profile_count new_node_count, orig_node_count = orig_node->count;
 
   if (dump_file)
-    fprintf (dump_file, "    the sum of counts of redirected  edges is "
-            HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) redirected_sum);
-  if (orig_node_count == 0)
+    {
+      fprintf (dump_file, "    the sum of counts of redirected  edges is ");
+      redirected_sum.dump (dump_file);
+      fprintf (dump_file, "\n");
+    }
+  if (!(orig_node_count > profile_count::zero ()))
     return;
 
   gcc_assert (orig_node_count >= redirected_sum);
@@ -3714,21 +3731,15 @@ update_specialized_profile (struct cgraph_node *new_node,
 
   for (cs = new_node->callees; cs; cs = cs->next_callee)
     if (cs->frequency)
-      cs->count += apply_probability (cs->count,
-                                     GCOV_COMPUTE_SCALE (redirected_sum,
-                                                         new_node_count));
+      cs->count += cs->count.apply_scale (redirected_sum, new_node_count);
     else
-      cs->count = 0;
+      cs->count = profile_count::zero ();
 
   for (cs = orig_node->callees; cs; cs = cs->next_callee)
     {
-      gcov_type dec = apply_probability (cs->count,
-                                        GCOV_COMPUTE_SCALE (redirected_sum,
-                                                            orig_node_count));
-      if (dec < cs->count)
-       cs->count -= dec;
-      else
-       cs->count = 0;
+      profile_count dec = cs->count.apply_scale (redirected_sum,
+                                                orig_node_count);
+      cs->count -= dec;
     }
 
   if (dump_file)
@@ -4423,7 +4434,7 @@ static void
 perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val)
 {
   ipcp_value_source<valtype> *src;
-  gcov_type redirected_sum = 0;
+  profile_count redirected_sum = profile_count::zero ();
 
   for (src = val->sources; src; src = src->next)
     {
@@ -4441,13 +4452,14 @@ perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val)
 
              cs->redirect_callee_duplicating_thunks (val->spec_node);
              val->spec_node->expand_all_artificial_thunks ();
-             redirected_sum += cs->count;
+             if (cs->count.initialized_p ())
+               redirected_sum = redirected_sum + cs->count;
            }
          cs = get_next_cgraph_edge_clone (cs);
        }
     }
 
-  if (redirected_sum)
+  if (redirected_sum > profile_count::zero ())
     update_specialized_profile (val->spec_node, node, redirected_sum);
 }
 
@@ -4550,7 +4562,7 @@ decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
 {
   struct ipa_agg_replacement_value *aggvals;
   int freq_sum, caller_count;
-  gcov_type count_sum;
+  profile_count count_sum;
   vec<cgraph_edge *> callers;
 
   if (val->spec_node)
@@ -5103,7 +5115,7 @@ make_pass_ipa_cp (gcc::context *ctxt)
 void
 ipa_cp_c_finalize (void)
 {
-  max_count = 0;
+  max_count = profile_count::zero ();
   overall_size = 0;
   max_new_size = 0;
 }