Daily bump.
[official-gcc.git] / gcc / coverage.c
blob3fea525a08d8b493a8b58003599e8a21fa3e1f2e
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, 2012
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
15 version.
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
20 for more details.
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/>. */
27 #define GCOV_LINKAGE
29 #include "config.h"
30 #include "system.h"
31 #include "coretypes.h"
32 #include "tm.h"
33 #include "rtl.h"
34 #include "tree.h"
35 #include "flags.h"
36 #include "output.h"
37 #include "regs.h"
38 #include "expr.h"
39 #include "function.h"
40 #include "basic-block.h"
41 #include "toplev.h"
42 #include "tm_p.h"
43 #include "ggc.h"
44 #include "coverage.h"
45 #include "langhooks.h"
46 #include "hash-table.h"
47 #include "tree-iterator.h"
48 #include "cgraph.h"
49 #include "dumpfile.h"
50 #include "diagnostic-core.h"
51 #include "intl.h"
52 #include "filenames.h"
53 #include "target.h"
55 #include "gcov-io.h"
56 #include "gcov-io.c"
58 struct GTY((chain_next ("%h.next"))) coverage_data
60 struct coverage_data *next; /* next function */
61 unsigned ident; /* function ident */
62 unsigned lineno_checksum; /* function lineno checksum */
63 unsigned cfg_checksum; /* function cfg checksum */
64 tree fn_decl; /* the function decl */
65 tree ctr_vars[GCOV_COUNTERS]; /* counter variables. */
68 /* Counts information for a function. */
69 typedef struct counts_entry
71 /* We hash by */
72 unsigned ident;
73 unsigned ctr;
75 /* Store */
76 unsigned lineno_checksum;
77 unsigned cfg_checksum;
78 gcov_type *counts;
79 struct gcov_ctr_summary summary;
80 } counts_entry_t;
82 static GTY(()) struct coverage_data *functions_head = 0;
83 static struct coverage_data **functions_tail = &functions_head;
84 static unsigned no_coverage = 0;
86 /* Cumulative counter information for whole program. */
87 static unsigned prg_ctr_mask; /* Mask of counter types generated. */
89 /* Counter information for current function. */
90 static unsigned fn_ctr_mask; /* Mask of counters used. */
91 static GTY(()) tree fn_v_ctrs[GCOV_COUNTERS]; /* counter variables. */
92 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated. */
93 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base. */
95 /* Coverage info VAR_DECL and function info type nodes. */
96 static GTY(()) tree gcov_info_var;
97 static GTY(()) tree gcov_fn_info_type;
98 static GTY(()) tree gcov_fn_info_ptr_type;
100 /* Name of the notes (gcno) output file. The "bbg" prefix is for
101 historical reasons, when the notes file contained only the
102 basic block graph notes.
103 If this is NULL we're not writing to the notes file. */
104 static char *bbg_file_name;
106 /* File stamp for notes file. */
107 static unsigned bbg_file_stamp;
109 /* Name of the count data (gcda) file. */
110 static char *da_file_name;
112 /* The names of merge functions for counters. */
113 static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
114 static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
116 /* Forward declarations. */
117 static void read_counts_file (void);
118 static tree build_var (tree, tree, int);
119 static void build_fn_info_type (tree, unsigned, tree);
120 static void build_info_type (tree, tree);
121 static tree build_fn_info (const struct coverage_data *, tree, tree);
122 static tree build_info (tree, tree);
123 static bool coverage_obj_init (void);
124 static VEC(constructor_elt,gc) *coverage_obj_fn
125 (VEC(constructor_elt,gc) *, tree, struct coverage_data const *);
126 static void coverage_obj_finish (VEC(constructor_elt,gc) *);
128 /* Return the type node for gcov_type. */
130 tree
131 get_gcov_type (void)
133 enum machine_mode mode = smallest_mode_for_size (GCOV_TYPE_SIZE, MODE_INT);
134 return lang_hooks.types.type_for_mode (mode, false);
137 /* Return the type node for gcov_unsigned_t. */
139 static tree
140 get_gcov_unsigned_t (void)
142 enum machine_mode mode = smallest_mode_for_size (32, MODE_INT);
143 return lang_hooks.types.type_for_mode (mode, true);
146 inline hashval_t
147 coverage_counts_entry_hash (const counts_entry_t *entry)
149 return entry->ident * GCOV_COUNTERS + entry->ctr;
152 inline int
153 coverage_counts_entry_eq (const counts_entry_t *entry1,
154 const counts_entry_t *entry2)
156 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
159 inline void
160 coverage_counts_entry_del (counts_entry_t *entry)
162 free (entry->counts);
163 free (entry);
166 /* Hash table of count data. */
167 static hash_table <counts_entry_t, coverage_counts_entry_hash,
168 coverage_counts_entry_eq, coverage_counts_entry_del>
169 counts_hash;
171 /* Read in the counts file, if available. */
173 static void
174 read_counts_file (void)
176 gcov_unsigned_t fn_ident = 0;
177 struct gcov_summary summary;
178 unsigned new_summary = 1;
179 gcov_unsigned_t tag;
180 int is_error = 0;
181 unsigned lineno_checksum = 0;
182 unsigned cfg_checksum = 0;
184 if (!gcov_open (da_file_name, 1))
185 return;
187 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
189 warning (0, "%qs is not a gcov data file", da_file_name);
190 gcov_close ();
191 return;
193 else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
195 char v[4], e[4];
197 GCOV_UNSIGNED2STRING (v, tag);
198 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
200 warning (0, "%qs is version %q.*s, expected version %q.*s",
201 da_file_name, 4, v, 4, e);
202 gcov_close ();
203 return;
206 /* Read the stamp, used for creating a generation count. */
207 tag = gcov_read_unsigned ();
208 bbg_file_stamp = crc32_unsigned (bbg_file_stamp, tag);
210 counts_hash.create (10);
211 while ((tag = gcov_read_unsigned ()))
213 gcov_unsigned_t length;
214 gcov_position_t offset;
216 length = gcov_read_unsigned ();
217 offset = gcov_position ();
218 if (tag == GCOV_TAG_FUNCTION)
220 if (length)
222 fn_ident = gcov_read_unsigned ();
223 lineno_checksum = gcov_read_unsigned ();
224 cfg_checksum = gcov_read_unsigned ();
226 else
227 fn_ident = lineno_checksum = cfg_checksum = 0;
228 new_summary = 1;
230 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
232 struct gcov_summary sum;
233 unsigned ix;
235 if (new_summary)
236 memset (&summary, 0, sizeof (summary));
238 gcov_read_summary (&sum);
239 for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++)
241 summary.ctrs[ix].runs += sum.ctrs[ix].runs;
242 summary.ctrs[ix].sum_all += sum.ctrs[ix].sum_all;
243 if (summary.ctrs[ix].run_max < sum.ctrs[ix].run_max)
244 summary.ctrs[ix].run_max = sum.ctrs[ix].run_max;
245 summary.ctrs[ix].sum_max += sum.ctrs[ix].sum_max;
247 new_summary = 0;
249 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
251 counts_entry_t **slot, *entry, elt;
252 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
253 unsigned ix;
255 elt.ident = fn_ident;
256 elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
258 slot = counts_hash.find_slot (&elt, INSERT);
259 entry = *slot;
260 if (!entry)
262 *slot = entry = XCNEW (counts_entry_t);
263 entry->ident = fn_ident;
264 entry->ctr = elt.ctr;
265 entry->lineno_checksum = lineno_checksum;
266 entry->cfg_checksum = cfg_checksum;
267 entry->summary = summary.ctrs[elt.ctr];
268 entry->summary.num = n_counts;
269 entry->counts = XCNEWVEC (gcov_type, n_counts);
271 else if (entry->lineno_checksum != lineno_checksum
272 || entry->cfg_checksum != cfg_checksum)
274 error ("Profile data for function %u is corrupted", fn_ident);
275 error ("checksum is (%x,%x) instead of (%x,%x)",
276 entry->lineno_checksum, entry->cfg_checksum,
277 lineno_checksum, cfg_checksum);
278 counts_hash.dispose ();
279 break;
281 else if (entry->summary.num != n_counts)
283 error ("Profile data for function %u is corrupted", fn_ident);
284 error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
285 counts_hash.dispose ();
286 break;
288 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
290 error ("cannot merge separate %s counters for function %u",
291 ctr_names[elt.ctr], fn_ident);
292 goto skip_merge;
294 else
296 entry->summary.runs += summary.ctrs[elt.ctr].runs;
297 entry->summary.sum_all += summary.ctrs[elt.ctr].sum_all;
298 if (entry->summary.run_max < summary.ctrs[elt.ctr].run_max)
299 entry->summary.run_max = summary.ctrs[elt.ctr].run_max;
300 entry->summary.sum_max += summary.ctrs[elt.ctr].sum_max;
302 for (ix = 0; ix != n_counts; ix++)
303 entry->counts[ix] += gcov_read_counter ();
304 skip_merge:;
306 gcov_sync (offset, length);
307 if ((is_error = gcov_is_error ()))
309 error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted",
310 da_file_name);
311 counts_hash.dispose ();
312 break;
316 gcov_close ();
319 /* Returns the counters for a particular tag. */
321 gcov_type *
322 get_coverage_counts (unsigned counter, unsigned expected,
323 unsigned cfg_checksum, unsigned lineno_checksum,
324 const struct gcov_ctr_summary **summary)
326 counts_entry_t *entry, elt;
328 /* No hash table, no counts. */
329 if (!counts_hash.is_created ())
331 static int warned = 0;
333 if (!warned++)
334 inform (input_location, (flag_guess_branch_prob
335 ? "file %s not found, execution counts estimated"
336 : "file %s not found, execution counts assumed to be zero"),
337 da_file_name);
338 return NULL;
341 elt.ident = current_function_funcdef_no + 1;
342 elt.ctr = counter;
343 entry = counts_hash.find (&elt);
344 if (!entry || !entry->summary.num)
345 /* The function was not emitted, or is weak and not chosen in the
346 final executable. Silently fail, because there's nothing we
347 can do about it. */
348 return NULL;
350 if (entry->cfg_checksum != cfg_checksum
351 || entry->summary.num != expected)
353 static int warned = 0;
354 bool warning_printed = false;
355 tree id = DECL_ASSEMBLER_NAME (current_function_decl);
357 warning_printed =
358 warning_at (input_location, OPT_Wcoverage_mismatch,
359 "the control flow of function %qE does not match "
360 "its profile data (counter %qs)", id, ctr_names[counter]);
361 if (warning_printed)
363 inform (input_location, "use -Wno-error=coverage-mismatch to tolerate "
364 "the mismatch but performance may drop if the function is hot");
366 if (!seen_error ()
367 && !warned++)
369 inform (input_location, "coverage mismatch ignored");
370 inform (input_location, flag_guess_branch_prob
371 ? G_("execution counts estimated")
372 : G_("execution counts assumed to be zero"));
373 if (!flag_guess_branch_prob)
374 inform (input_location,
375 "this can result in poorly optimized code");
379 return NULL;
381 else if (entry->lineno_checksum != lineno_checksum)
383 warning (0, "source locations for function %qE have changed,"
384 " the profile data may be out of date",
385 DECL_ASSEMBLER_NAME (current_function_decl));
388 if (summary)
389 *summary = &entry->summary;
391 return entry->counts;
394 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
395 allocation succeeded. */
398 coverage_counter_alloc (unsigned counter, unsigned num)
400 if (no_coverage)
401 return 0;
403 if (!num)
404 return 1;
406 if (!fn_v_ctrs[counter])
408 tree array_type = build_array_type (get_gcov_type (), NULL_TREE);
410 fn_v_ctrs[counter]
411 = build_var (current_function_decl, array_type, counter);
414 fn_b_ctrs[counter] = fn_n_ctrs[counter];
415 fn_n_ctrs[counter] += num;
417 fn_ctr_mask |= 1 << counter;
418 return 1;
421 /* Generate a tree to access COUNTER NO. */
423 tree
424 tree_coverage_counter_ref (unsigned counter, unsigned no)
426 tree gcov_type_node = get_gcov_type ();
428 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
430 no += fn_b_ctrs[counter];
432 /* "no" here is an array index, scaled to bytes later. */
433 return build4 (ARRAY_REF, gcov_type_node, fn_v_ctrs[counter],
434 build_int_cst (integer_type_node, no), NULL, NULL);
437 /* Generate a tree to access the address of COUNTER NO. */
439 tree
440 tree_coverage_counter_addr (unsigned counter, unsigned no)
442 tree gcov_type_node = get_gcov_type ();
444 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
445 no += fn_b_ctrs[counter];
447 /* "no" here is an array index, scaled to bytes later. */
448 return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node,
449 fn_v_ctrs[counter],
450 build_int_cst (integer_type_node, no),
451 NULL, NULL));
455 /* Generate a checksum for a string. CHKSUM is the current
456 checksum. */
458 static unsigned
459 coverage_checksum_string (unsigned chksum, const char *string)
461 int i;
462 char *dup = NULL;
464 /* Look for everything that looks if it were produced by
465 get_file_function_name and zero out the second part
466 that may result from flag_random_seed. This is not critical
467 as the checksums are used only for sanity checking. */
468 for (i = 0; string[i]; i++)
470 int offset = 0;
471 if (!strncmp (string + i, "_GLOBAL__N_", 11))
472 offset = 11;
473 if (!strncmp (string + i, "_GLOBAL__", 9))
474 offset = 9;
476 /* C++ namespaces do have scheme:
477 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
478 since filename might contain extra underscores there seems
479 to be no better chance then walk all possible offsets looking
480 for magicnumber. */
481 if (offset)
483 for (i = i + offset; string[i]; i++)
484 if (string[i]=='_')
486 int y;
488 for (y = 1; y < 9; y++)
489 if (!(string[i + y] >= '0' && string[i + y] <= '9')
490 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
491 break;
492 if (y != 9 || string[i + 9] != '_')
493 continue;
494 for (y = 10; y < 18; y++)
495 if (!(string[i + y] >= '0' && string[i + y] <= '9')
496 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
497 break;
498 if (y != 18)
499 continue;
500 if (!dup)
501 string = dup = xstrdup (string);
502 for (y = 10; y < 18; y++)
503 dup[i + y] = '0';
505 break;
509 chksum = crc32_string (chksum, string);
510 free (dup);
512 return chksum;
515 /* Compute checksum for the current function. We generate a CRC32. */
517 unsigned
518 coverage_compute_lineno_checksum (void)
520 expanded_location xloc
521 = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
522 unsigned chksum = xloc.line;
524 chksum = coverage_checksum_string (chksum, xloc.file);
525 chksum = coverage_checksum_string
526 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
528 return chksum;
531 /* Compute cfg checksum for the current function.
532 The checksum is calculated carefully so that
533 source code changes that doesn't affect the control flow graph
534 won't change the checksum.
535 This is to make the profile data useable across source code change.
536 The downside of this is that the compiler may use potentially
537 wrong profile data - that the source code change has non-trivial impact
538 on the validity of profile data (e.g. the reversed condition)
539 but the compiler won't detect the change and use the wrong profile data. */
541 unsigned
542 coverage_compute_cfg_checksum (void)
544 basic_block bb;
545 unsigned chksum = n_basic_blocks;
547 FOR_EACH_BB (bb)
549 edge e;
550 edge_iterator ei;
551 chksum = crc32_byte (chksum, bb->index);
552 FOR_EACH_EDGE (e, ei, bb->succs)
554 chksum = crc32_byte (chksum, e->dest->index);
558 return chksum;
561 /* Begin output to the notes file for the current function.
562 Writes the function header. Returns nonzero if data should be output. */
565 coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
567 expanded_location xloc;
568 unsigned long offset;
570 /* We don't need to output .gcno file unless we're under -ftest-coverage
571 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
572 if (no_coverage || !bbg_file_name)
573 return 0;
575 xloc = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
577 /* Announce function */
578 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
579 gcov_write_unsigned (current_function_funcdef_no + 1);
580 gcov_write_unsigned (lineno_checksum);
581 gcov_write_unsigned (cfg_checksum);
582 gcov_write_string (IDENTIFIER_POINTER
583 (DECL_ASSEMBLER_NAME (current_function_decl)));
584 gcov_write_string (xloc.file);
585 gcov_write_unsigned (xloc.line);
586 gcov_write_length (offset);
588 return !gcov_is_error ();
591 /* Finish coverage data for the current function. Verify no output
592 error has occurred. Save function coverage counts. */
594 void
595 coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum)
597 unsigned i;
599 if (bbg_file_name && gcov_is_error ())
601 warning (0, "error writing %qs", bbg_file_name);
602 unlink (bbg_file_name);
603 bbg_file_name = NULL;
606 if (fn_ctr_mask)
608 struct coverage_data *item = 0;
610 /* If the function is extern (i.e. extern inline), then we won't
611 be outputting it, so don't chain it onto the function
612 list. */
613 if (!DECL_EXTERNAL (current_function_decl))
615 item = ggc_alloc_coverage_data ();
617 item->ident = current_function_funcdef_no + 1;
618 item->lineno_checksum = lineno_checksum;
619 item->cfg_checksum = cfg_checksum;
621 item->fn_decl = current_function_decl;
622 item->next = 0;
623 *functions_tail = item;
624 functions_tail = &item->next;
627 for (i = 0; i != GCOV_COUNTERS; i++)
629 tree var = fn_v_ctrs[i];
631 if (item)
632 item->ctr_vars[i] = var;
633 if (var)
635 tree array_type = build_index_type (size_int (fn_n_ctrs[i] - 1));
636 array_type = build_array_type (get_gcov_type (), array_type);
637 TREE_TYPE (var) = array_type;
638 DECL_SIZE (var) = TYPE_SIZE (array_type);
639 DECL_SIZE_UNIT (var) = TYPE_SIZE_UNIT (array_type);
640 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;
647 fn_ctr_mask = 0;
651 /* Build a coverage variable of TYPE for function FN_DECL. If COUNTER
652 >= 0 it is a counter array, otherwise it is the function structure. */
654 static tree
655 build_var (tree fn_decl, tree type, int counter)
657 tree var = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, type);
658 const char *fn_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn_decl));
659 char *buf;
660 size_t fn_name_len, len;
662 fn_name = targetm.strip_name_encoding (fn_name);
663 fn_name_len = strlen (fn_name);
664 buf = XALLOCAVEC (char, fn_name_len + 8 + sizeof (int) * 3);
666 if (counter < 0)
667 strcpy (buf, "__gcov__");
668 else
669 sprintf (buf, "__gcov%u_", counter);
670 len = strlen (buf);
671 #ifndef NO_DOT_IN_LABEL
672 buf[len - 1] = '.';
673 #elif !defined NO_DOLLAR_IN_LABEL
674 buf[len - 1] = '$';
675 #endif
676 memcpy (buf + len, fn_name, fn_name_len + 1);
677 DECL_NAME (var) = get_identifier (buf);
678 TREE_STATIC (var) = 1;
679 TREE_ADDRESSABLE (var) = 1;
680 DECL_ALIGN (var) = TYPE_ALIGN (type);
682 return var;
685 /* Creates the gcov_fn_info RECORD_TYPE. */
687 static void
688 build_fn_info_type (tree type, unsigned counters, tree gcov_info_type)
690 tree ctr_info = lang_hooks.types.make_type (RECORD_TYPE);
691 tree field, fields;
692 tree array_type;
694 gcc_assert (counters);
696 /* ctr_info::num */
697 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
698 get_gcov_unsigned_t ());
699 fields = field;
701 /* ctr_info::values */
702 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
703 build_pointer_type (get_gcov_type ()));
704 DECL_CHAIN (field) = fields;
705 fields = field;
707 finish_builtin_struct (ctr_info, "__gcov_ctr_info", fields, NULL_TREE);
709 /* key */
710 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
711 build_pointer_type (build_qualified_type
712 (gcov_info_type, TYPE_QUAL_CONST)));
713 fields = field;
715 /* ident */
716 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
717 get_gcov_unsigned_t ());
718 DECL_CHAIN (field) = fields;
719 fields = field;
721 /* lineno_checksum */
722 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
723 get_gcov_unsigned_t ());
724 DECL_CHAIN (field) = fields;
725 fields = field;
727 /* cfg checksum */
728 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
729 get_gcov_unsigned_t ());
730 DECL_CHAIN (field) = fields;
731 fields = field;
733 array_type = build_index_type (size_int (counters - 1));
734 array_type = build_array_type (ctr_info, array_type);
736 /* counters */
737 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, array_type);
738 DECL_CHAIN (field) = fields;
739 fields = field;
741 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
744 /* Returns a CONSTRUCTOR for a gcov_fn_info. DATA is
745 the coverage data for the function and TYPE is the gcov_fn_info
746 RECORD_TYPE. KEY is the object file key. */
748 static tree
749 build_fn_info (const struct coverage_data *data, tree type, tree key)
751 tree fields = TYPE_FIELDS (type);
752 tree ctr_type;
753 unsigned ix;
754 VEC(constructor_elt,gc) *v1 = NULL;
755 VEC(constructor_elt,gc) *v2 = NULL;
757 /* key */
758 CONSTRUCTOR_APPEND_ELT (v1, fields,
759 build1 (ADDR_EXPR, TREE_TYPE (fields), key));
760 fields = DECL_CHAIN (fields);
762 /* ident */
763 CONSTRUCTOR_APPEND_ELT (v1, fields,
764 build_int_cstu (get_gcov_unsigned_t (),
765 data->ident));
766 fields = DECL_CHAIN (fields);
768 /* lineno_checksum */
769 CONSTRUCTOR_APPEND_ELT (v1, fields,
770 build_int_cstu (get_gcov_unsigned_t (),
771 data->lineno_checksum));
772 fields = DECL_CHAIN (fields);
774 /* cfg_checksum */
775 CONSTRUCTOR_APPEND_ELT (v1, fields,
776 build_int_cstu (get_gcov_unsigned_t (),
777 data->cfg_checksum));
778 fields = DECL_CHAIN (fields);
780 /* counters */
781 ctr_type = TREE_TYPE (TREE_TYPE (fields));
782 for (ix = 0; ix != GCOV_COUNTERS; ix++)
783 if (prg_ctr_mask & (1 << ix))
785 VEC(constructor_elt,gc) *ctr = NULL;
786 tree var = data->ctr_vars[ix];
787 unsigned count = 0;
789 if (var)
790 count
791 = tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var))), 0)
792 + 1;
794 CONSTRUCTOR_APPEND_ELT (ctr, TYPE_FIELDS (ctr_type),
795 build_int_cstu (get_gcov_unsigned_t (),
796 count));
798 if (var)
799 CONSTRUCTOR_APPEND_ELT (ctr, DECL_CHAIN (TYPE_FIELDS (ctr_type)),
800 build_fold_addr_expr (var));
802 CONSTRUCTOR_APPEND_ELT (v2, NULL, build_constructor (ctr_type, ctr));
805 CONSTRUCTOR_APPEND_ELT (v1, fields,
806 build_constructor (TREE_TYPE (fields), v2));
808 return build_constructor (type, v1);
811 /* Create gcov_info struct. TYPE is the incomplete RECORD_TYPE to be
812 completed, and FN_INFO_PTR_TYPE is a pointer to the function info type. */
814 static void
815 build_info_type (tree type, tree fn_info_ptr_type)
817 tree field, fields = NULL_TREE;
818 tree merge_fn_type;
820 /* Version ident */
821 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
822 get_gcov_unsigned_t ());
823 DECL_CHAIN (field) = fields;
824 fields = field;
826 /* next pointer */
827 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
828 build_pointer_type (build_qualified_type
829 (type, TYPE_QUAL_CONST)));
830 DECL_CHAIN (field) = fields;
831 fields = field;
833 /* stamp */
834 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
835 get_gcov_unsigned_t ());
836 DECL_CHAIN (field) = fields;
837 fields = field;
839 /* Filename */
840 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
841 build_pointer_type (build_qualified_type
842 (char_type_node, TYPE_QUAL_CONST)));
843 DECL_CHAIN (field) = fields;
844 fields = field;
846 /* merge fn array */
847 merge_fn_type
848 = build_function_type_list (void_type_node,
849 build_pointer_type (get_gcov_type ()),
850 get_gcov_unsigned_t (), NULL_TREE);
851 merge_fn_type
852 = build_array_type (build_pointer_type (merge_fn_type),
853 build_index_type (size_int (GCOV_COUNTERS - 1)));
854 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
855 merge_fn_type);
856 DECL_CHAIN (field) = fields;
857 fields = field;
859 /* n_functions */
860 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
861 get_gcov_unsigned_t ());
862 DECL_CHAIN (field) = fields;
863 fields = field;
865 /* function_info pointer pointer */
866 fn_info_ptr_type = build_pointer_type
867 (build_qualified_type (fn_info_ptr_type, TYPE_QUAL_CONST));
868 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
869 fn_info_ptr_type);
870 DECL_CHAIN (field) = fields;
871 fields = field;
873 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
876 /* Returns a CONSTRUCTOR for the gcov_info object. INFO_TYPE is the
877 gcov_info structure type, FN_ARY is the array of pointers to
878 function info objects. */
880 static tree
881 build_info (tree info_type, tree fn_ary)
883 tree info_fields = TYPE_FIELDS (info_type);
884 tree merge_fn_type, n_funcs;
885 unsigned ix;
886 tree filename_string;
887 int da_file_name_len;
888 VEC(constructor_elt,gc) *v1 = NULL;
889 VEC(constructor_elt,gc) *v2 = NULL;
891 /* Version ident */
892 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
893 build_int_cstu (TREE_TYPE (info_fields),
894 GCOV_VERSION));
895 info_fields = DECL_CHAIN (info_fields);
897 /* next -- NULL */
898 CONSTRUCTOR_APPEND_ELT (v1, info_fields, null_pointer_node);
899 info_fields = DECL_CHAIN (info_fields);
901 /* stamp */
902 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
903 build_int_cstu (TREE_TYPE (info_fields),
904 bbg_file_stamp));
905 info_fields = DECL_CHAIN (info_fields);
907 /* Filename */
908 da_file_name_len = strlen (da_file_name);
909 filename_string = build_string (da_file_name_len + 1, da_file_name);
910 TREE_TYPE (filename_string) = build_array_type
911 (char_type_node, build_index_type (size_int (da_file_name_len)));
912 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
913 build1 (ADDR_EXPR, TREE_TYPE (info_fields),
914 filename_string));
915 info_fields = DECL_CHAIN (info_fields);
917 /* merge fn array -- NULL slots indicate unmeasured counters */
918 merge_fn_type = TREE_TYPE (TREE_TYPE (info_fields));
919 for (ix = 0; ix != GCOV_COUNTERS; ix++)
921 tree ptr = null_pointer_node;
923 if ((1u << ix) & prg_ctr_mask)
925 tree merge_fn = build_decl (BUILTINS_LOCATION,
926 FUNCTION_DECL,
927 get_identifier (ctr_merge_functions[ix]),
928 TREE_TYPE (merge_fn_type));
929 DECL_EXTERNAL (merge_fn) = 1;
930 TREE_PUBLIC (merge_fn) = 1;
931 DECL_ARTIFICIAL (merge_fn) = 1;
932 TREE_NOTHROW (merge_fn) = 1;
933 /* Initialize assembler name so we can stream out. */
934 DECL_ASSEMBLER_NAME (merge_fn);
935 ptr = build1 (ADDR_EXPR, merge_fn_type, merge_fn);
937 CONSTRUCTOR_APPEND_ELT (v2, NULL, ptr);
939 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
940 build_constructor (TREE_TYPE (info_fields), v2));
941 info_fields = DECL_CHAIN (info_fields);
943 /* n_functions */
944 n_funcs = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (fn_ary)));
945 n_funcs = fold_build2 (PLUS_EXPR, TREE_TYPE (info_fields),
946 n_funcs, size_one_node);
947 CONSTRUCTOR_APPEND_ELT (v1, info_fields, n_funcs);
948 info_fields = DECL_CHAIN (info_fields);
950 /* functions */
951 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
952 build1 (ADDR_EXPR, TREE_TYPE (info_fields), fn_ary));
953 info_fields = DECL_CHAIN (info_fields);
955 gcc_assert (!info_fields);
956 return build_constructor (info_type, v1);
959 /* Create the gcov_info types and object. Generate the constructor
960 function to call __gcov_init. Does not generate the initializer
961 for the object. Returns TRUE if coverage data is being emitted. */
963 static bool
964 coverage_obj_init (void)
966 tree gcov_info_type, ctor, stmt, init_fn;
967 unsigned n_counters = 0;
968 unsigned ix;
969 struct coverage_data *fn;
970 struct coverage_data **fn_prev;
971 char name_buf[32];
973 no_coverage = 1; /* Disable any further coverage. */
975 if (!prg_ctr_mask)
976 return false;
978 if (cgraph_dump_file)
979 fprintf (cgraph_dump_file, "Using data file %s\n", da_file_name);
981 /* Prune functions. */
982 for (fn_prev = &functions_head; (fn = *fn_prev);)
983 if (DECL_STRUCT_FUNCTION (fn->fn_decl))
984 fn_prev = &fn->next;
985 else
986 /* The function is not being emitted, remove from list. */
987 *fn_prev = fn->next;
989 for (ix = 0; ix != GCOV_COUNTERS; ix++)
990 if ((1u << ix) & prg_ctr_mask)
991 n_counters++;
993 /* Build the info and fn_info types. These are mutually recursive. */
994 gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
995 gcov_fn_info_type = lang_hooks.types.make_type (RECORD_TYPE);
996 gcov_fn_info_ptr_type = build_pointer_type
997 (build_qualified_type (gcov_fn_info_type, TYPE_QUAL_CONST));
998 build_fn_info_type (gcov_fn_info_type, n_counters, gcov_info_type);
999 build_info_type (gcov_info_type, gcov_fn_info_ptr_type);
1001 /* Build the gcov info var, this is referred to in its own
1002 initializer. */
1003 gcov_info_var = build_decl (BUILTINS_LOCATION,
1004 VAR_DECL, NULL_TREE, gcov_info_type);
1005 TREE_STATIC (gcov_info_var) = 1;
1006 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
1007 DECL_NAME (gcov_info_var) = get_identifier (name_buf);
1009 /* Build a decl for __gcov_init. */
1010 init_fn = build_pointer_type (gcov_info_type);
1011 init_fn = build_function_type_list (void_type_node, init_fn, NULL);
1012 init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
1013 get_identifier ("__gcov_init"), init_fn);
1014 TREE_PUBLIC (init_fn) = 1;
1015 DECL_EXTERNAL (init_fn) = 1;
1016 DECL_ASSEMBLER_NAME (init_fn);
1018 /* Generate a call to __gcov_init(&gcov_info). */
1019 ctor = NULL;
1020 stmt = build_fold_addr_expr (gcov_info_var);
1021 stmt = build_call_expr (init_fn, 1, stmt);
1022 append_to_statement_list (stmt, &ctor);
1024 /* Generate a constructor to run it. */
1025 cgraph_build_static_cdtor ('I', ctor, DEFAULT_INIT_PRIORITY);
1027 return true;
1030 /* Generate the coverage function info for FN and DATA. Append a
1031 pointer to that object to CTOR and return the appended CTOR. */
1033 static VEC(constructor_elt,gc) *
1034 coverage_obj_fn (VEC(constructor_elt,gc) *ctor, tree fn,
1035 struct coverage_data const *data)
1037 tree init = build_fn_info (data, gcov_fn_info_type, gcov_info_var);
1038 tree var = build_var (fn, gcov_fn_info_type, -1);
1040 DECL_INITIAL (var) = init;
1041 varpool_finalize_decl (var);
1043 CONSTRUCTOR_APPEND_ELT (ctor, NULL,
1044 build1 (ADDR_EXPR, gcov_fn_info_ptr_type, var));
1045 return ctor;
1048 /* Finalize the coverage data. Generates the array of pointers to
1049 function objects from CTOR. Generate the gcov_info initializer. */
1051 static void
1052 coverage_obj_finish (VEC(constructor_elt,gc) *ctor)
1054 unsigned n_functions = VEC_length(constructor_elt, ctor);
1055 tree fn_info_ary_type = build_array_type
1056 (build_qualified_type (gcov_fn_info_ptr_type, TYPE_QUAL_CONST),
1057 build_index_type (size_int (n_functions - 1)));
1058 tree fn_info_ary = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE,
1059 fn_info_ary_type);
1060 char name_buf[32];
1062 TREE_STATIC (fn_info_ary) = 1;
1063 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 1);
1064 DECL_NAME (fn_info_ary) = get_identifier (name_buf);
1065 DECL_INITIAL (fn_info_ary) = build_constructor (fn_info_ary_type, ctor);
1066 varpool_finalize_decl (fn_info_ary);
1068 DECL_INITIAL (gcov_info_var)
1069 = build_info (TREE_TYPE (gcov_info_var), fn_info_ary);
1070 varpool_finalize_decl (gcov_info_var);
1073 /* Perform file-level initialization. Read in data file, generate name
1074 of notes file. */
1076 void
1077 coverage_init (const char *filename)
1079 int len = strlen (filename);
1080 int prefix_len = 0;
1082 if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
1083 profile_data_prefix = getpwd ();
1085 if (profile_data_prefix)
1086 prefix_len = strlen (profile_data_prefix);
1088 /* Name of da file. */
1089 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
1090 + prefix_len + 2);
1092 if (profile_data_prefix)
1094 memcpy (da_file_name, profile_data_prefix, prefix_len);
1095 da_file_name[prefix_len++] = '/';
1097 memcpy (da_file_name + prefix_len, filename, len);
1098 strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX);
1100 bbg_file_stamp = local_tick;
1102 if (flag_branch_probabilities)
1103 read_counts_file ();
1105 /* Name of bbg file. */
1106 if (flag_test_coverage && !flag_compare_debug)
1108 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1);
1109 memcpy (bbg_file_name, filename, len);
1110 strcpy (bbg_file_name + len, GCOV_NOTE_SUFFIX);
1112 if (!gcov_open (bbg_file_name, -1))
1114 error ("cannot open %s", bbg_file_name);
1115 bbg_file_name = NULL;
1117 else
1119 gcov_write_unsigned (GCOV_NOTE_MAGIC);
1120 gcov_write_unsigned (GCOV_VERSION);
1121 gcov_write_unsigned (bbg_file_stamp);
1126 /* Performs file-level cleanup. Close notes file, generate coverage
1127 variables and constructor. */
1129 void
1130 coverage_finish (void)
1132 if (bbg_file_name && gcov_close ())
1133 unlink (bbg_file_name);
1135 if (!flag_branch_probabilities && flag_test_coverage
1136 && (!local_tick || local_tick == (unsigned)-1))
1137 /* Only remove the da file, if we're emitting coverage code and
1138 cannot uniquely stamp it. If we can stamp it, libgcov will DTRT. */
1139 unlink (da_file_name);
1141 if (coverage_obj_init ())
1143 VEC(constructor_elt,gc) *fn_ctor = NULL;
1144 struct coverage_data *fn;
1146 for (fn = functions_head; fn; fn = fn->next)
1147 fn_ctor = coverage_obj_fn (fn_ctor, fn->fn_decl, fn);
1148 coverage_obj_finish (fn_ctor);
1152 #include "gt-coverage.h"