LCOV - code coverage report
Current view: top level - gcc - coverage.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.6 % 628 563
Test Date: 2024-04-13 14:00:49 Functions: 96.4 % 28 27
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Read and write coverage files, and associated functionality.
       2                 :             :    Copyright (C) 1990-2024 Free Software Foundation, Inc.
       3                 :             :    Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
       4                 :             :    based on some ideas from Dain Samples of UC Berkeley.
       5                 :             :    Further mangling by Bob Manson, Cygnus Support.
       6                 :             :    Further mangled by Nathan Sidwell, CodeSourcery
       7                 :             : 
       8                 :             : This file is part of GCC.
       9                 :             : 
      10                 :             : GCC is free software; you can redistribute it and/or modify it under
      11                 :             : the terms of the GNU General Public License as published by the Free
      12                 :             : Software Foundation; either version 3, or (at your option) any later
      13                 :             : version.
      14                 :             : 
      15                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      16                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      17                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      18                 :             : for more details.
      19                 :             : 
      20                 :             : You should have received a copy of the GNU General Public License
      21                 :             : along with GCC; see the file COPYING3.  If not see
      22                 :             : <http://www.gnu.org/licenses/>.  */
      23                 :             : 
      24                 :             : 
      25                 :             : #define GCOV_LINKAGE
      26                 :             : 
      27                 :             : #include "config.h"
      28                 :             : #include "system.h"
      29                 :             : #include "coretypes.h"
      30                 :             : #include "backend.h"
      31                 :             : #include "target.h"
      32                 :             : #include "rtl.h"
      33                 :             : #include "tree.h"
      34                 :             : #include "tree-pass.h"
      35                 :             : #include "memmodel.h"
      36                 :             : #include "tm_p.h"
      37                 :             : #include "stringpool.h"
      38                 :             : #include "cgraph.h"
      39                 :             : #include "coverage.h"
      40                 :             : #include "diagnostic-core.h"
      41                 :             : #include "fold-const.h"
      42                 :             : #include "stor-layout.h"
      43                 :             : #include "output.h"
      44                 :             : #include "toplev.h"
      45                 :             : #include "langhooks.h"
      46                 :             : #include "tree-iterator.h"
      47                 :             : #include "context.h"
      48                 :             : #include "pass_manager.h"
      49                 :             : #include "intl.h"
      50                 :             : #include "auto-profile.h"
      51                 :             : #include "profile.h"
      52                 :             : #include "diagnostic.h"
      53                 :             : #include "varasm.h"
      54                 :             : #include "file-prefix-map.h"
      55                 :             : 
      56                 :             : #include "gcov-io.cc"
      57                 :             : 
      58                 :             : struct GTY((chain_next ("%h.next"))) coverage_data
      59                 :             : {
      60                 :             :   struct coverage_data *next;    /* next function */
      61                 :             :   unsigned ident;                /* function ident */
      62                 :             :   unsigned lineno_checksum;      /* function lineno checksum */
      63                 :             :   unsigned cfg_checksum;         /* function cfg checksum */
      64                 :             :   tree fn_decl;                  /* the function decl */
      65                 :             :   tree ctr_vars[GCOV_COUNTERS];  /* counter variables.  */
      66                 :             : };
      67                 :             : 
      68                 :             : /* Counts information for a function.  */
      69                 :             : struct counts_entry : pointer_hash <counts_entry>
      70                 :             : {
      71                 :             :   /* We hash by  */
      72                 :             :   unsigned ident;
      73                 :             :   unsigned ctr;
      74                 :             : 
      75                 :             :   /* Store  */
      76                 :             :   unsigned lineno_checksum;
      77                 :             :   unsigned cfg_checksum;
      78                 :             :   gcov_type *counts;
      79                 :             :   unsigned n_counts;
      80                 :             : 
      81                 :             :   /* hash_table support.  */
      82                 :             :   static inline hashval_t hash (const counts_entry *);
      83                 :             :   static int equal (const counts_entry *, const counts_entry *);
      84                 :             :   static void remove (counts_entry *);
      85                 :             : };
      86                 :             : 
      87                 :             : static GTY(()) struct coverage_data *functions_head = 0;
      88                 :             : static struct coverage_data **functions_tail = &functions_head;
      89                 :             : static unsigned no_coverage = 0;
      90                 :             : 
      91                 :             : /* Cumulative counter information for whole program.  */
      92                 :             : static unsigned prg_ctr_mask; /* Mask of counter types generated.  */
      93                 :             : 
      94                 :             : /* Counter information for current function.  */
      95                 :             : static unsigned fn_ctr_mask; /* Mask of counters used.  */
      96                 :             : static GTY(()) tree fn_v_ctrs[GCOV_COUNTERS];   /* counter variables.  */
      97                 :             : static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated.  */
      98                 :             : static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base.  */
      99                 :             : 
     100                 :             : /* Coverage info VAR_DECL and function info type nodes.  */
     101                 :             : static GTY(()) tree gcov_info_var;
     102                 :             : static GTY(()) tree gcov_fn_info_type;
     103                 :             : static GTY(()) tree gcov_fn_info_ptr_type;
     104                 :             : 
     105                 :             : /* Name of the notes (gcno) output file.  The "bbg" prefix is for
     106                 :             :    historical reasons, when the notes file contained only the
     107                 :             :    basic block graph notes.
     108                 :             :    If this is NULL we're not writing to the notes file.  */
     109                 :             : static char *bbg_file_name;
     110                 :             : 
     111                 :             : /* File stamp for notes file.  */
     112                 :             : static unsigned bbg_file_stamp;
     113                 :             : 
     114                 :             : /* Name of the count data (gcda) file.  */
     115                 :             : static char *da_file_name;
     116                 :             : 
     117                 :             : /* The names of merge functions for counters.  */
     118                 :             : #define STR(str) #str
     119                 :             : #define DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) STR(__gcov_merge ## FN_TYPE),
     120                 :             : static const char *const ctr_merge_functions[GCOV_COUNTERS] = {
     121                 :             : #include "gcov-counter.def"
     122                 :             : };
     123                 :             : #undef DEF_GCOV_COUNTER
     124                 :             : #undef STR
     125                 :             : 
     126                 :             : #define DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) NAME,
     127                 :             : static const char *const ctr_names[GCOV_COUNTERS] = {
     128                 :             : #include "gcov-counter.def"
     129                 :             : };
     130                 :             : #undef DEF_GCOV_COUNTER
     131                 :             : 
     132                 :             : /* Forward declarations.  */
     133                 :             : static tree build_var (tree, tree, int);
     134                 :             : 
     135                 :             : /* Return the type node for gcov_type.  */
     136                 :             : 
     137                 :             : tree
     138                 :       15896 : get_gcov_type (void)
     139                 :             : {
     140                 :       15896 :   scalar_int_mode mode
     141                 :       15896 :     = smallest_int_mode_for_size (LONG_LONG_TYPE_SIZE > 32 ? 64 : 32);
     142                 :       15896 :   return lang_hooks.types.type_for_mode (mode, false);
     143                 :             : }
     144                 :             : 
     145                 :             : /* Return the type node for gcov_unsigned_t.  */
     146                 :             : 
     147                 :             : static tree
     148                 :       11223 : get_gcov_unsigned_t (void)
     149                 :             : {
     150                 :       11223 :   scalar_int_mode mode = smallest_int_mode_for_size (32);
     151                 :       11223 :   return lang_hooks.types.type_for_mode (mode, true);
     152                 :             : }
     153                 :             : 
     154                 :             : inline hashval_t
     155                 :       10795 : counts_entry::hash (const counts_entry *entry)
     156                 :             : {
     157                 :       10795 :   return entry->ident * GCOV_COUNTERS + entry->ctr;
     158                 :             : }
     159                 :             : 
     160                 :             : inline int
     161                 :        9697 : counts_entry::equal (const counts_entry *entry1, const counts_entry *entry2)
     162                 :             : {
     163                 :        9697 :   return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
     164                 :             : }
     165                 :             : 
     166                 :             : inline void
     167                 :           0 : counts_entry::remove (counts_entry *entry)
     168                 :             : {
     169                 :           0 :   free (entry->counts);
     170                 :           0 :   free (entry);
     171                 :           0 : }
     172                 :             : 
     173                 :             : /* Hash table of count data.  */
     174                 :             : static hash_table<counts_entry> *counts_hash;
     175                 :             : 
     176                 :             : /* Read in the counts file, if available.  */
     177                 :             : 
     178                 :             : static void
     179                 :         168 : read_counts_file (void)
     180                 :             : {
     181                 :         168 :   gcov_unsigned_t fn_ident = 0;
     182                 :         168 :   gcov_unsigned_t tag;
     183                 :         168 :   int is_error = 0;
     184                 :         168 :   unsigned lineno_checksum = 0;
     185                 :         168 :   unsigned cfg_checksum = 0;
     186                 :             : 
     187                 :         168 :   if (!gcov_open (da_file_name, 1))
     188                 :             :     return;
     189                 :             : 
     190                 :         113 :   if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
     191                 :             :     {
     192                 :           0 :       warning (0, "%qs is not a gcov data file", da_file_name);
     193                 :           0 :       gcov_close ();
     194                 :           0 :       return;
     195                 :             :     }
     196                 :         113 :   else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
     197                 :             :     {
     198                 :           0 :       char v[4], e[4];
     199                 :             : 
     200                 :           0 :       GCOV_UNSIGNED2STRING (v, tag);
     201                 :           0 :       GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
     202                 :             : 
     203                 :           0 :       warning (0, "%qs is version %q.*s, expected version %q.*s",
     204                 :             :                da_file_name, 4, v, 4, e);
     205                 :           0 :       gcov_close ();
     206                 :           0 :       return;
     207                 :             :     }
     208                 :             : 
     209                 :             :   /* Read the stamp, used for creating a generation count.  */
     210                 :         113 :   tag = gcov_read_unsigned ();
     211                 :         113 :   bbg_file_stamp = crc32_unsigned (bbg_file_stamp, tag);
     212                 :             : 
     213                 :             :   /* Read checksum.  */
     214                 :         113 :   gcov_read_unsigned ();
     215                 :             : 
     216                 :         113 :   counts_hash = new hash_table<counts_entry> (10);
     217                 :        1739 :   while ((tag = gcov_read_unsigned ()))
     218                 :             :     {
     219                 :        1626 :       gcov_unsigned_t length;
     220                 :        1626 :       gcov_position_t offset;
     221                 :             : 
     222                 :        1626 :       length = gcov_read_unsigned ();
     223                 :        1626 :       offset = gcov_position ();
     224                 :        1626 :       if (tag == GCOV_TAG_FUNCTION)
     225                 :             :         {
     226                 :         478 :           if (length)
     227                 :             :             {
     228                 :         478 :               fn_ident = gcov_read_unsigned ();
     229                 :         478 :               lineno_checksum = gcov_read_unsigned ();
     230                 :         478 :               cfg_checksum = gcov_read_unsigned ();
     231                 :             :             }
     232                 :             :           else
     233                 :             :             fn_ident = lineno_checksum = cfg_checksum = 0;
     234                 :             :         }
     235                 :        1148 :       else if (tag == GCOV_TAG_OBJECT_SUMMARY)
     236                 :             :         {
     237                 :         113 :           profile_info = XCNEW (gcov_summary);
     238                 :         113 :           profile_info->runs = gcov_read_unsigned ();
     239                 :         113 :           profile_info->sum_max = gcov_read_unsigned ();
     240                 :             :         }
     241                 :        1035 :       else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
     242                 :             :         {
     243                 :        1035 :           counts_entry **slot, *entry, elt;
     244                 :        1035 :           int read_length = (int)length;
     245                 :        1035 :           length = read_length > 0 ? read_length : 0;
     246                 :        1035 :           unsigned n_counts = GCOV_TAG_COUNTER_NUM (abs (read_length));
     247                 :        1035 :           unsigned ix;
     248                 :             : 
     249                 :        1035 :           elt.ident = fn_ident;
     250                 :        1035 :           elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
     251                 :             : 
     252                 :        1035 :           slot = counts_hash->find_slot (&elt, INSERT);
     253                 :        1035 :           entry = *slot;
     254                 :        1035 :           if (!entry)
     255                 :             :             {
     256                 :        1035 :               *slot = entry = XCNEW (counts_entry);
     257                 :        1035 :               entry->ident = fn_ident;
     258                 :        1035 :               entry->ctr = elt.ctr;
     259                 :        1035 :               entry->lineno_checksum = lineno_checksum;
     260                 :        1035 :               entry->cfg_checksum = cfg_checksum;
     261                 :        1035 :               entry->counts = XCNEWVEC (gcov_type, n_counts);
     262                 :        1035 :               entry->n_counts = n_counts;
     263                 :             :             }
     264                 :           0 :           else if (entry->lineno_checksum != lineno_checksum
     265                 :           0 :                    || entry->cfg_checksum != cfg_checksum)
     266                 :             :             {
     267                 :           0 :               error ("profile data for function %u is corrupted", fn_ident);
     268                 :           0 :               error ("checksum is (%x,%x) instead of (%x,%x)",
     269                 :             :                      entry->lineno_checksum, entry->cfg_checksum,
     270                 :             :                      lineno_checksum, cfg_checksum);
     271                 :           0 :               delete counts_hash;
     272                 :           0 :               counts_hash = NULL;
     273                 :           0 :               break;
     274                 :             :             }
     275                 :        1035 :           if (read_length > 0)
     276                 :        2800 :             for (ix = 0; ix != n_counts; ix++)
     277                 :        2099 :               entry->counts[ix] = gcov_read_counter ();
     278                 :             :         }
     279                 :        1626 :       gcov_sync (offset, length);
     280                 :        3252 :       if ((is_error = gcov_is_error ()))
     281                 :             :         {
     282                 :           0 :           error (is_error < 0
     283                 :             :                  ? G_("%qs has overflowed")
     284                 :             :                  : G_("%qs is corrupted"),
     285                 :             :                  da_file_name);
     286                 :           0 :           delete counts_hash;
     287                 :           0 :           counts_hash = NULL;
     288                 :           0 :           break;
     289                 :             :         }
     290                 :             :     }
     291                 :             : 
     292                 :         113 :   gcov_close ();
     293                 :             : }
     294                 :             : 
     295                 :             : /* Returns the counters for a particular tag.  */
     296                 :             : 
     297                 :             : gcov_type *
     298                 :        1130 : get_coverage_counts (unsigned counter, unsigned cfg_checksum,
     299                 :             :                      unsigned lineno_checksum, unsigned int n_counts)
     300                 :             : {
     301                 :        1130 :   counts_entry *entry, elt;
     302                 :             : 
     303                 :             :   /* No hash table, no counts.  */
     304                 :        1130 :   if (!counts_hash)
     305                 :             :     {
     306                 :         204 :       static int warned = 0;
     307                 :             : 
     308                 :         204 :       if (!warned++)
     309                 :             :         {
     310                 :          47 :           warning (OPT_Wmissing_profile,
     311                 :             :                    "%qs profile count data file not found",
     312                 :             :                    da_file_name);
     313                 :          47 :           if (dump_enabled_p ())
     314                 :             :             {
     315                 :           7 :               dump_user_location_t loc
     316                 :           7 :                 = dump_user_location_t::from_location_t (input_location);
     317                 :           7 :               dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
     318                 :             :                                "file %s not found, %s\n", da_file_name,
     319                 :           7 :                                (flag_guess_branch_prob
     320                 :             :                                 ? "execution counts estimated"
     321                 :             :                                 : "execution counts assumed to be zero"));
     322                 :             :             }
     323                 :             :         }
     324                 :         204 :       return NULL;
     325                 :             :     }
     326                 :         926 :   if (param_profile_func_internal_id)
     327                 :           0 :     elt.ident = current_function_funcdef_no + 1;
     328                 :             :   else
     329                 :             :     {
     330                 :         926 :       gcc_assert (coverage_node_map_initialized_p ());
     331                 :         926 :       elt.ident = cgraph_node::get (current_function_decl)->profile_id;
     332                 :             :     }
     333                 :         926 :   elt.ctr = counter;
     334                 :         926 :   entry = counts_hash->find (&elt);
     335                 :         926 :   if (!entry)
     336                 :             :     {
     337                 :          21 :       if (counter == GCOV_COUNTER_ARCS)
     338                 :           1 :         warning_at (DECL_SOURCE_LOCATION (current_function_decl),
     339                 :             :                     OPT_Wmissing_profile,
     340                 :             :                     "profile for function %qD not found in profile data",
     341                 :             :                     current_function_decl);
     342                 :             :       /* The function was not emitted, or is weak and not chosen in the
     343                 :             :          final executable.  Silently fail, because there's nothing we
     344                 :             :          can do about it.  */
     345                 :          21 :       return NULL;
     346                 :             :     }
     347                 :             : 
     348                 :         905 :   if (entry->cfg_checksum != cfg_checksum
     349                 :         903 :       || (counter != GCOV_COUNTER_V_INDIR
     350                 :         903 :           && counter != GCOV_COUNTER_V_TOPN
     351                 :         837 :           && entry->n_counts != n_counts))
     352                 :             :     {
     353                 :           2 :       static int warned = 0;
     354                 :           2 :       bool warning_printed = false;
     355                 :             : 
     356                 :           2 :       if (entry->n_counts != n_counts)
     357                 :           1 :         warning_printed =
     358                 :           1 :           warning_at (DECL_SOURCE_LOCATION (current_function_decl),
     359                 :             :                       OPT_Wcoverage_mismatch,
     360                 :             :                       "number of counters in profile data for function %qD "
     361                 :             :                       "does not match "
     362                 :             :                       "its profile data (counter %qs, expected %i and have %i)",
     363                 :             :                       current_function_decl,
     364                 :           1 :                       ctr_names[counter], entry->n_counts, n_counts);
     365                 :             :       else
     366                 :           1 :         warning_printed =
     367                 :           1 :           warning_at (DECL_SOURCE_LOCATION (current_function_decl),
     368                 :             :                       OPT_Wcoverage_mismatch,
     369                 :             :                       "the control flow of function %qD does not match "
     370                 :             :                       "its profile data (counter %qs)", current_function_decl,
     371                 :           1 :                       ctr_names[counter]);
     372                 :           2 :       if (warning_printed && dump_enabled_p ())
     373                 :             :         {
     374                 :           0 :           dump_user_location_t loc
     375                 :           0 :             = dump_user_location_t::from_function_decl (current_function_decl);
     376                 :           0 :           dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
     377                 :             :                            "use -Wno-error=coverage-mismatch to tolerate "
     378                 :             :                            "the mismatch but performance may drop if the "
     379                 :             :                            "function is hot\n");
     380                 :             :           
     381                 :           0 :           if (!seen_error ()
     382                 :           0 :               && !warned++)
     383                 :             :             {
     384                 :           0 :               dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
     385                 :             :                                "coverage mismatch ignored\n");
     386                 :           0 :               dump_printf (MSG_MISSED_OPTIMIZATION,
     387                 :           0 :                            flag_guess_branch_prob
     388                 :             :                            ? G_("execution counts estimated\n")
     389                 :             :                            : G_("execution counts assumed to be zero\n"));
     390                 :           0 :               if (!flag_guess_branch_prob)
     391                 :           0 :                 dump_printf (MSG_MISSED_OPTIMIZATION,
     392                 :             :                              "this can result in poorly optimized code\n");
     393                 :             :             }
     394                 :             :         }
     395                 :             : 
     396                 :           2 :       return NULL;
     397                 :             :     }
     398                 :         903 :   else if (entry->lineno_checksum != lineno_checksum)
     399                 :             :     {
     400                 :           8 :       warning_at (DECL_SOURCE_LOCATION (current_function_decl),
     401                 :             :                   OPT_Wcoverage_mismatch,
     402                 :             :                   "source locations for function %qD have changed,"
     403                 :             :                   " the profile data may be out of date",
     404                 :             :                   current_function_decl);
     405                 :             :     }
     406                 :             : 
     407                 :         903 :   return entry->counts;
     408                 :             : }
     409                 :             : 
     410                 :             : /* Allocate NUM counters of type COUNTER. Returns nonzero if the
     411                 :             :    allocation succeeded.  */
     412                 :             : 
     413                 :             : int
     414                 :        2407 : coverage_counter_alloc (unsigned counter, unsigned num)
     415                 :             : {
     416                 :        2407 :   if (no_coverage)
     417                 :             :     return 0;
     418                 :             : 
     419                 :        2407 :   if (!num)
     420                 :             :     return 1;
     421                 :             : 
     422                 :        2384 :   if (!fn_v_ctrs[counter])
     423                 :             :     {
     424                 :        2380 :       tree array_type = build_array_type (get_gcov_type (), NULL_TREE);
     425                 :             : 
     426                 :        2380 :       fn_v_ctrs[counter]
     427                 :        2380 :         = build_var (current_function_decl, array_type, counter);
     428                 :             :     }
     429                 :             : 
     430                 :        2384 :   fn_b_ctrs[counter] = fn_n_ctrs[counter];
     431                 :        2384 :   fn_n_ctrs[counter] += num;
     432                 :             :   
     433                 :        2384 :   fn_ctr_mask |= 1 << counter;
     434                 :        2384 :   return 1;
     435                 :             : }
     436                 :             : 
     437                 :             : /* Generate a tree to access COUNTER NO.  */
     438                 :             : 
     439                 :             : tree
     440                 :        7822 : tree_coverage_counter_ref (unsigned counter, unsigned no)
     441                 :             : {
     442                 :        7822 :   tree gcov_type_node = get_gcov_type ();
     443                 :             : 
     444                 :        7822 :   gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
     445                 :             : 
     446                 :        7822 :   no += fn_b_ctrs[counter];
     447                 :             :   
     448                 :             :   /* "no" here is an array index, scaled to bytes later.  */
     449                 :        7822 :   return build4 (ARRAY_REF, gcov_type_node, fn_v_ctrs[counter],
     450                 :        7822 :                  build_int_cst (integer_type_node, no), NULL, NULL);
     451                 :             : }
     452                 :             : 
     453                 :             : /* Generate a tree to access the address of COUNTER NO.  */
     454                 :             : 
     455                 :             : tree
     456                 :         143 : tree_coverage_counter_addr (unsigned counter, unsigned no)
     457                 :             : {
     458                 :         143 :   tree gcov_type_node = get_gcov_type ();
     459                 :             : 
     460                 :         143 :   gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
     461                 :         143 :   no += fn_b_ctrs[counter];
     462                 :             : 
     463                 :             :   /* "no" here is an array index, scaled to bytes later.  */
     464                 :         143 :   return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node,
     465                 :             :                                        fn_v_ctrs[counter],
     466                 :             :                                        build_int_cst (integer_type_node, no),
     467                 :             :                                        NULL, NULL));
     468                 :             : }
     469                 :             : 
     470                 :             : 
     471                 :             : /* Generate a checksum for a string.  CHKSUM is the current
     472                 :             :    checksum.  */
     473                 :             : 
     474                 :             : static unsigned
     475                 :        7280 : coverage_checksum_string (unsigned chksum, const char *string)
     476                 :             : {
     477                 :        7280 :   int i;
     478                 :        7280 :   char *dup = NULL;
     479                 :             : 
     480                 :             :   /* Look for everything that looks if it were produced by
     481                 :             :      get_file_function_name and zero out the second part
     482                 :             :      that may result from flag_random_seed.  This is not critical
     483                 :             :      as the checksums are used only for sanity checking.  */
     484                 :      297000 :   for (i = 0; string[i]; i++)
     485                 :             :     {
     486                 :      289798 :       int offset = 0;
     487                 :      289798 :       if (startswith (string + i, "_GLOBAL__N_"))
     488                 :          28 :       offset = 11;
     489                 :      289798 :       if (startswith (string + i, "_GLOBAL__"))
     490                 :             :       offset = 9;
     491                 :             : 
     492                 :             :       /* C++ namespaces do have scheme:
     493                 :             :          _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
     494                 :             :        since filename might contain extra underscores there seems
     495                 :             :        to be no better chance then walk all possible offsets looking
     496                 :             :        for magicnumber.  */
     497                 :      289720 :       if (offset)
     498                 :             :         {
     499                 :         772 :           for (i = i + offset; string[i]; i++)
     500                 :         694 :             if (string[i]=='_')
     501                 :             :               {
     502                 :             :                 int y;
     503                 :             : 
     504                 :         202 :                 for (y = 1; y < 9; y++)
     505                 :         202 :                   if (!(string[i + y] >= '0' && string[i + y] <= '9')
     506                 :         138 :                       && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
     507                 :             :                     break;
     508                 :         136 :                 if (y != 9 || string[i + 9] != '_')
     509                 :         136 :                   continue;
     510                 :           0 :                 for (y = 10; y < 18; y++)
     511                 :           0 :                   if (!(string[i + y] >= '0' && string[i + y] <= '9')
     512                 :           0 :                       && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
     513                 :             :                     break;
     514                 :           0 :                 if (y != 18)
     515                 :           0 :                   continue;
     516                 :           0 :                 if (!dup)
     517                 :           0 :                   string = dup = xstrdup (string);
     518                 :           0 :                 for (y = 10; y < 18; y++)
     519                 :           0 :                   dup[i + y] = '0';
     520                 :             :               }
     521                 :             :           break;
     522                 :             :         }
     523                 :             :     }
     524                 :             : 
     525                 :        7280 :   chksum = crc32_string (chksum, string);
     526                 :        7280 :   free (dup);
     527                 :             : 
     528                 :        7280 :   return chksum;
     529                 :             : }
     530                 :             : 
     531                 :             : /* Compute checksum for the current function.  We generate a CRC32.  */
     532                 :             : 
     533                 :             : unsigned
     534                 :        2266 : coverage_compute_lineno_checksum (void)
     535                 :             : {
     536                 :        2266 :   expanded_location xloc
     537                 :        2266 :     = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
     538                 :        2266 :   unsigned chksum = xloc.line;
     539                 :             : 
     540                 :        2266 :   if (xloc.file)
     541                 :        2266 :     chksum = coverage_checksum_string (chksum, xloc.file);
     542                 :        2266 :   chksum = coverage_checksum_string
     543                 :        2266 :     (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
     544                 :             : 
     545                 :        2266 :   return chksum;
     546                 :             : }
     547                 :             : 
     548                 :             : /* Compute profile ID.  This is better to be unique in whole program.  */
     549                 :             : 
     550                 :             : unsigned
     551                 :        2290 : coverage_compute_profile_id (struct cgraph_node *n)
     552                 :             : {
     553                 :        2290 :   unsigned chksum;
     554                 :             : 
     555                 :             :   /* Externally visible symbols have unique name.  */
     556                 :        2290 :   if (TREE_PUBLIC (n->decl) || DECL_EXTERNAL (n->decl) || n->unique_name)
     557                 :             :     {
     558                 :        2061 :       chksum = coverage_checksum_string
     559                 :        2061 :         (0, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl)));
     560                 :             :     }
     561                 :             :   else
     562                 :             :     {
     563                 :         229 :       expanded_location xloc
     564                 :         229 :         = expand_location (DECL_SOURCE_LOCATION (n->decl));
     565                 :         229 :       bool use_name_only = (param_profile_func_internal_id == 0);
     566                 :             : 
     567                 :         229 :       chksum = (use_name_only ? 0 : xloc.line);
     568                 :         229 :       if (xloc.file)
     569                 :         229 :         chksum = coverage_checksum_string (chksum, xloc.file);
     570                 :         229 :       chksum = coverage_checksum_string
     571                 :         229 :         (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl)));
     572                 :         229 :       if (!use_name_only && first_global_object_name)
     573                 :           0 :         chksum = coverage_checksum_string
     574                 :           0 :           (chksum, first_global_object_name);
     575                 :         229 :       char *base_name = xstrdup (aux_base_name);
     576                 :         229 :       if (endswith (base_name, ".gk"))
     577                 :           1 :         base_name[strlen (base_name) - 3] = '\0';
     578                 :         229 :       chksum = coverage_checksum_string (chksum, base_name);
     579                 :         229 :       free (base_name);
     580                 :             :     }
     581                 :             : 
     582                 :             :   /* Non-negative integers are hopefully small enough to fit in all targets.
     583                 :             :      Gcov file formats wants non-zero function IDs.  */
     584                 :        2290 :   chksum = chksum & 0x7fffffff;
     585                 :        2290 :   return chksum + (!chksum);
     586                 :             : }
     587                 :             : 
     588                 :             : /* Compute cfg checksum for the function FN given as argument.
     589                 :             :    The checksum is calculated carefully so that
     590                 :             :    source code changes that doesn't affect the control flow graph
     591                 :             :    won't change the checksum.
     592                 :             :    This is to make the profile data useable across source code change.
     593                 :             :    The downside of this is that the compiler may use potentially
     594                 :             :    wrong profile data - that the source code change has non-trivial impact
     595                 :             :    on the validity of profile data (e.g. the reversed condition)
     596                 :             :    but the compiler won't detect the change and use the wrong profile data.  */
     597                 :             : 
     598                 :             : unsigned
     599                 :      978709 : coverage_compute_cfg_checksum (struct function *fn)
     600                 :             : {
     601                 :      978709 :   basic_block bb;
     602                 :      978709 :   unsigned chksum = n_basic_blocks_for_fn (fn);
     603                 :             : 
     604                 :     6669051 :   FOR_EACH_BB_FN (bb, fn)
     605                 :             :     {
     606                 :     5690342 :       edge e;
     607                 :     5690342 :       edge_iterator ei;
     608                 :     5690342 :       chksum = crc32_byte (chksum, bb->index);
     609                 :    13265722 :       FOR_EACH_EDGE (e, ei, bb->succs)
     610                 :             :         {
     611                 :     7575380 :           chksum = crc32_byte (chksum, e->dest->index);
     612                 :             :         }
     613                 :             :     }
     614                 :             : 
     615                 :      978709 :   return chksum;
     616                 :             : }
     617                 :             : 
     618                 :             : /* Begin output to the notes file for the current function.
     619                 :             :    Writes the function header. Returns nonzero if data should be output.  */
     620                 :             : 
     621                 :             : int
     622                 :        2273 : coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
     623                 :             : {
     624                 :             :   /* We don't need to output .gcno file unless we're under -ftest-coverage
     625                 :             :      (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
     626                 :        2273 :   if (no_coverage || !bbg_file_name)
     627                 :             :     return 0;
     628                 :             : 
     629                 :         859 :   expanded_location startloc
     630                 :         859 :     = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
     631                 :             : 
     632                 :             :   /* Announce function */
     633                 :         859 :   unsigned long offset = gcov_write_tag (GCOV_TAG_FUNCTION);
     634                 :         859 :   if (param_profile_func_internal_id)
     635                 :           0 :     gcov_write_unsigned (current_function_funcdef_no + 1);
     636                 :             :   else
     637                 :             :     {
     638                 :         859 :       gcc_assert (coverage_node_map_initialized_p ());
     639                 :         859 :       gcov_write_unsigned (
     640                 :         859 :         cgraph_node::get (current_function_decl)->profile_id);
     641                 :             :     }
     642                 :             : 
     643                 :         859 :   gcov_write_unsigned (lineno_checksum);
     644                 :         859 :   gcov_write_unsigned (cfg_checksum);
     645                 :         859 :   gcov_write_string (IDENTIFIER_POINTER
     646                 :             :                      (DECL_ASSEMBLER_NAME (current_function_decl)));
     647                 :        1718 :   gcov_write_unsigned (DECL_ARTIFICIAL (current_function_decl)
     648                 :          45 :                        && !DECL_FUNCTION_VERSIONED (current_function_decl)
     649                 :         904 :                        && !DECL_LAMBDA_FUNCTION_P (current_function_decl));
     650                 :         859 :   gcov_write_filename (remap_profile_filename (startloc.file));
     651                 :         859 :   gcov_write_unsigned (startloc.line);
     652                 :         859 :   gcov_write_unsigned (startloc.column);
     653                 :             : 
     654                 :         859 :   expanded_location endloc = expand_location (cfun->function_end_locus);
     655                 :             : 
     656                 :             :   /* Function can start in a single file and end in another one.  */
     657                 :        1718 :   int end_line
     658                 :         859 :     = endloc.file == startloc.file ? endloc.line : startloc.line;
     659                 :        1718 :   int end_column
     660                 :         859 :     = endloc.file == startloc.file ? endloc.column: startloc.column;
     661                 :             : 
     662                 :         859 :   if (startloc.line > end_line)
     663                 :             :     {
     664                 :           1 :       warning_at (DECL_SOURCE_LOCATION (current_function_decl),
     665                 :             :                   OPT_Wcoverage_invalid_line_number,
     666                 :             :                   "function starts on a higher line number than it ends");
     667                 :           1 :       end_line = startloc.line;
     668                 :           1 :       end_column = startloc.column;
     669                 :             :     }
     670                 :             : 
     671                 :         859 :   gcov_write_unsigned (end_line);
     672                 :         859 :   gcov_write_unsigned (end_column);
     673                 :         859 :   gcov_write_length (offset);
     674                 :             : 
     675                 :        1718 :   return !gcov_is_error ();
     676                 :             : }
     677                 :             : 
     678                 :             : /* Finish coverage data for the current function. Verify no output
     679                 :             :    error has occurred.  Save function coverage counts.  */
     680                 :             : 
     681                 :             : void
     682                 :        2273 : coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum)
     683                 :             : {
     684                 :        2273 :   unsigned i;
     685                 :             : 
     686                 :        3132 :   if (bbg_file_name && gcov_is_error ())
     687                 :             :     {
     688                 :           0 :       warning (0, "error writing %qs", bbg_file_name);
     689                 :           0 :       unlink (bbg_file_name);
     690                 :           0 :       bbg_file_name = NULL;
     691                 :             :     }
     692                 :             : 
     693                 :        2273 :   if (fn_ctr_mask)
     694                 :             :     {
     695                 :        1686 :       struct coverage_data *item = 0;
     696                 :             : 
     697                 :        1686 :       item = ggc_alloc<coverage_data> ();
     698                 :             : 
     699                 :        1686 :       if (param_profile_func_internal_id)
     700                 :           0 :         item->ident = current_function_funcdef_no + 1;
     701                 :             :       else
     702                 :             :         {
     703                 :        1686 :           gcc_assert (coverage_node_map_initialized_p ());
     704                 :        1686 :           item->ident = cgraph_node::get (cfun->decl)->profile_id;
     705                 :             :         }
     706                 :             : 
     707                 :        1686 :       item->lineno_checksum = lineno_checksum;
     708                 :        1686 :       item->cfg_checksum = cfg_checksum;
     709                 :             : 
     710                 :        1686 :       item->fn_decl = current_function_decl;
     711                 :        1686 :       item->next = 0;
     712                 :        1686 :       *functions_tail = item;
     713                 :        1686 :       functions_tail = &item->next;
     714                 :             : 
     715                 :       16860 :       for (i = 0; i != GCOV_COUNTERS; i++)
     716                 :             :         {
     717                 :       15174 :           tree var = fn_v_ctrs[i];
     718                 :             : 
     719                 :       15174 :           if (item)
     720                 :       15174 :             item->ctr_vars[i] = var;
     721                 :       15174 :           if (var)
     722                 :             :             {
     723                 :        2380 :               tree array_type = build_index_type (size_int (fn_n_ctrs[i] - 1));
     724                 :        2380 :               array_type = build_array_type (get_gcov_type (), array_type);
     725                 :        2380 :               TREE_TYPE (var) = array_type;
     726                 :        2380 :               DECL_SIZE (var) = TYPE_SIZE (array_type);
     727                 :        2380 :               DECL_SIZE_UNIT (var) = TYPE_SIZE_UNIT (array_type);
     728                 :        2380 :               varpool_node::finalize_decl (var);
     729                 :             :             }
     730                 :             :           
     731                 :       15174 :           fn_b_ctrs[i] = fn_n_ctrs[i] = 0;
     732                 :       15174 :           fn_v_ctrs[i] = NULL_TREE;
     733                 :             :         }
     734                 :        1686 :       prg_ctr_mask |= fn_ctr_mask;
     735                 :        1686 :       fn_ctr_mask = 0;
     736                 :             :     }
     737                 :        2273 : }
     738                 :             : 
     739                 :             : /* Remove coverage file if opened.  */
     740                 :             : 
     741                 :             : void
     742                 :       26601 : coverage_remove_note_file (void)
     743                 :             : {
     744                 :       26601 :   if (bbg_file_name)
     745                 :             :     {
     746                 :           0 :       gcov_close ();
     747                 :           0 :       unlink (bbg_file_name);
     748                 :             :     }
     749                 :       26601 : }
     750                 :             : 
     751                 :             : /* Build a coverage variable of TYPE for function FN_DECL.  If COUNTER
     752                 :             :    >= 0 it is a counter array, otherwise it is the function structure.  */
     753                 :             : 
     754                 :             : static tree
     755                 :        4066 : build_var (tree fn_decl, tree type, int counter)
     756                 :             : {
     757                 :        4066 :   tree var = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, type);
     758                 :        4066 :   const char *fn_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn_decl));
     759                 :        4066 :   char *buf;
     760                 :        4066 :   size_t fn_name_len, len;
     761                 :             : 
     762                 :        4066 :   fn_name = targetm.strip_name_encoding (fn_name);
     763                 :        4066 :   fn_name_len = strlen (fn_name);
     764                 :        4066 :   buf = XALLOCAVEC (char, fn_name_len + 8 + sizeof (int) * 3);
     765                 :             : 
     766                 :        4066 :   if (counter < 0)
     767                 :        1686 :     strcpy (buf, "__gcov__");
     768                 :             :   else
     769                 :        2380 :     sprintf (buf, "__gcov%u_", counter);
     770                 :        4066 :   len = strlen (buf);
     771                 :        4066 :   buf[len - 1] = symbol_table::symbol_suffix_separator ();
     772                 :        4066 :   memcpy (buf + len, fn_name, fn_name_len + 1);
     773                 :        4066 :   DECL_NAME (var) = get_identifier (buf);
     774                 :        4066 :   TREE_STATIC (var) = 1;
     775                 :        4066 :   TREE_ADDRESSABLE (var) = 1;
     776                 :        4066 :   DECL_NONALIASED (var) = 1;
     777                 :        4066 :   SET_DECL_ALIGN (var, TYPE_ALIGN (type));
     778                 :             : 
     779                 :        4066 :   return var;
     780                 :             : }
     781                 :             : 
     782                 :             : /* Creates the gcov_fn_info RECORD_TYPE.  */
     783                 :             : 
     784                 :             : static void
     785                 :         400 : build_fn_info_type (tree type, unsigned counters, tree gcov_info_type)
     786                 :             : {
     787                 :         400 :   tree ctr_info = lang_hooks.types.make_type (RECORD_TYPE);
     788                 :         400 :   tree field, fields;
     789                 :         400 :   tree array_type;
     790                 :             : 
     791                 :         400 :   gcc_assert (counters);
     792                 :             :   
     793                 :             :   /* ctr_info::num */
     794                 :         400 :   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
     795                 :             :                       get_gcov_unsigned_t ());
     796                 :         400 :   fields = field;
     797                 :             :   
     798                 :             :   /* ctr_info::values */
     799                 :         400 :   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
     800                 :             :                       build_pointer_type (get_gcov_type ()));
     801                 :         400 :   DECL_CHAIN (field) = fields;
     802                 :         400 :   fields = field;
     803                 :             :   
     804                 :         400 :   finish_builtin_struct (ctr_info, "__gcov_ctr_info", fields, NULL_TREE);
     805                 :             : 
     806                 :             :   /* key */
     807                 :         400 :   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
     808                 :             :                       build_pointer_type (build_qualified_type
     809                 :             :                                           (gcov_info_type, TYPE_QUAL_CONST)));
     810                 :         400 :   fields = field;
     811                 :             :   
     812                 :             :   /* ident */
     813                 :         400 :   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
     814                 :             :                       get_gcov_unsigned_t ());
     815                 :         400 :   DECL_CHAIN (field) = fields;
     816                 :         400 :   fields = field;
     817                 :             :   
     818                 :             :   /* lineno_checksum */
     819                 :         400 :   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
     820                 :             :                       get_gcov_unsigned_t ());
     821                 :         400 :   DECL_CHAIN (field) = fields;
     822                 :         400 :   fields = field;
     823                 :             : 
     824                 :             :   /* cfg checksum */
     825                 :         400 :   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
     826                 :             :                       get_gcov_unsigned_t ());
     827                 :         400 :   DECL_CHAIN (field) = fields;
     828                 :         400 :   fields = field;
     829                 :             : 
     830                 :         400 :   array_type = build_index_type (size_int (counters - 1));
     831                 :         400 :   array_type = build_array_type (ctr_info, array_type);
     832                 :             : 
     833                 :             :   /* counters */
     834                 :         400 :   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, array_type);
     835                 :         400 :   DECL_CHAIN (field) = fields;
     836                 :         400 :   fields = field;
     837                 :             : 
     838                 :         400 :   finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
     839                 :         400 : }
     840                 :             : 
     841                 :             : /* Returns a CONSTRUCTOR for a gcov_fn_info.  DATA is
     842                 :             :    the coverage data for the function and TYPE is the gcov_fn_info
     843                 :             :    RECORD_TYPE.  KEY is the object file key.  */
     844                 :             : 
     845                 :             : static tree
     846                 :        1686 : build_fn_info (const struct coverage_data *data, tree type, tree key)
     847                 :             : {
     848                 :        1686 :   tree fields = TYPE_FIELDS (type);
     849                 :        1686 :   tree ctr_type;
     850                 :        1686 :   unsigned ix;
     851                 :        1686 :   vec<constructor_elt, va_gc> *v1 = NULL;
     852                 :        1686 :   vec<constructor_elt, va_gc> *v2 = NULL;
     853                 :             : 
     854                 :             :   /* key */
     855                 :        1686 :   CONSTRUCTOR_APPEND_ELT (v1, fields,
     856                 :             :                           build1 (ADDR_EXPR, TREE_TYPE (fields), key));
     857                 :        1686 :   fields = DECL_CHAIN (fields);
     858                 :             :   
     859                 :             :   /* ident */
     860                 :        1686 :   CONSTRUCTOR_APPEND_ELT (v1, fields,
     861                 :             :                           build_int_cstu (get_gcov_unsigned_t (),
     862                 :             :                                           data->ident));
     863                 :        1686 :   fields = DECL_CHAIN (fields);
     864                 :             : 
     865                 :             :   /* lineno_checksum */
     866                 :        1686 :   CONSTRUCTOR_APPEND_ELT (v1, fields,
     867                 :             :                           build_int_cstu (get_gcov_unsigned_t (),
     868                 :             :                                           data->lineno_checksum));
     869                 :        1686 :   fields = DECL_CHAIN (fields);
     870                 :             : 
     871                 :             :   /* cfg_checksum */
     872                 :        1686 :   CONSTRUCTOR_APPEND_ELT (v1, fields,
     873                 :             :                           build_int_cstu (get_gcov_unsigned_t (),
     874                 :             :                                           data->cfg_checksum));
     875                 :        1686 :   fields = DECL_CHAIN (fields);
     876                 :             : 
     877                 :             :   /* counters */
     878                 :        1686 :   ctr_type = TREE_TYPE (TREE_TYPE (fields));
     879                 :       16860 :   for (ix = 0; ix != GCOV_COUNTERS; ix++)
     880                 :       15174 :     if (prg_ctr_mask & (1 << ix))
     881                 :             :       {
     882                 :        2565 :         vec<constructor_elt, va_gc> *ctr = NULL;
     883                 :        2565 :         tree var = data->ctr_vars[ix];
     884                 :        2565 :         unsigned count = 0;
     885                 :             : 
     886                 :        2565 :         if (var)
     887                 :        2380 :           count
     888                 :        2380 :             = tree_to_shwi (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var))))
     889                 :        2380 :             + 1;
     890                 :             : 
     891                 :        2565 :         CONSTRUCTOR_APPEND_ELT (ctr, TYPE_FIELDS (ctr_type),
     892                 :             :                                 build_int_cstu (get_gcov_unsigned_t (),
     893                 :             :                                                 count));
     894                 :             : 
     895                 :        2565 :         if (var)
     896                 :        2380 :           CONSTRUCTOR_APPEND_ELT (ctr, DECL_CHAIN (TYPE_FIELDS (ctr_type)),
     897                 :             :                                   build_fold_addr_expr (var));
     898                 :             :         
     899                 :        2565 :         CONSTRUCTOR_APPEND_ELT (v2, NULL, build_constructor (ctr_type, ctr));
     900                 :             :       }
     901                 :             :   
     902                 :        1686 :   CONSTRUCTOR_APPEND_ELT (v1, fields,
     903                 :             :                           build_constructor (TREE_TYPE (fields), v2));
     904                 :             : 
     905                 :        1686 :   return build_constructor (type, v1);
     906                 :             : }
     907                 :             : 
     908                 :             : /* Create gcov_info struct.  TYPE is the incomplete RECORD_TYPE to be
     909                 :             :    completed, and FN_INFO_PTR_TYPE is a pointer to the function info type.  */
     910                 :             : 
     911                 :             : static void
     912                 :         400 : build_info_type (tree type, tree fn_info_ptr_type)
     913                 :             : {
     914                 :         400 :   tree field, fields = NULL_TREE;
     915                 :         400 :   tree merge_fn_type;
     916                 :             : 
     917                 :             :   /* Version ident */
     918                 :         400 :   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
     919                 :             :                       get_gcov_unsigned_t ());
     920                 :         400 :   DECL_CHAIN (field) = fields;
     921                 :         400 :   fields = field;
     922                 :             : 
     923                 :             :   /* next pointer */
     924                 :         400 :   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
     925                 :             :                       build_pointer_type (build_qualified_type
     926                 :             :                                           (type, TYPE_QUAL_CONST)));
     927                 :         400 :   DECL_CHAIN (field) = fields;
     928                 :         400 :   fields = field;
     929                 :             : 
     930                 :             :   /* stamp */
     931                 :         400 :   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
     932                 :             :                       get_gcov_unsigned_t ());
     933                 :         400 :   DECL_CHAIN (field) = fields;
     934                 :         400 :   fields = field;
     935                 :             : 
     936                 :             :   /* Checksum.  */
     937                 :         400 :   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
     938                 :             :                       get_gcov_unsigned_t ());
     939                 :         400 :   DECL_CHAIN (field) = fields;
     940                 :         400 :   fields = field;
     941                 :             : 
     942                 :             :   /* Filename */
     943                 :         400 :   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
     944                 :             :                       build_pointer_type (build_qualified_type
     945                 :             :                                           (char_type_node, TYPE_QUAL_CONST)));
     946                 :         400 :   DECL_CHAIN (field) = fields;
     947                 :         400 :   fields = field;
     948                 :             : 
     949                 :             :   /* merge fn array */
     950                 :         400 :   merge_fn_type
     951                 :         400 :     = build_function_type_list (void_type_node,
     952                 :             :                                 build_pointer_type (get_gcov_type ()),
     953                 :             :                                 get_gcov_unsigned_t (), NULL_TREE);
     954                 :         400 :   merge_fn_type
     955                 :         400 :     = build_array_type (build_pointer_type (merge_fn_type),
     956                 :         400 :                         build_index_type (size_int (GCOV_COUNTERS - 1)));
     957                 :         400 :   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
     958                 :             :                       merge_fn_type);
     959                 :         400 :   DECL_CHAIN (field) = fields;
     960                 :         400 :   fields = field;
     961                 :             :   
     962                 :             :   /* n_functions */
     963                 :         400 :   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
     964                 :             :                       get_gcov_unsigned_t ());
     965                 :         400 :   DECL_CHAIN (field) = fields;
     966                 :         400 :   fields = field;
     967                 :             :   
     968                 :             :   /* function_info pointer pointer */
     969                 :         400 :   fn_info_ptr_type = build_pointer_type
     970                 :         400 :     (build_qualified_type (fn_info_ptr_type, TYPE_QUAL_CONST));
     971                 :         400 :   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
     972                 :             :                       fn_info_ptr_type);
     973                 :         400 :   DECL_CHAIN (field) = fields;
     974                 :         400 :   fields = field;
     975                 :             : 
     976                 :         400 :   finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
     977                 :         400 : }
     978                 :             : 
     979                 :             : /* Returns a CONSTRUCTOR for the gcov_info object.  INFO_TYPE is the
     980                 :             :    gcov_info structure type, FN_ARY is the array of pointers to
     981                 :             :    function info objects.  */
     982                 :             : 
     983                 :             : static tree
     984                 :         400 : build_info (tree info_type, tree fn_ary, unsigned object_checksum)
     985                 :             : {
     986                 :         400 :   tree info_fields = TYPE_FIELDS (info_type);
     987                 :         400 :   tree merge_fn_type, n_funcs;
     988                 :         400 :   unsigned ix;
     989                 :         400 :   tree filename_string;
     990                 :         400 :   int da_file_name_len;
     991                 :         400 :   vec<constructor_elt, va_gc> *v1 = NULL;
     992                 :         400 :   vec<constructor_elt, va_gc> *v2 = NULL;
     993                 :             : 
     994                 :             :   /* Version ident */
     995                 :         400 :   CONSTRUCTOR_APPEND_ELT (v1, info_fields,
     996                 :             :                           build_int_cstu (TREE_TYPE (info_fields),
     997                 :             :                                           GCOV_VERSION));
     998                 :         400 :   info_fields = DECL_CHAIN (info_fields);
     999                 :             : 
    1000                 :             :   /* next -- NULL */
    1001                 :         400 :   CONSTRUCTOR_APPEND_ELT (v1, info_fields, null_pointer_node);
    1002                 :         400 :   info_fields = DECL_CHAIN (info_fields);
    1003                 :             : 
    1004                 :             :   /* stamp */
    1005                 :         400 :   CONSTRUCTOR_APPEND_ELT (v1, info_fields,
    1006                 :             :                           build_int_cstu (TREE_TYPE (info_fields),
    1007                 :             :                                           bbg_file_stamp));
    1008                 :         400 :   info_fields = DECL_CHAIN (info_fields);
    1009                 :             : 
    1010                 :             :   /* Checksum.  */
    1011                 :         400 :   CONSTRUCTOR_APPEND_ELT (v1, info_fields,
    1012                 :             :                           build_int_cstu (TREE_TYPE (info_fields),
    1013                 :             :                                           object_checksum));
    1014                 :         400 :   info_fields = DECL_CHAIN (info_fields);
    1015                 :             : 
    1016                 :             :   /* Filename */
    1017                 :         400 :   da_file_name_len = strlen (da_file_name);
    1018                 :         400 :   filename_string = build_string (da_file_name_len + 1, da_file_name);
    1019                 :         800 :   TREE_TYPE (filename_string) = build_array_type
    1020                 :         400 :     (char_type_node, build_index_type (size_int (da_file_name_len)));
    1021                 :         400 :   CONSTRUCTOR_APPEND_ELT (v1, info_fields,
    1022                 :             :                           build1 (ADDR_EXPR, TREE_TYPE (info_fields),
    1023                 :             :                                   filename_string));
    1024                 :         400 :   info_fields = DECL_CHAIN (info_fields);
    1025                 :             : 
    1026                 :             :   /* merge fn array -- NULL slots indicate unmeasured counters */
    1027                 :         400 :   merge_fn_type = TREE_TYPE (TREE_TYPE (info_fields));
    1028                 :        4000 :   for (ix = 0; ix != GCOV_COUNTERS; ix++)
    1029                 :             :     {
    1030                 :        3600 :       tree ptr = null_pointer_node;
    1031                 :             : 
    1032                 :        3600 :       if ((1u << ix) & prg_ctr_mask)
    1033                 :             :         {
    1034                 :         711 :           tree merge_fn = build_decl (BUILTINS_LOCATION,
    1035                 :             :                                       FUNCTION_DECL,
    1036                 :         711 :                                       get_identifier (ctr_merge_functions[ix]),
    1037                 :         711 :                                       TREE_TYPE (merge_fn_type));
    1038                 :         711 :           DECL_EXTERNAL (merge_fn) = 1;
    1039                 :         711 :           TREE_PUBLIC (merge_fn) = 1;
    1040                 :         711 :           DECL_ARTIFICIAL (merge_fn) = 1;
    1041                 :         711 :           TREE_NOTHROW (merge_fn) = 1;
    1042                 :             :           /* Initialize assembler name so we can stream out. */
    1043                 :         711 :           DECL_ASSEMBLER_NAME (merge_fn);
    1044                 :         711 :           ptr = build1 (ADDR_EXPR, merge_fn_type, merge_fn);
    1045                 :             :         }
    1046                 :        3600 :       CONSTRUCTOR_APPEND_ELT (v2, NULL, ptr);
    1047                 :             :     }
    1048                 :         400 :   CONSTRUCTOR_APPEND_ELT (v1, info_fields,
    1049                 :             :                           build_constructor (TREE_TYPE (info_fields), v2));
    1050                 :         400 :   info_fields = DECL_CHAIN (info_fields);
    1051                 :             : 
    1052                 :             :   /* n_functions */
    1053                 :         400 :   n_funcs = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (fn_ary)));
    1054                 :         400 :   n_funcs = fold_build2 (PLUS_EXPR, TREE_TYPE (info_fields),
    1055                 :             :                          n_funcs, size_one_node);
    1056                 :         400 :   CONSTRUCTOR_APPEND_ELT (v1, info_fields, n_funcs);
    1057                 :         400 :   info_fields = DECL_CHAIN (info_fields);
    1058                 :             : 
    1059                 :             :   /* functions */
    1060                 :         400 :   CONSTRUCTOR_APPEND_ELT (v1, info_fields,
    1061                 :             :                           build1 (ADDR_EXPR, TREE_TYPE (info_fields), fn_ary));
    1062                 :         400 :   info_fields = DECL_CHAIN (info_fields);
    1063                 :             : 
    1064                 :         400 :   gcc_assert (!info_fields);
    1065                 :         400 :   return build_constructor (info_type, v1);
    1066                 :             : }
    1067                 :             : 
    1068                 :             : /* Generate the constructor function to call __gcov_init.  */
    1069                 :             : 
    1070                 :             : static void
    1071                 :         398 : build_init_ctor (tree gcov_info_type)
    1072                 :             : {
    1073                 :         398 :   tree ctor, stmt, init_fn;
    1074                 :             : 
    1075                 :             :   /* Build a decl for __gcov_init.  */
    1076                 :         398 :   init_fn = build_pointer_type (gcov_info_type);
    1077                 :         398 :   init_fn = build_function_type_list (void_type_node, init_fn, NULL);
    1078                 :         398 :   init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
    1079                 :             :                         get_identifier ("__gcov_init"), init_fn);
    1080                 :         398 :   TREE_PUBLIC (init_fn) = 1;
    1081                 :         398 :   DECL_EXTERNAL (init_fn) = 1;
    1082                 :         398 :   DECL_ASSEMBLER_NAME (init_fn);
    1083                 :             : 
    1084                 :             :   /* Generate a call to __gcov_init(&gcov_info).  */
    1085                 :         398 :   ctor = NULL;
    1086                 :         398 :   stmt = build_fold_addr_expr (gcov_info_var);
    1087                 :         398 :   stmt = build_call_expr (init_fn, 1, stmt);
    1088                 :         398 :   append_to_statement_list (stmt, &ctor);
    1089                 :             : 
    1090                 :             :   /* Generate a constructor to run it.  */
    1091                 :         398 :   int priority = SUPPORTS_INIT_PRIORITY
    1092                 :             :     ? MAX_RESERVED_INIT_PRIORITY: DEFAULT_INIT_PRIORITY;
    1093                 :         398 :   cgraph_build_static_cdtor ('I', ctor, priority);
    1094                 :         398 : }
    1095                 :             : 
    1096                 :             : /* Generate the destructor function to call __gcov_exit.  */
    1097                 :             : 
    1098                 :             : static void
    1099                 :         398 : build_gcov_exit_decl (void)
    1100                 :             : {
    1101                 :         398 :   tree init_fn = build_function_type_list (void_type_node, NULL);
    1102                 :         398 :   init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
    1103                 :             :                         get_identifier ("__gcov_exit"), init_fn);
    1104                 :         398 :   TREE_PUBLIC (init_fn) = 1;
    1105                 :         398 :   DECL_EXTERNAL (init_fn) = 1;
    1106                 :         398 :   DECL_ASSEMBLER_NAME (init_fn);
    1107                 :             : 
    1108                 :             :   /* Generate a call to __gcov_exit ().  */
    1109                 :         398 :   tree dtor = NULL;
    1110                 :         398 :   tree stmt = build_call_expr (init_fn, 0);
    1111                 :         398 :   append_to_statement_list (stmt, &dtor);
    1112                 :             : 
    1113                 :             :   /* Generate a destructor to run it.  */
    1114                 :         398 :   int priority = SUPPORTS_INIT_PRIORITY
    1115                 :             :     ? MAX_RESERVED_INIT_PRIORITY: DEFAULT_INIT_PRIORITY;
    1116                 :             : 
    1117                 :         398 :   cgraph_build_static_cdtor ('D', dtor, priority);
    1118                 :         398 : }
    1119                 :             : 
    1120                 :             : /* Generate the pointer to the gcov_info_var in a dedicated section.  */
    1121                 :             : 
    1122                 :             : static void
    1123                 :           2 : build_gcov_info_var_registration (tree gcov_info_type)
    1124                 :             : {
    1125                 :           2 :   tree var = build_decl (BUILTINS_LOCATION,
    1126                 :             :                          VAR_DECL, NULL_TREE,
    1127                 :             :                          build_pointer_type (gcov_info_type));
    1128                 :           2 :   TREE_STATIC (var) = 1;
    1129                 :           2 :   TREE_READONLY (var) = 1;
    1130                 :           2 :   char name_buf[32];
    1131                 :           2 :   ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 2);
    1132                 :           2 :   DECL_NAME (var) = get_identifier (name_buf);
    1133                 :           2 :   get_section (profile_info_section, SECTION_UNNAMED, NULL);
    1134                 :           2 :   set_decl_section_name (var, profile_info_section);
    1135                 :           2 :   mark_decl_referenced (var);
    1136                 :           2 :   DECL_INITIAL (var) = build_fold_addr_expr (gcov_info_var);
    1137                 :           2 :   varpool_node::finalize_decl (var);
    1138                 :           2 : }
    1139                 :             : 
    1140                 :             : /* Create the gcov_info types and object.  Generate the constructor
    1141                 :             :    function to call __gcov_init.  Does not generate the initializer
    1142                 :             :    for the object.  Returns TRUE if coverage data is being emitted.  */
    1143                 :             : 
    1144                 :             : static bool
    1145                 :      225017 : coverage_obj_init (void)
    1146                 :             : {
    1147                 :      225017 :   tree gcov_info_type;
    1148                 :      225017 :   unsigned n_counters = 0;
    1149                 :      225017 :   unsigned ix;
    1150                 :      225017 :   struct coverage_data *fn;
    1151                 :      225017 :   struct coverage_data **fn_prev;
    1152                 :      225017 :   char name_buf[32];
    1153                 :             : 
    1154                 :      225017 :   no_coverage = 1; /* Disable any further coverage.  */
    1155                 :             : 
    1156                 :      225017 :   if (!prg_ctr_mask)
    1157                 :             :     return false;
    1158                 :             : 
    1159                 :         400 :   if (symtab->dump_file)
    1160                 :           3 :     fprintf (symtab->dump_file, "Using data file %s\n", da_file_name);
    1161                 :             : 
    1162                 :             :   /* Prune functions.  */
    1163                 :        2086 :   for (fn_prev = &functions_head; (fn = *fn_prev);)
    1164                 :        1686 :     if (DECL_STRUCT_FUNCTION (fn->fn_decl))
    1165                 :        1686 :       fn_prev = &fn->next;
    1166                 :             :     else
    1167                 :             :       /* The function is not being emitted, remove from list.  */
    1168                 :           0 :       *fn_prev = fn->next;
    1169                 :             : 
    1170                 :         400 :   if (functions_head == NULL)
    1171                 :             :     return false;
    1172                 :             : 
    1173                 :        4000 :   for (ix = 0; ix != GCOV_COUNTERS; ix++)
    1174                 :        3600 :     if ((1u << ix) & prg_ctr_mask)
    1175                 :         711 :       n_counters++;
    1176                 :             :   
    1177                 :             :   /* Build the info and fn_info types.  These are mutually recursive.  */
    1178                 :         400 :   gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
    1179                 :         400 :   gcov_fn_info_type = lang_hooks.types.make_type (RECORD_TYPE);
    1180                 :         400 :   build_fn_info_type (gcov_fn_info_type, n_counters, gcov_info_type);
    1181                 :         400 :   gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
    1182                 :         800 :   gcov_fn_info_ptr_type = build_pointer_type
    1183                 :         400 :     (build_qualified_type (gcov_fn_info_type, TYPE_QUAL_CONST));
    1184                 :         400 :   build_info_type (gcov_info_type, gcov_fn_info_ptr_type);
    1185                 :             :   
    1186                 :             :   /* Build the gcov info var, this is referred to in its own
    1187                 :             :      initializer.  */
    1188                 :         400 :   gcov_info_var = build_decl (BUILTINS_LOCATION,
    1189                 :             :                               VAR_DECL, NULL_TREE, gcov_info_type);
    1190                 :         400 :   TREE_STATIC (gcov_info_var) = 1;
    1191                 :         400 :   ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
    1192                 :         400 :   DECL_NAME (gcov_info_var) = get_identifier (name_buf);
    1193                 :             : 
    1194                 :         400 :   if (profile_info_section)
    1195                 :           2 :     build_gcov_info_var_registration (gcov_info_type);
    1196                 :             :   else
    1197                 :             :     {
    1198                 :         398 :       build_init_ctor (gcov_info_type);
    1199                 :         398 :       build_gcov_exit_decl ();
    1200                 :             :     }
    1201                 :             : 
    1202                 :             :   return true;
    1203                 :             : }
    1204                 :             : 
    1205                 :             : /* Generate the coverage function info for FN and DATA.  Append a
    1206                 :             :    pointer to that object to CTOR and return the appended CTOR.  */
    1207                 :             : 
    1208                 :             : static vec<constructor_elt, va_gc> *
    1209                 :        1686 : coverage_obj_fn (vec<constructor_elt, va_gc> *ctor, tree fn,
    1210                 :             :                  struct coverage_data const *data)
    1211                 :             : {
    1212                 :        1686 :   tree init = build_fn_info (data, gcov_fn_info_type, gcov_info_var);
    1213                 :        1686 :   tree var = build_var (fn, gcov_fn_info_type, -1);
    1214                 :             :   
    1215                 :        1686 :   DECL_INITIAL (var) = init;
    1216                 :        1686 :   varpool_node::finalize_decl (var);
    1217                 :             :       
    1218                 :        1686 :   CONSTRUCTOR_APPEND_ELT (ctor, NULL,
    1219                 :             :                           build1 (ADDR_EXPR, gcov_fn_info_ptr_type, var));
    1220                 :        1686 :   return ctor;
    1221                 :             : }
    1222                 :             : 
    1223                 :             : /* Finalize the coverage data.  Generates the array of pointers to
    1224                 :             :    function objects from CTOR.  Generate the gcov_info initializer.  */
    1225                 :             : 
    1226                 :             : static void
    1227                 :         400 : coverage_obj_finish (vec<constructor_elt, va_gc> *ctor,
    1228                 :             :                      unsigned object_checksum)
    1229                 :             : {
    1230                 :         400 :   unsigned n_functions = vec_safe_length (ctor);
    1231                 :         400 :   tree fn_info_ary_type = build_array_type
    1232                 :         400 :     (build_qualified_type (gcov_fn_info_ptr_type, TYPE_QUAL_CONST),
    1233                 :         400 :      build_index_type (size_int (n_functions - 1)));
    1234                 :         400 :   tree fn_info_ary = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE,
    1235                 :             :                                  fn_info_ary_type);
    1236                 :         400 :   char name_buf[32];
    1237                 :             : 
    1238                 :         400 :   TREE_STATIC (fn_info_ary) = 1;
    1239                 :         400 :   ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 1);
    1240                 :         400 :   DECL_NAME (fn_info_ary) = get_identifier (name_buf);
    1241                 :         400 :   DECL_INITIAL (fn_info_ary) = build_constructor (fn_info_ary_type, ctor);
    1242                 :         400 :   varpool_node::finalize_decl (fn_info_ary);
    1243                 :             :   
    1244                 :         400 :   DECL_INITIAL (gcov_info_var)
    1245                 :         400 :     = build_info (TREE_TYPE (gcov_info_var), fn_info_ary, object_checksum);
    1246                 :         400 :   varpool_node::finalize_decl (gcov_info_var);
    1247                 :         400 : }
    1248                 :             : 
    1249                 :             : /* Perform file-level initialization. Read in data file, generate name
    1250                 :             :    of notes file.  */
    1251                 :             : 
    1252                 :             : void
    1253                 :      274481 : coverage_init (const char *filename)
    1254                 :             : {
    1255                 :      274481 :   const char *original_filename = filename;
    1256                 :      274481 :   int original_len = strlen (original_filename);
    1257                 :             : #if HAVE_DOS_BASED_FILE_SYSTEM
    1258                 :             :   const char *separator = "\\";
    1259                 :             : #else
    1260                 :      274481 :   const char *separator = "/";
    1261                 :             : #endif
    1262                 :      274481 :   int len = strlen (filename);
    1263                 :      274481 :   int prefix_len = 0;
    1264                 :             : 
    1265                 :             :   /* Since coverage_init is invoked very early, before the pass
    1266                 :             :      manager, we need to set up the dumping explicitly. This is
    1267                 :             :      similar to the handling in finish_optimization_passes.  */
    1268                 :      274481 :   int profile_pass_num =
    1269                 :      274481 :     g->get_passes ()->get_pass_profile ()->static_pass_number;
    1270                 :      274481 :   g->get_dumps ()->dump_start (profile_pass_num, NULL);
    1271                 :             : 
    1272                 :      274481 :   if (!IS_ABSOLUTE_PATH (filename))
    1273                 :             :     {
    1274                 :             :       /* When a profile_data_prefix is provided, then mangle full path
    1275                 :             :          of filename in order to prevent file path clashing.  */
    1276                 :      256014 :       if (profile_data_prefix)
    1277                 :             :         {
    1278                 :           3 :           filename = concat (getpwd (), separator, filename, NULL);
    1279                 :           3 :           if (profile_prefix_path)
    1280                 :             :             {
    1281                 :           0 :               if (startswith (filename, profile_prefix_path))
    1282                 :             :                 {
    1283                 :           0 :                   filename += strlen (profile_prefix_path);
    1284                 :           0 :                   while (*filename == *separator)
    1285                 :           0 :                     filename++;
    1286                 :             :                 }
    1287                 :             :               else
    1288                 :           0 :                 warning (0, "filename %qs does not start with profile "
    1289                 :             :                          "prefix %qs", filename, profile_prefix_path);
    1290                 :             :             }
    1291                 :           3 :           filename = mangle_path (filename);
    1292                 :           3 :           len = strlen (filename);
    1293                 :             :         }
    1294                 :             :       else
    1295                 :      256011 :         profile_data_prefix = getpwd ();
    1296                 :             :     }
    1297                 :             : 
    1298                 :      274481 :   if (profile_data_prefix)
    1299                 :      256014 :     prefix_len = strlen (profile_data_prefix);
    1300                 :             : 
    1301                 :             :   /* Name of da file.  */
    1302                 :      274481 :   da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
    1303                 :             :                           + prefix_len + 2);
    1304                 :             : 
    1305                 :      274481 :   if (profile_data_prefix)
    1306                 :             :     {
    1307                 :      256014 :       memcpy (da_file_name, profile_data_prefix, prefix_len);
    1308                 :      256014 :       da_file_name[prefix_len++] = *separator;
    1309                 :             :     }
    1310                 :      274481 :   memcpy (da_file_name + prefix_len, filename, len);
    1311                 :      274481 :   strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX);
    1312                 :             : 
    1313                 :      274481 :   bbg_file_stamp = local_tick;
    1314                 :      274481 :   if (flag_auto_profile)
    1315                 :           0 :     read_autofdo_file ();
    1316                 :      274481 :   else if (flag_branch_probabilities)
    1317                 :         168 :     read_counts_file ();
    1318                 :             : 
    1319                 :             :   /* Name of bbg file.  */
    1320                 :      274481 :   if (flag_test_coverage && !flag_compare_debug)
    1321                 :             :     {
    1322                 :         156 :       if (profile_note_location)
    1323                 :           0 :         bbg_file_name = xstrdup (profile_note_location);
    1324                 :             :       else
    1325                 :             :         {
    1326                 :         156 :           bbg_file_name = XNEWVEC (char, original_len + strlen (GCOV_NOTE_SUFFIX) + 1);
    1327                 :         156 :           memcpy (bbg_file_name, original_filename, original_len);
    1328                 :         156 :           strcpy (bbg_file_name + original_len, GCOV_NOTE_SUFFIX);
    1329                 :             :         }
    1330                 :             : 
    1331                 :         156 :       if (!gcov_open (bbg_file_name, -1))
    1332                 :             :         {
    1333                 :           0 :           error ("cannot open %s", bbg_file_name);
    1334                 :           0 :           bbg_file_name = NULL;
    1335                 :             :         }
    1336                 :             :       else
    1337                 :             :         {
    1338                 :         156 :           gcov_write_unsigned (GCOV_NOTE_MAGIC);
    1339                 :         156 :           gcov_write_unsigned (GCOV_VERSION);
    1340                 :         156 :           gcov_write_unsigned (bbg_file_stamp);
    1341                 :             :           /* Use an arbitrary checksum */
    1342                 :         156 :           gcov_write_unsigned (0);
    1343                 :         156 :           gcov_write_string (getpwd ());
    1344                 :             : 
    1345                 :             :           /* Do not support has_unexecuted_blocks for Ada.  */
    1346                 :         156 :           gcov_write_unsigned (strcmp (lang_hooks.name, "GNU Ada") != 0);
    1347                 :             :         }
    1348                 :             :     }
    1349                 :             : 
    1350                 :      274481 :   g->get_dumps ()->dump_finish (profile_pass_num);
    1351                 :      274481 : }
    1352                 :             : 
    1353                 :             : /* Performs file-level cleanup.  Close notes file, generate coverage
    1354                 :             :    variables and constructor.  */
    1355                 :             : 
    1356                 :             : void
    1357                 :      225017 : coverage_finish (void)
    1358                 :             : {
    1359                 :      225017 :   if (bbg_file_name && gcov_close ())
    1360                 :           0 :     unlink (bbg_file_name);
    1361                 :             : 
    1362                 :      225017 :   if (!flag_branch_probabilities && flag_test_coverage
    1363                 :         156 :       && (!local_tick || local_tick == (unsigned)-1))
    1364                 :             :     /* Only remove the da file, if we're emitting coverage code and
    1365                 :             :        cannot uniquely stamp it.  If we can stamp it, libgcov will DTRT.  */
    1366                 :           0 :     unlink (da_file_name);
    1367                 :             : 
    1368                 :             :   /* Global GCDA checksum that aggregates all functions.  */
    1369                 :      225017 :   unsigned object_checksum = 0;
    1370                 :             : 
    1371                 :      225017 :   if (coverage_obj_init ())
    1372                 :             :     {
    1373                 :         400 :       vec<constructor_elt, va_gc> *fn_ctor = NULL;
    1374                 :         400 :       struct coverage_data *fn;
    1375                 :             :       
    1376                 :        2086 :       for (fn = functions_head; fn; fn = fn->next)
    1377                 :             :         {
    1378                 :        1686 :           fn_ctor = coverage_obj_fn (fn_ctor, fn->fn_decl, fn);
    1379                 :             : 
    1380                 :        1686 :           object_checksum = crc32_unsigned (object_checksum, fn->ident);
    1381                 :        1686 :           object_checksum = crc32_unsigned (object_checksum,
    1382                 :             :                                             fn->lineno_checksum);
    1383                 :        1686 :           object_checksum = crc32_unsigned (object_checksum, fn->cfg_checksum);
    1384                 :             :         }
    1385                 :         400 :       coverage_obj_finish (fn_ctor, object_checksum);
    1386                 :             :     }
    1387                 :             : 
    1388                 :      225017 :   XDELETEVEC (da_file_name);
    1389                 :      225017 :   da_file_name = NULL;
    1390                 :      225017 : }
    1391                 :             : 
    1392                 :             : #include "gt-coverage.h"
        

Generated by: LCOV version 2.1-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.