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