1 /* Read and write coverage files, and associated functionality.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
3 2000, 2001, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
4 Free Software Foundation, Inc.
5 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
6 based on some ideas from Dain Samples of UC Berkeley.
7 Further mangling by Bob Manson, Cygnus Support.
8 Further mangled by Nathan Sidwell, CodeSourcery
10 This file is part of GCC.
12 GCC is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free
14 Software Foundation; either version 3, or (at your option) any later
17 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18 WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 You should have received a copy of the GNU General Public License
23 along with GCC; see the file COPYING3. If not see
24 <http://www.gnu.org/licenses/>. */
31 #include "coretypes.h"
40 #include "basic-block.h"
45 #include "langhooks.h"
47 #include "tree-iterator.h"
49 #include "tree-pass.h"
50 #include "diagnostic-core.h"
52 #include "filenames.h"
57 struct GTY((chain_next ("%h.next"))) function_list
59 struct function_list *next; /* next function */
60 unsigned ident; /* function ident */
61 unsigned lineno_checksum; /* function lineno checksum */
62 unsigned cfg_checksum; /* function cfg checksum */
63 tree fn_decl; /* the function decl */
64 tree ctr_vars[GCOV_COUNTERS]; /* counter variables. */
67 /* Counts information for a function. */
68 typedef struct counts_entry
75 unsigned lineno_checksum;
76 unsigned cfg_checksum;
78 struct gcov_ctr_summary summary;
81 static GTY(()) struct function_list *functions_head = 0;
82 static struct function_list **functions_tail = &functions_head;
83 static unsigned no_coverage = 0;
85 /* Cumulative counter information for whole program. */
86 static unsigned prg_ctr_mask; /* Mask of counter types generated. */
88 /* Counter information for current function. */
89 static unsigned fn_ctr_mask; /* Mask of counters used. */
90 static GTY(()) tree fn_v_ctrs[GCOV_COUNTERS]; /* counter variables. */
91 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated. */
92 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base. */
94 /* Name of the output file for coverage output file. */
95 static char *bbg_file_name;
96 static unsigned bbg_file_opened;
97 static int bbg_function_announced;
99 /* Name of the count data file. */
100 static char *da_file_name;
102 /* Hash table of count data. */
103 static htab_t counts_hash = NULL;
105 /* The names of merge functions for counters. */
106 static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
107 static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
109 /* Forward declarations. */
110 static hashval_t htab_counts_entry_hash (const void *);
111 static int htab_counts_entry_eq (const void *, const void *);
112 static void htab_counts_entry_del (void *);
113 static void read_counts_file (void);
114 static tree build_var (tree, tree, int);
115 static void build_fn_info_type (tree, unsigned, tree);
116 static tree build_fn_info (const struct function_list *, tree, tree);
117 static void build_info_type (tree, unsigned, tree);
118 static tree build_info (tree, tree, tree, unsigned);
119 static void create_coverage (void);
121 /* Return the type node for gcov_type. */
126 return lang_hooks.types.type_for_size (GCOV_TYPE_SIZE, false);
129 /* Return the type node for gcov_unsigned_t. */
132 get_gcov_unsigned_t (void)
134 return lang_hooks.types.type_for_size (32, true);
138 htab_counts_entry_hash (const void *of)
140 const counts_entry_t *const entry = (const counts_entry_t *) of;
142 return entry->ident * GCOV_COUNTERS + entry->ctr;
146 htab_counts_entry_eq (const void *of1, const void *of2)
148 const counts_entry_t *const entry1 = (const counts_entry_t *) of1;
149 const counts_entry_t *const entry2 = (const counts_entry_t *) of2;
151 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
155 htab_counts_entry_del (void *of)
157 counts_entry_t *const entry = (counts_entry_t *) of;
159 free (entry->counts);
163 /* Read in the counts file, if available. */
166 read_counts_file (void)
168 gcov_unsigned_t fn_ident = 0;
169 struct gcov_summary summary;
170 unsigned new_summary = 1;
173 unsigned lineno_checksum = 0;
174 unsigned cfg_checksum = 0;
176 if (!gcov_open (da_file_name, 1))
179 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
181 warning (0, "%qs is not a gcov data file", da_file_name);
185 else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
189 GCOV_UNSIGNED2STRING (v, tag);
190 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
192 warning (0, "%qs is version %q.*s, expected version %q.*s",
193 da_file_name, 4, v, 4, e);
198 /* Read and discard the stamp. */
199 gcov_read_unsigned ();
201 counts_hash = htab_create (10,
202 htab_counts_entry_hash, htab_counts_entry_eq,
203 htab_counts_entry_del);
204 while ((tag = gcov_read_unsigned ()))
206 gcov_unsigned_t length;
207 gcov_position_t offset;
209 length = gcov_read_unsigned ();
210 offset = gcov_position ();
211 if (tag == GCOV_TAG_FUNCTION)
215 fn_ident = gcov_read_unsigned ();
216 lineno_checksum = gcov_read_unsigned ();
217 cfg_checksum = gcov_read_unsigned ();
220 fn_ident = lineno_checksum = cfg_checksum = 0;
223 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
225 struct gcov_summary sum;
229 memset (&summary, 0, sizeof (summary));
231 gcov_read_summary (&sum);
232 for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++)
234 summary.ctrs[ix].runs += sum.ctrs[ix].runs;
235 summary.ctrs[ix].sum_all += sum.ctrs[ix].sum_all;
236 if (summary.ctrs[ix].run_max < sum.ctrs[ix].run_max)
237 summary.ctrs[ix].run_max = sum.ctrs[ix].run_max;
238 summary.ctrs[ix].sum_max += sum.ctrs[ix].sum_max;
242 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
244 counts_entry_t **slot, *entry, elt;
245 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
248 elt.ident = fn_ident;
249 elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
251 slot = (counts_entry_t **) htab_find_slot
252 (counts_hash, &elt, INSERT);
256 *slot = entry = XCNEW (counts_entry_t);
257 entry->ident = fn_ident;
258 entry->ctr = elt.ctr;
259 entry->lineno_checksum = lineno_checksum;
260 entry->cfg_checksum = cfg_checksum;
261 entry->summary = summary.ctrs[elt.ctr];
262 entry->summary.num = n_counts;
263 entry->counts = XCNEWVEC (gcov_type, n_counts);
265 else if (entry->lineno_checksum != lineno_checksum
266 || entry->cfg_checksum != cfg_checksum)
268 error ("Profile data for function %u is corrupted", fn_ident);
269 error ("checksum is (%x,%x) instead of (%x,%x)",
270 entry->lineno_checksum, entry->cfg_checksum,
271 lineno_checksum, cfg_checksum);
272 htab_delete (counts_hash);
275 else if (entry->summary.num != n_counts)
277 error ("Profile data for function %u is corrupted", fn_ident);
278 error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
279 htab_delete (counts_hash);
282 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
284 error ("cannot merge separate %s counters for function %u",
285 ctr_names[elt.ctr], fn_ident);
290 entry->summary.runs += summary.ctrs[elt.ctr].runs;
291 entry->summary.sum_all += summary.ctrs[elt.ctr].sum_all;
292 if (entry->summary.run_max < summary.ctrs[elt.ctr].run_max)
293 entry->summary.run_max = summary.ctrs[elt.ctr].run_max;
294 entry->summary.sum_max += summary.ctrs[elt.ctr].sum_max;
296 for (ix = 0; ix != n_counts; ix++)
297 entry->counts[ix] += gcov_read_counter ();
300 gcov_sync (offset, length);
301 if ((is_error = gcov_is_error ()))
303 error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted",
305 htab_delete (counts_hash);
313 /* Returns the counters for a particular tag. */
316 get_coverage_counts (unsigned counter, unsigned expected,
317 unsigned cfg_checksum, unsigned lineno_checksum,
318 const struct gcov_ctr_summary **summary)
320 counts_entry_t *entry, elt;
322 /* No hash table, no counts. */
325 static int warned = 0;
328 inform (input_location, (flag_guess_branch_prob
329 ? "file %s not found, execution counts estimated"
330 : "file %s not found, execution counts assumed to be zero"),
335 elt.ident = current_function_funcdef_no + 1;
337 entry = (counts_entry_t *) htab_find (counts_hash, &elt);
338 if (!entry || !entry->summary.num)
339 /* The function was not emitted, or is weak and not chosen in the
340 final executable. Silently fail, because there's nothing we
344 if (entry->cfg_checksum != cfg_checksum
345 || entry->summary.num != expected)
347 static int warned = 0;
348 bool warning_printed = false;
349 tree id = DECL_ASSEMBLER_NAME (current_function_decl);
352 warning_at (input_location, OPT_Wcoverage_mismatch,
353 "the control flow of function %qE does not match "
354 "its profile data (counter %qs)", id, ctr_names[counter]);
357 inform (input_location, "use -Wno-error=coverage-mismatch to tolerate "
358 "the mismatch but performance may drop if the function is hot");
363 inform (input_location, "coverage mismatch ignored");
364 inform (input_location, flag_guess_branch_prob
365 ? G_("execution counts estimated")
366 : G_("execution counts assumed to be zero"));
367 if (!flag_guess_branch_prob)
368 inform (input_location,
369 "this can result in poorly optimized code");
375 else if (entry->lineno_checksum != lineno_checksum)
377 warning (0, "source location for function %qE have changed,"
378 " the profile data may be out of date",
379 DECL_ASSEMBLER_NAME (current_function_decl));
383 *summary = &entry->summary;
385 return entry->counts;
388 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
389 allocation succeeded. */
392 coverage_counter_alloc (unsigned counter, unsigned num)
400 if (!fn_v_ctrs[counter])
402 tree array_type = build_array_type (get_gcov_type (), NULL_TREE);
405 = build_var (current_function_decl, array_type, counter);
408 fn_b_ctrs[counter] = fn_n_ctrs[counter];
409 fn_n_ctrs[counter] += num;
411 fn_ctr_mask |= 1 << counter;
415 /* Generate a tree to access COUNTER NO. */
418 tree_coverage_counter_ref (unsigned counter, unsigned no)
420 tree gcov_type_node = get_gcov_type ();
422 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
424 no += fn_b_ctrs[counter];
426 /* "no" here is an array index, scaled to bytes later. */
427 return build4 (ARRAY_REF, gcov_type_node, fn_v_ctrs[counter],
428 build_int_cst (integer_type_node, no), NULL, NULL);
431 /* Generate a tree to access the address of COUNTER NO. */
434 tree_coverage_counter_addr (unsigned counter, unsigned no)
436 tree gcov_type_node = get_gcov_type ();
438 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
439 no += fn_b_ctrs[counter];
441 /* "no" here is an array index, scaled to bytes later. */
442 return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node,
444 build_int_cst (integer_type_node, no),
449 /* Generate a checksum for a string. CHKSUM is the current
453 coverage_checksum_string (unsigned chksum, const char *string)
458 /* Look for everything that looks if it were produced by
459 get_file_function_name and zero out the second part
460 that may result from flag_random_seed. This is not critical
461 as the checksums are used only for sanity checking. */
462 for (i = 0; string[i]; i++)
465 if (!strncmp (string + i, "_GLOBAL__N_", 11))
467 if (!strncmp (string + i, "_GLOBAL__", 9))
470 /* C++ namespaces do have scheme:
471 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
472 since filename might contain extra underscores there seems
473 to be no better chance then walk all possible offsets looking
477 for (i = i + offset; string[i]; i++)
482 for (y = 1; y < 9; y++)
483 if (!(string[i + y] >= '0' && string[i + y] <= '9')
484 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
486 if (y != 9 || string[i + 9] != '_')
488 for (y = 10; y < 18; y++)
489 if (!(string[i + y] >= '0' && string[i + y] <= '9')
490 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
495 string = dup = xstrdup (string);
496 for (y = 10; y < 18; y++)
503 chksum = crc32_string (chksum, string);
509 /* Compute checksum for the current function. We generate a CRC32. */
512 coverage_compute_lineno_checksum (void)
514 expanded_location xloc
515 = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
516 unsigned chksum = xloc.line;
518 chksum = coverage_checksum_string (chksum, xloc.file);
519 chksum = coverage_checksum_string
520 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
525 /* Compute cfg checksum for the current function.
526 The checksum is calculated carefully so that
527 source code changes that doesn't affect the control flow graph
528 won't change the checksum.
529 This is to make the profile data useable across source code change.
530 The downside of this is that the compiler may use potentially
531 wrong profile data - that the source code change has non-trivial impact
532 on the validity of profile data (e.g. the reversed condition)
533 but the compiler won't detect the change and use the wrong profile data. */
536 coverage_compute_cfg_checksum (void)
539 unsigned chksum = n_basic_blocks;
545 chksum = crc32_byte (chksum, bb->index);
546 FOR_EACH_EDGE (e, ei, bb->succs)
548 chksum = crc32_byte (chksum, e->dest->index);
555 /* Begin output to the graph file for the current function.
556 Opens the output file, if not already done. Writes the
557 function header, if not already done. Returns nonzero if data
561 coverage_begin_output (unsigned lineno_checksum, unsigned cfg_checksum)
563 /* We don't need to output .gcno file unless we're under -ftest-coverage
564 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
565 if (no_coverage || !flag_test_coverage || flag_compare_debug)
568 if (!bbg_function_announced)
570 expanded_location xloc
571 = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
572 unsigned long offset;
574 if (!bbg_file_opened)
576 if (!gcov_open (bbg_file_name, -1))
577 error ("cannot open %s", bbg_file_name);
580 gcov_write_unsigned (GCOV_NOTE_MAGIC);
581 gcov_write_unsigned (GCOV_VERSION);
582 gcov_write_unsigned (local_tick);
588 /* Announce function */
589 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
590 gcov_write_unsigned (current_function_funcdef_no + 1);
591 gcov_write_unsigned (lineno_checksum);
592 gcov_write_unsigned (cfg_checksum);
593 gcov_write_string (IDENTIFIER_POINTER
594 (DECL_ASSEMBLER_NAME (current_function_decl)));
595 gcov_write_string (xloc.file);
596 gcov_write_unsigned (xloc.line);
597 gcov_write_length (offset);
599 bbg_function_announced = 1;
601 return !gcov_is_error ();
604 /* Finish coverage data for the current function. Verify no output
605 error has occurred. Save function coverage counts. */
608 coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum)
612 if (bbg_file_opened > 1 && gcov_is_error ())
614 warning (0, "error writing %qs", bbg_file_name);
615 bbg_file_opened = -1;
620 struct function_list *item;
622 item = ggc_alloc_function_list ();
625 item->ident = current_function_funcdef_no + 1;
626 item->lineno_checksum = lineno_checksum;
627 item->cfg_checksum = cfg_checksum;
628 item->fn_decl = current_function_decl;
629 for (i = 0; i != GCOV_COUNTERS; i++)
631 tree var = fn_v_ctrs[i];
633 item->ctr_vars[i] = var;
636 tree array_type = build_index_type (size_int (fn_n_ctrs[i] - 1));
637 array_type = build_array_type (get_gcov_type (), array_type);
638 TREE_TYPE (var) = array_type;
639 DECL_SIZE (var) = TYPE_SIZE (array_type);
640 DECL_SIZE_UNIT (var) = TYPE_SIZE_UNIT (array_type);
641 varpool_finalize_decl (var);
643 fn_b_ctrs[i] = fn_n_ctrs[i] = 0;
644 fn_v_ctrs[i] = NULL_TREE;
646 prg_ctr_mask |= fn_ctr_mask;
648 /* If the function is extern (i.e. extern inline), then we won't
649 be outputting it, so don't chain it onto the function list. */
650 if (!DECL_EXTERNAL (item->fn_decl))
652 *functions_tail = item;
653 functions_tail = &item->next;
656 bbg_function_announced = 0;
659 /* Build a coverage variable of TYPE for function FN_DECL. If COUNTER
660 >= 0 it is a counter array, otherwise it is the function structure.
661 Propagate appropriate linkage and visibility from the function decl. */
664 build_var (tree fn_decl, tree type, int counter)
666 tree var = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, type);
667 tree fn_name = DECL_ASSEMBLER_NAME (fn_decl);
668 char *buf = (char *)alloca (IDENTIFIER_LENGTH (fn_name) + 10);
671 sprintf (buf, "__gcov__%s", IDENTIFIER_POINTER (fn_name));
673 sprintf (buf, "__gcov%u_%s", counter, IDENTIFIER_POINTER (fn_name));
674 DECL_NAME (var) = get_identifier (buf);
675 TREE_STATIC (var) = 1;
676 TREE_ADDRESSABLE (var) = 1;
677 DECL_ALIGN (var) = TYPE_ALIGN (type);
678 DECL_WEAK (var) = DECL_WEAK (fn_decl);
680 = TREE_PUBLIC (fn_decl) && (counter < 0 || DECL_WEAK (fn_decl));
681 if (DECL_ONE_ONLY (fn_decl))
682 make_decl_one_only (var, DECL_COMDAT_GROUP (fn_decl));
684 if (TREE_PUBLIC (var))
686 DECL_VISIBILITY (var) = DECL_VISIBILITY (fn_decl);
687 DECL_VISIBILITY_SPECIFIED (var)
688 = DECL_VISIBILITY_SPECIFIED (fn_decl);
690 /* Initialize assembler name so we can stream out. */
691 DECL_ASSEMBLER_NAME (var);
697 /* Creates the gcov_fn_info RECORD_TYPE. */
700 build_fn_info_type (tree type, unsigned counters, tree gcov_info_type)
702 tree ctr_info = lang_hooks.types.make_type (RECORD_TYPE);
706 gcc_assert (counters);
709 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
710 get_gcov_unsigned_t ());
713 /* ctr_info::values */
714 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
715 build_pointer_type (get_gcov_type ()));
716 DECL_CHAIN (field) = fields;
719 finish_builtin_struct (ctr_info, "__gcov_ctr_info", fields, NULL_TREE);
722 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
723 build_pointer_type (build_qualified_type
724 (gcov_info_type, TYPE_QUAL_CONST)));
728 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
729 get_gcov_unsigned_t ());
730 DECL_CHAIN (field) = fields;
733 /* lineno_checksum */
734 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
735 get_gcov_unsigned_t ());
736 DECL_CHAIN (field) = fields;
740 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
741 get_gcov_unsigned_t ());
742 DECL_CHAIN (field) = fields;
745 array_type = build_index_type (size_int (counters - 1));
746 array_type = build_array_type (ctr_info, array_type);
749 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, array_type);
750 DECL_CHAIN (field) = fields;
753 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
756 /* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is
757 the function being processed and TYPE is the gcov_fn_info
758 RECORD_TYPE. KEY is the object file key. */
761 build_fn_info (const struct function_list *function, tree type, tree key)
763 tree fields = TYPE_FIELDS (type);
766 VEC(constructor_elt,gc) *v1 = NULL;
767 VEC(constructor_elt,gc) *v2 = NULL;
770 CONSTRUCTOR_APPEND_ELT (v1, fields,
771 build1 (ADDR_EXPR, TREE_TYPE (fields), key));
772 fields = DECL_CHAIN (fields);
775 CONSTRUCTOR_APPEND_ELT (v1, fields,
776 build_int_cstu (get_gcov_unsigned_t (),
778 fields = DECL_CHAIN (fields);
780 /* lineno_checksum */
781 CONSTRUCTOR_APPEND_ELT (v1, fields,
782 build_int_cstu (get_gcov_unsigned_t (),
783 function->lineno_checksum));
784 fields = DECL_CHAIN (fields);
787 CONSTRUCTOR_APPEND_ELT (v1, fields,
788 build_int_cstu (get_gcov_unsigned_t (),
789 function->cfg_checksum));
790 fields = DECL_CHAIN (fields);
793 ctr_type = TREE_TYPE (TREE_TYPE (fields));
794 for (ix = 0; ix != GCOV_COUNTERS; ix++)
795 if (prg_ctr_mask & (1 << ix))
797 VEC(constructor_elt,gc) *ctr = NULL;
798 tree var = function->ctr_vars[ix];
803 = tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var))), 0)
806 CONSTRUCTOR_APPEND_ELT (ctr, TYPE_FIELDS (ctr_type),
807 build_int_cstu (get_gcov_unsigned_t (),
811 CONSTRUCTOR_APPEND_ELT (ctr, DECL_CHAIN (TYPE_FIELDS (ctr_type)),
812 build_fold_addr_expr (var));
814 CONSTRUCTOR_APPEND_ELT (v2, NULL, build_constructor (ctr_type, ctr));
817 CONSTRUCTOR_APPEND_ELT (v1, fields,
818 build_constructor (TREE_TYPE (fields), v2));
820 return build_constructor (type, v1);
823 /* Creaste gcov_info_struct. N_FUNCS is the number of functions in
824 the trailing array. */
827 build_info_type (tree type, unsigned n_funcs, tree fn_info_type)
829 tree field, fields = NULL_TREE;
830 tree merge_fn_type, fn_info_array;
832 gcc_assert (n_funcs);
835 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
836 get_gcov_unsigned_t ());
837 DECL_CHAIN (field) = fields;
841 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
842 build_pointer_type (build_qualified_type
843 (type, TYPE_QUAL_CONST)));
844 DECL_CHAIN (field) = fields;
848 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
849 get_gcov_unsigned_t ());
850 DECL_CHAIN (field) = fields;
854 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
855 build_pointer_type (build_qualified_type
856 (char_type_node, TYPE_QUAL_CONST)));
857 DECL_CHAIN (field) = fields;
862 = build_function_type_list (void_type_node,
863 build_pointer_type (get_gcov_type ()),
864 get_gcov_unsigned_t (), NULL_TREE);
866 = build_array_type (build_pointer_type (merge_fn_type),
867 build_index_type (size_int (GCOV_COUNTERS - 1)));
868 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
870 DECL_CHAIN (field) = fields;
874 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
875 get_gcov_unsigned_t ());
876 DECL_CHAIN (field) = fields;
879 /* function_info pointer array */
880 fn_info_type = build_pointer_type
881 (build_qualified_type (fn_info_type, TYPE_QUAL_CONST));
882 fn_info_array = build_index_type (size_int (n_funcs));
883 fn_info_array = build_array_type (fn_info_type, fn_info_array);
884 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
886 DECL_CHAIN (field) = fields;
889 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
892 /* Creates the gcov_info initializer. Returns a CONSTRUCTOR. */
895 build_info (tree info_type, tree fn_type, tree key_var, unsigned n_funcs)
897 tree info_fields = TYPE_FIELDS (info_type);
898 tree merge_fn_type, fn_info_ptr_type;
900 tree filename_string;
901 int da_file_name_len;
902 const struct function_list *fn;
903 VEC(constructor_elt,gc) *v1 = NULL;
904 VEC(constructor_elt,gc) *v2 = NULL;
905 VEC(constructor_elt,gc) *v3 = NULL;
908 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
909 build_int_cstu (TREE_TYPE (info_fields),
911 info_fields = DECL_CHAIN (info_fields);
914 CONSTRUCTOR_APPEND_ELT (v1, info_fields, null_pointer_node);
915 info_fields = DECL_CHAIN (info_fields);
918 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
919 build_int_cstu (TREE_TYPE (info_fields),
921 info_fields = DECL_CHAIN (info_fields);
924 da_file_name_len = strlen (da_file_name);
925 filename_string = build_string (da_file_name_len + 1, da_file_name);
926 TREE_TYPE (filename_string) = build_array_type
927 (char_type_node, build_index_type (size_int (da_file_name_len)));
928 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
929 build1 (ADDR_EXPR, TREE_TYPE (info_fields),
931 info_fields = DECL_CHAIN (info_fields);
933 /* merge fn array -- NULL slots indicate unmeasured counters */
934 merge_fn_type = TREE_TYPE (TREE_TYPE (info_fields));
935 for (ix = 0; ix != GCOV_COUNTERS; ix++)
937 tree ptr = null_pointer_node;
939 if ((1u << ix) & prg_ctr_mask)
941 tree merge_fn = build_decl (BUILTINS_LOCATION,
943 get_identifier (ctr_merge_functions[ix]),
944 TREE_TYPE (merge_fn_type));
945 DECL_EXTERNAL (merge_fn) = 1;
946 TREE_PUBLIC (merge_fn) = 1;
947 DECL_ARTIFICIAL (merge_fn) = 1;
948 TREE_NOTHROW (merge_fn) = 1;
949 /* Initialize assembler name so we can stream out. */
950 DECL_ASSEMBLER_NAME (merge_fn);
951 ptr = build1 (ADDR_EXPR, merge_fn_type, merge_fn);
953 CONSTRUCTOR_APPEND_ELT (v2, NULL, ptr);
955 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
956 build_constructor (TREE_TYPE (info_fields), v2));
957 info_fields = DECL_CHAIN (info_fields);
960 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
961 build_int_cstu (TREE_TYPE (info_fields), n_funcs));
962 info_fields = DECL_CHAIN (info_fields);
964 /* Build the fn_info type and initializer. */
965 fn_info_ptr_type = TREE_TYPE (TREE_TYPE (info_fields));
967 for (fn = functions_head; fn; fn = fn->next)
969 tree init = build_fn_info (fn, fn_type, key_var);
970 tree var = build_var (fn->fn_decl, fn_type, -1);
972 DECL_INITIAL (var) = init;
973 varpool_finalize_decl (var);
975 CONSTRUCTOR_APPEND_ELT (v3, NULL,
976 build1 (ADDR_EXPR, fn_info_ptr_type, var));
978 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
979 build_constructor (TREE_TYPE (info_fields), v3));
980 return build_constructor (info_type, v1);
983 /* Write out the structure which libgcov uses to locate all the
984 counters. The structures used here must match those defined in
985 gcov-io.h. Write out the constructor to call __gcov_init. */
988 create_coverage (void)
990 tree gcov_info, gcov_init, body, t;
991 tree gcov_info_type, gcov_fn_type;
992 unsigned n_counters = 0, n_functions = 0;
993 struct function_list *fn;
994 struct function_list **fn_prev;
998 no_coverage = 1; /* Disable any further coverage. */
1003 if (cgraph_dump_file)
1004 fprintf (cgraph_dump_file, "Using data file %s\n", da_file_name);
1006 for (ix = 0; ix != GCOV_COUNTERS; ix++)
1007 if ((1u << ix) & prg_ctr_mask)
1009 for (fn_prev = &functions_head; (fn = *fn_prev);)
1010 if (DECL_STRUCT_FUNCTION (fn->fn_decl))
1013 fn_prev = &fn->next;
1016 /* The function is not being emitted, remove from list. */
1017 *fn_prev = fn->next;
1019 /* Build the info and fn_info types. These are mutually recursive. */
1020 gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1021 gcov_fn_type = lang_hooks.types.make_type (RECORD_TYPE);
1022 build_fn_info_type (gcov_fn_type, n_counters, gcov_info_type);
1023 build_info_type (gcov_info_type, n_functions, gcov_fn_type);
1025 /* Build the gcov info var, this is referred to in its own
1027 gcov_info = build_decl (BUILTINS_LOCATION,
1028 VAR_DECL, NULL_TREE, gcov_info_type);
1029 TREE_STATIC (gcov_info) = 1;
1030 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
1031 DECL_NAME (gcov_info) = get_identifier (name_buf);
1032 DECL_INITIAL (gcov_info) = build_info (gcov_info_type, gcov_fn_type,
1033 gcov_info, n_functions);
1035 /* Build structure. */
1036 varpool_finalize_decl (gcov_info);
1038 /* Build a decl for __gcov_init. */
1039 t = build_pointer_type (TREE_TYPE (gcov_info));
1040 t = build_function_type_list (void_type_node, t, NULL);
1041 t = build_decl (BUILTINS_LOCATION,
1042 FUNCTION_DECL, get_identifier ("__gcov_init"), t);
1043 TREE_PUBLIC (t) = 1;
1044 DECL_EXTERNAL (t) = 1;
1045 DECL_ASSEMBLER_NAME (t); /* Initialize assembler name so we can stream out. */
1048 /* Generate a call to __gcov_init(&gcov_info). */
1050 t = build_fold_addr_expr (gcov_info);
1051 t = build_call_expr (gcov_init, 1, t);
1052 append_to_statement_list (t, &body);
1054 /* Generate a constructor to run it. */
1055 cgraph_build_static_cdtor ('I', body, DEFAULT_INIT_PRIORITY);
1058 /* Perform file-level initialization. Read in data file, generate name
1062 coverage_init (const char *filename)
1064 int len = strlen (filename);
1065 /* + 1 for extra '/', in case prefix doesn't end with /. */
1068 if (profile_data_prefix == 0 && !IS_ABSOLUTE_PATH(&filename[0]))
1069 profile_data_prefix = getpwd ();
1071 prefix_len = (profile_data_prefix) ? strlen (profile_data_prefix) + 1 : 0;
1073 /* Name of da file. */
1074 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
1077 if (profile_data_prefix)
1079 strcpy (da_file_name, profile_data_prefix);
1080 da_file_name[prefix_len - 1] = '/';
1081 da_file_name[prefix_len] = 0;
1084 da_file_name[0] = 0;
1085 strcat (da_file_name, filename);
1086 strcat (da_file_name, GCOV_DATA_SUFFIX);
1088 /* Name of bbg file. */
1089 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1);
1090 strcpy (bbg_file_name, filename);
1091 strcat (bbg_file_name, GCOV_NOTE_SUFFIX);
1093 if (flag_branch_probabilities)
1094 read_counts_file ();
1097 /* Performs file-level cleanup. Close graph file, generate coverage
1098 variables and constructor. */
1101 coverage_finish (void)
1104 if (bbg_file_opened)
1106 int error = gcov_close ();
1109 unlink (bbg_file_name);
1111 /* Only remove the da file, if we cannot stamp it. If we can
1112 stamp it, libgcov will DTRT. */
1113 unlink (da_file_name);
1117 #include "gt-coverage.h"