]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libgcc/libgcov-util.c
Use REST API for bug titles in mklog.
[thirdparty/gcc.git] / libgcc / libgcov-util.c
index b1d966cc22da4bc8febcbc2ae3539b5fc4f9f3d4..449638bc4b66fbe6e618991a86824b891ba2c2cc 100644 (file)
@@ -1,6 +1,6 @@
 /* Utility functions for reading gcda files into in-memory
    gcov_info structures and offline profile processing. */
-/* Copyright (C) 2014-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2014-2020 Free Software Foundation, Inc.
    Contributed by Rong Xu <xur@google.com>.
 
 This file is part of GCC.
@@ -32,6 +32,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #include "diagnostic.h"
 #include "version.h"
 #include "demangle.h"
+#include "gcov-io.h"
 
 /* Borrowed from basic-block.h.  */
 #define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
@@ -79,6 +80,8 @@ static int k_ctrs_mask[GCOV_COUNTERS];
 static struct gcov_ctr_info k_ctrs[GCOV_COUNTERS];
 /* Number of kind of counters that have been seen.  */
 static int k_ctrs_types;
+/* The object summary being processed.  */
+static struct gcov_summary *curr_object_summary;
 
 /* Merge functions for counters.  */
 #define DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) __gcov_merge ## FN_TYPE,
@@ -131,7 +134,6 @@ static const tag_format_t tag_table[] =
   {GCOV_TAG_ARCS, "ARCS", tag_arcs},
   {GCOV_TAG_LINES, "LINES", tag_lines},
   {GCOV_TAG_OBJECT_SUMMARY, "OBJECT_SUMMARY", tag_summary},
-  {GCOV_TAG_PROGRAM_SUMMARY, "PROGRAM_SUMMARY", tag_summary},
   {0, NULL, NULL}
 };
 
@@ -223,9 +225,8 @@ tag_counters (unsigned tag, unsigned length)
 static void
 tag_summary (unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
 {
-  struct gcov_summary summary;
-
-  gcov_read_summary (&summary);
+  curr_object_summary = (gcov_summary *) xcalloc (sizeof (gcov_summary), 1);
+  gcov_read_summary (curr_object_summary);
 }
 
 /* This function is called at the end of reading a gcda file.
@@ -239,7 +240,8 @@ read_gcda_finalize (struct gcov_info *obj_info)
   set_fn_ctrs (curr_fn_info);
   obstack_ptr_grow (&fn_info, curr_fn_info);
 
-  /* We set the following fields: merge, n_functions, and functions.  */
+  /* We set the following fields: merge, n_functions, functions
+     and summary.  */
   obj_info->n_functions = num_fn_info;
   obj_info->functions = (const struct gcov_fn_info**) obstack_finish (&fn_info);
 
@@ -299,6 +301,7 @@ read_gcda_file (const char *filename)
   obstack_init (&fn_info);
   num_fn_info = 0;
   curr_fn_info = 0;
+  curr_object_summary = NULL;
   {
     size_t len = strlen (filename) + 1;
     char *str_dup = (char*) xmalloc (len);
@@ -329,7 +332,7 @@ read_gcda_file (const char *filename)
         {
           if (((mask & 0xff) != 0xff))
             {
-              warning (0, "%s:tag `%x' is invalid\n", filename, tag);
+             warning (0, "%s:tag %qx is invalid", filename, tag);
               break;
             }
           tag_depth--;
@@ -344,7 +347,7 @@ read_gcda_file (const char *filename)
           if (depth && depth < tag_depth)
             {
               if (!GCOV_TAG_IS_SUBTAG (tags[depth - 1], tag))
-                warning (0, "%s:tag `%x' is incorrectly nested\n",
+               warning (0, "%s:tag %qx is incorrectly nested",
                          filename, tag);
             }
           depth = tag_depth;
@@ -359,18 +362,18 @@ read_gcda_file (const char *filename)
 
           actual_length = gcov_position () - base;
           if (actual_length > length)
-            warning (0, "%s:record size mismatch %lu bytes overread\n",
+           warning (0, "%s:record size mismatch %lu bytes overread",
                      filename, actual_length - length);
           else if (length > actual_length)
-            warning (0, "%s:record size mismatch %lu bytes unread\n",
+           warning (0, "%s:record size mismatch %lu bytes unread",
                      filename, length - actual_length);
        }
 
       gcov_sync (base, length);
       if ((error = gcov_is_error ()))
         {
-          warning (0, error < 0 ? "%s:counter overflow at %lu\n" :
-                                  "%s:read error at %lu\n", filename,
+         warning (0, error < 0 ? "%s:counter overflow at %lu" :
+                                 "%s:read error at %lu", filename,
                    (long unsigned) gcov_position ());
           break;
         }
@@ -458,10 +461,9 @@ gcov_read_profile_dir (const char* dir_name, int recompute_summary ATTRIBUTE_UNU
 #ifdef HAVE_FTW_H
   ftw (".", ftw_read_file, 50);
 #endif
-  ret = chdir (pwd);
+  chdir (pwd);
   free (pwd);
 
-
   return gcov_info_head;;
 }
 
@@ -678,6 +680,9 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info *src_profile
       tgt_tail = gi_ptr;
     }
 
+  free (in_src_not_tgt);
+  free (tgt_infos);
+
   return 0;
 }
 
@@ -720,11 +725,11 @@ __gcov_time_profile_counter_op (gcov_type *counters ATTRIBUTE_UNUSED,
   /* Do nothing.  */
 }
 
-/* Performing FN upon single counters.  */
+/* Performing FN upon TOP N counters.  */
 
 static void
-__gcov_single_counter_op (gcov_type *counters, unsigned n_counters,
-                          counter_op_fn fn, void *data1, void *data2)
+__gcov_topn_counter_op (gcov_type *counters, unsigned n_counters,
+                       counter_op_fn fn, void *data1, void *data2)
 {
   unsigned i, n_measures;
 
@@ -737,25 +742,6 @@ __gcov_single_counter_op (gcov_type *counters, unsigned n_counters,
     }
 }
 
-/* Performing FN upon indirect-call profile counters.  */
-
-static void
-__gcov_icall_topn_counter_op (gcov_type *counters, unsigned n_counters,
-                              counter_op_fn fn, void *data1, void *data2)
-{
-  unsigned i;
-
-  gcc_assert (!(n_counters % GCOV_ICALL_TOPN_NCOUNTS));
-  for (i = 0; i < n_counters; i += GCOV_ICALL_TOPN_NCOUNTS)
-    {
-      unsigned j;
-      gcov_type *value_array = &counters[i + 1];
-
-      for (j = 0; j < GCOV_ICALL_TOPN_NCOUNTS - 1; j += 2)
-        value_array[j + 1] = fn (value_array[j + 1], data1, data2);
-    }
-}
-
 /* Scaling the counter value V by multiplying *(float*) DATA1.  */
 
 static gcov_type
@@ -892,8 +878,6 @@ calculate_2_entries (const unsigned long v1, const unsigned long v2,
 }
 
 /*  Compute the overlap score between GCOV_INFO1 and GCOV_INFO2.
-    SUM_1 is the sum_all for profile1 where GCOV_INFO1 belongs.
-    SUM_2 is the sum_all for profile2 where GCOV_INFO2 belongs.
     This function also updates cumulative score CUM_1_RESULT and
     CUM_2_RESULT.  */
 
@@ -930,24 +914,13 @@ compute_one_gcov (const struct gcov_info *gcov_info1,
   {
     for (f_ix = 0; f_ix < gcov_info->n_functions; f_ix++)
       {
-        unsigned t_ix;
         const struct gcov_fn_info *gfi_ptr = gcov_info->functions[f_ix];
         if (!gfi_ptr || gfi_ptr->key != gcov_info)
           continue;
         const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs;
-        for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
-          {
-            unsigned c_num;
-
-            if (!gcov_info->merge[t_ix])
-              continue;
-
-            for (c_num = 0; c_num < ci_ptr->num; c_num++)
-              {
-                cum_1 += ci_ptr->values[c_num] / sum;
-              }
-            ci_ptr++;
-          }
+       unsigned c_num;
+       for (c_num = 0; c_num < ci_ptr->num; c_num++)
+         cum_1 += ci_ptr->values[c_num] / sum;
       }
     *cum_p = cum_1;
     return 0.0;
@@ -955,7 +928,6 @@ compute_one_gcov (const struct gcov_info *gcov_info1,
 
   for (f_ix = 0; f_ix < gcov_info1->n_functions; f_ix++)
     {
-      unsigned t_ix;
       double func_cum_1 = 0.0;
       double func_cum_2 = 0.0;
       double func_val = 0.0;
@@ -971,32 +943,24 @@ compute_one_gcov (const struct gcov_info *gcov_info1,
 
       const struct gcov_ctr_info *ci_ptr1 = gfi_ptr1->ctrs;
       const struct gcov_ctr_info *ci_ptr2 = gfi_ptr2->ctrs;
-      for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
-        {
-          unsigned c_num;
+      unsigned c_num;
+      for (c_num = 0; c_num < ci_ptr1->num; c_num++)
+       {
+         if (ci_ptr1->values[c_num] | ci_ptr2->values[c_num])
+           {
+             func_val += calculate_2_entries (ci_ptr1->values[c_num],
+                                              ci_ptr2->values[c_num],
+                                              sum_1, sum_2);
+
+             func_cum_1 += ci_ptr1->values[c_num] / sum_1;
+             func_cum_2 += ci_ptr2->values[c_num] / sum_2;
+             nonzero = 1;
+             if (ci_ptr1->values[c_num] / sum_1 >= overlap_hot_threshold
+                 || ci_ptr2->values[c_num] / sum_2 >= overlap_hot_threshold)
+               hot = 1;
+           }
+       }
 
-          if (!gcov_info1->merge[t_ix])
-            continue;
-
-          for (c_num = 0; c_num < ci_ptr1->num; c_num++)
-            {
-              if (ci_ptr1->values[c_num] | ci_ptr2->values[c_num])
-                {
-                  func_val += calculate_2_entries (ci_ptr1->values[c_num],
-                                          ci_ptr2->values[c_num],
-                                          sum_1, sum_2);
-
-                  func_cum_1 += ci_ptr1->values[c_num] / sum_1;
-                  func_cum_2 += ci_ptr2->values[c_num] / sum_2;
-                  nonzero = 1;
-                  if (ci_ptr1->values[c_num] / sum_1 >= overlap_hot_threshold ||
-                      ci_ptr2->values[c_num] / sum_2 >= overlap_hot_threshold)
-                    hot = 1;
-                }
-            }
-          ci_ptr1++;
-          ci_ptr2++;
-        }
       ret += func_val;
       cum_1 += func_cum_1;
       cum_2 += func_cum_2;
@@ -1023,26 +987,14 @@ gcov_info_count_all_cold (const struct gcov_info *gcov_info,
 
   for (f_ix = 0; f_ix < gcov_info->n_functions; f_ix++)
     {
-      unsigned t_ix;
       const struct gcov_fn_info *gfi_ptr = gcov_info->functions[f_ix];
 
       if (!gfi_ptr || gfi_ptr->key != gcov_info)
         continue;
       const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs;
-      for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
-        {
-          unsigned c_num;
-
-          if (!gcov_info->merge[t_ix])
-            continue;
-
-          for (c_num = 0; c_num < ci_ptr->num; c_num++)
-            {
-              if (ci_ptr->values[c_num] > threshold)
-                return false;
-            }
-          ci_ptr++;
-        }
+      for (unsigned c_num = 0; c_num < ci_ptr->num; c_num++)
+       if (ci_ptr->values[c_num] > threshold)
+         return false;
     }
 
   return true;
@@ -1080,12 +1032,6 @@ struct overlap_t {
 /* Cumlative overlap dscore for profile1 and profile2.  */
 static double overlap_sum_1, overlap_sum_2;
 
-/* sum_all for profile1 and profile2.  */
-static gcov_type p1_sum_all, p2_sum_all;
-
-/* run_max for profile1 and profile2.  */
-static gcov_type p1_run_max, p2_run_max;
-
 /* The number of gcda files in the profiles.  */
 static unsigned gcda_files[2];
 
@@ -1232,10 +1178,6 @@ matched_gcov_info (const struct gcov_info *info1, const struct gcov_info *info2)
   return 1;
 }
 
-/* Defined in libgcov-driver.c.  */
-extern gcov_unsigned_t compute_summary (struct gcov_info *,
-                 struct gcov_summary *, size_t *);
-
 /* Compute the overlap score of two profiles with the head of GCOV_LIST1 and
    GCOV_LIST1. Return a number ranging from [0.0, 1.0], with 0.0 meaning no
    match and 1.0 meaning a perfect match.  */
@@ -1244,22 +1186,11 @@ static double
 calculate_overlap (struct gcov_info *gcov_list1,
                    struct gcov_info *gcov_list2)
 {
-  struct gcov_summary this_prg;
   unsigned list1_cnt = 0, list2_cnt= 0, all_cnt;
   unsigned int i, j;
-  size_t max_length;
   const struct gcov_info *gi_ptr;
   struct overlap_t *all_infos;
 
-  compute_summary (gcov_list1, &this_prg, &max_length);
-  overlap_sum_1 = (double) (this_prg.ctrs[0].sum_all);
-  p1_sum_all = this_prg.ctrs[0].sum_all;
-  p1_run_max = this_prg.ctrs[0].run_max;
-  compute_summary (gcov_list2, &this_prg, &max_length);
-  overlap_sum_2 = (double) (this_prg.ctrs[0].sum_all);
-  p2_sum_all = this_prg.ctrs[0].sum_all;
-  p2_run_max = this_prg.ctrs[0].run_max;
-
   for (gi_ptr = gcov_list1; gi_ptr; gi_ptr = gi_ptr->next)
     list1_cnt++;
   for (gi_ptr = gcov_list2; gi_ptr; gi_ptr = gi_ptr->next)
@@ -1351,6 +1282,8 @@ calculate_overlap (struct gcov_info *gcov_list1,
 
     }
 
+  free (all_infos);
+
   if (overlap_obj_level)
     printf("   SUM:%36s  overlap = %6.2f%% (%5.2f%% %5.2f%%)\n",
            "", sum_val*100, sum_cum_1*100, sum_cum_2*100);
@@ -1367,10 +1300,6 @@ calculate_overlap (struct gcov_info *gcov_list1,
          cold_gcda_files[1], both_cold_cnt);
   printf ("    zero files:  %12u\t%12u\t%12u\n", zero_gcda_files[0],
          zero_gcda_files[1], both_zero_cnt);
-  printf ("       sum_all:  %12" PRId64 "\t%12" PRId64 "\n",
-         p1_sum_all, p2_sum_all);
-  printf ("       run_max:  %12" PRId64 "\t%12" PRId64 "\n",
-         p1_run_max, p2_run_max);
 
   return prg_val;
 }