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