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