2012-11-19 Mans Rullgard <mans@mansr.com>
[official-gcc.git] / gcc / coverage.c
blob7581a97f35f9162814d2186dbec503453fb31d05
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;
81 /* hash_table support. */
82 typedef counts_entry value_type;
83 typedef counts_entry compare_type;
84 static inline hashval_t hash (const value_type *);
85 static int equal (const value_type *, const compare_type *);
86 static void remove (value_type *);
87 } counts_entry_t;
89 static GTY(()) struct coverage_data *functions_head = 0;
90 static struct coverage_data **functions_tail = &functions_head;
91 static unsigned no_coverage = 0;
93 /* Cumulative counter information for whole program. */
94 static unsigned prg_ctr_mask; /* Mask of counter types generated. */
96 /* Counter information for current function. */
97 static unsigned fn_ctr_mask; /* Mask of counters used. */
98 static GTY(()) tree fn_v_ctrs[GCOV_COUNTERS]; /* counter variables. */
99 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated. */
100 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base. */
102 /* Coverage info VAR_DECL and function info type nodes. */
103 static GTY(()) tree gcov_info_var;
104 static GTY(()) tree gcov_fn_info_type;
105 static GTY(()) tree gcov_fn_info_ptr_type;
107 /* Name of the notes (gcno) output file. The "bbg" prefix is for
108 historical reasons, when the notes file contained only the
109 basic block graph notes.
110 If this is NULL we're not writing to the notes file. */
111 static char *bbg_file_name;
113 /* File stamp for notes file. */
114 static unsigned bbg_file_stamp;
116 /* Name of the count data (gcda) file. */
117 static char *da_file_name;
119 /* The names of merge functions for counters. */
120 static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
121 static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
123 /* Forward declarations. */
124 static void read_counts_file (void);
125 static tree build_var (tree, tree, int);
126 static void build_fn_info_type (tree, unsigned, tree);
127 static void build_info_type (tree, tree);
128 static tree build_fn_info (const struct coverage_data *, tree, tree);
129 static tree build_info (tree, tree);
130 static bool coverage_obj_init (void);
131 static vec<constructor_elt, va_gc> *coverage_obj_fn
132 (vec<constructor_elt, va_gc> *, tree, struct coverage_data const *);
133 static void coverage_obj_finish (vec<constructor_elt, va_gc> *);
135 /* Return the type node for gcov_type. */
137 tree
138 get_gcov_type (void)
140 enum machine_mode mode = smallest_mode_for_size (GCOV_TYPE_SIZE, MODE_INT);
141 return lang_hooks.types.type_for_mode (mode, false);
144 /* Return the type node for gcov_unsigned_t. */
146 static tree
147 get_gcov_unsigned_t (void)
149 enum machine_mode mode = smallest_mode_for_size (32, MODE_INT);
150 return lang_hooks.types.type_for_mode (mode, true);
153 inline hashval_t
154 counts_entry::hash (const value_type *entry)
156 return entry->ident * GCOV_COUNTERS + entry->ctr;
159 inline int
160 counts_entry::equal (const value_type *entry1,
161 const compare_type *entry2)
163 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
166 inline void
167 counts_entry::remove (value_type *entry)
169 free (entry->counts);
170 free (entry);
173 /* Hash table of count data. */
174 static hash_table <counts_entry> counts_hash;
176 /* Read in the counts file, if available. */
178 static void
179 read_counts_file (void)
181 gcov_unsigned_t fn_ident = 0;
182 struct gcov_summary summary;
183 unsigned new_summary = 1;
184 gcov_unsigned_t tag;
185 int is_error = 0;
186 unsigned lineno_checksum = 0;
187 unsigned cfg_checksum = 0;
189 if (!gcov_open (da_file_name, 1))
190 return;
192 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
194 warning (0, "%qs is not a gcov data file", da_file_name);
195 gcov_close ();
196 return;
198 else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
200 char v[4], e[4];
202 GCOV_UNSIGNED2STRING (v, tag);
203 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
205 warning (0, "%qs is version %q.*s, expected version %q.*s",
206 da_file_name, 4, v, 4, e);
207 gcov_close ();
208 return;
211 /* Read the stamp, used for creating a generation count. */
212 tag = gcov_read_unsigned ();
213 bbg_file_stamp = crc32_unsigned (bbg_file_stamp, tag);
215 counts_hash.create (10);
216 while ((tag = gcov_read_unsigned ()))
218 gcov_unsigned_t length;
219 gcov_position_t offset;
221 length = gcov_read_unsigned ();
222 offset = gcov_position ();
223 if (tag == GCOV_TAG_FUNCTION)
225 if (length)
227 fn_ident = gcov_read_unsigned ();
228 lineno_checksum = gcov_read_unsigned ();
229 cfg_checksum = gcov_read_unsigned ();
231 else
232 fn_ident = lineno_checksum = cfg_checksum = 0;
233 new_summary = 1;
235 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
237 struct gcov_summary sum;
238 unsigned ix;
240 if (new_summary)
241 memset (&summary, 0, sizeof (summary));
243 gcov_read_summary (&sum);
244 for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++)
246 summary.ctrs[ix].runs += sum.ctrs[ix].runs;
247 summary.ctrs[ix].sum_all += sum.ctrs[ix].sum_all;
248 if (summary.ctrs[ix].run_max < sum.ctrs[ix].run_max)
249 summary.ctrs[ix].run_max = sum.ctrs[ix].run_max;
250 summary.ctrs[ix].sum_max += sum.ctrs[ix].sum_max;
252 if (new_summary)
253 memcpy (summary.ctrs[GCOV_COUNTER_ARCS].histogram,
254 sum.ctrs[GCOV_COUNTER_ARCS].histogram,
255 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
256 else
257 gcov_histogram_merge (summary.ctrs[GCOV_COUNTER_ARCS].histogram,
258 sum.ctrs[GCOV_COUNTER_ARCS].histogram);
259 new_summary = 0;
261 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
263 counts_entry_t **slot, *entry, elt;
264 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
265 unsigned ix;
267 elt.ident = fn_ident;
268 elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
270 slot = counts_hash.find_slot (&elt, INSERT);
271 entry = *slot;
272 if (!entry)
274 *slot = entry = XCNEW (counts_entry_t);
275 entry->ident = fn_ident;
276 entry->ctr = elt.ctr;
277 entry->lineno_checksum = lineno_checksum;
278 entry->cfg_checksum = cfg_checksum;
279 if (elt.ctr < GCOV_COUNTERS_SUMMABLE)
280 entry->summary = summary.ctrs[elt.ctr];
281 entry->summary.num = n_counts;
282 entry->counts = XCNEWVEC (gcov_type, n_counts);
284 else if (entry->lineno_checksum != lineno_checksum
285 || entry->cfg_checksum != cfg_checksum)
287 error ("Profile data for function %u is corrupted", fn_ident);
288 error ("checksum is (%x,%x) instead of (%x,%x)",
289 entry->lineno_checksum, entry->cfg_checksum,
290 lineno_checksum, cfg_checksum);
291 counts_hash.dispose ();
292 break;
294 else if (entry->summary.num != n_counts)
296 error ("Profile data for function %u is corrupted", fn_ident);
297 error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
298 counts_hash.dispose ();
299 break;
301 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
303 error ("cannot merge separate %s counters for function %u",
304 ctr_names[elt.ctr], fn_ident);
305 goto skip_merge;
307 else
309 entry->summary.runs += summary.ctrs[elt.ctr].runs;
310 entry->summary.sum_all += summary.ctrs[elt.ctr].sum_all;
311 if (entry->summary.run_max < summary.ctrs[elt.ctr].run_max)
312 entry->summary.run_max = summary.ctrs[elt.ctr].run_max;
313 entry->summary.sum_max += summary.ctrs[elt.ctr].sum_max;
315 for (ix = 0; ix != n_counts; ix++)
316 entry->counts[ix] += gcov_read_counter ();
317 skip_merge:;
319 gcov_sync (offset, length);
320 if ((is_error = gcov_is_error ()))
322 error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted",
323 da_file_name);
324 counts_hash.dispose ();
325 break;
329 gcov_close ();
332 /* Returns the counters for a particular tag. */
334 gcov_type *
335 get_coverage_counts (unsigned counter, unsigned expected,
336 unsigned cfg_checksum, unsigned lineno_checksum,
337 const struct gcov_ctr_summary **summary)
339 counts_entry_t *entry, elt;
341 /* No hash table, no counts. */
342 if (!counts_hash.is_created ())
344 static int warned = 0;
346 if (!warned++)
347 inform (input_location, (flag_guess_branch_prob
348 ? "file %s not found, execution counts estimated"
349 : "file %s not found, execution counts assumed to be zero"),
350 da_file_name);
351 return NULL;
354 elt.ident = current_function_funcdef_no + 1;
355 elt.ctr = counter;
356 entry = counts_hash.find (&elt);
357 if (!entry || !entry->summary.num)
358 /* The function was not emitted, or is weak and not chosen in the
359 final executable. Silently fail, because there's nothing we
360 can do about it. */
361 return NULL;
363 if (entry->cfg_checksum != cfg_checksum
364 || entry->summary.num != expected)
366 static int warned = 0;
367 bool warning_printed = false;
368 tree id = DECL_ASSEMBLER_NAME (current_function_decl);
370 warning_printed =
371 warning_at (input_location, OPT_Wcoverage_mismatch,
372 "the control flow of function %qE does not match "
373 "its profile data (counter %qs)", id, ctr_names[counter]);
374 if (warning_printed)
376 inform (input_location, "use -Wno-error=coverage-mismatch to tolerate "
377 "the mismatch but performance may drop if the function is hot");
379 if (!seen_error ()
380 && !warned++)
382 inform (input_location, "coverage mismatch ignored");
383 inform (input_location, flag_guess_branch_prob
384 ? G_("execution counts estimated")
385 : G_("execution counts assumed to be zero"));
386 if (!flag_guess_branch_prob)
387 inform (input_location,
388 "this can result in poorly optimized code");
392 return NULL;
394 else if (entry->lineno_checksum != lineno_checksum)
396 warning (0, "source locations for function %qE have changed,"
397 " the profile data may be out of date",
398 DECL_ASSEMBLER_NAME (current_function_decl));
401 if (summary)
402 *summary = &entry->summary;
404 return entry->counts;
407 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
408 allocation succeeded. */
411 coverage_counter_alloc (unsigned counter, unsigned num)
413 if (no_coverage)
414 return 0;
416 if (!num)
417 return 1;
419 if (!fn_v_ctrs[counter])
421 tree array_type = build_array_type (get_gcov_type (), NULL_TREE);
423 fn_v_ctrs[counter]
424 = build_var (current_function_decl, array_type, counter);
427 fn_b_ctrs[counter] = fn_n_ctrs[counter];
428 fn_n_ctrs[counter] += num;
430 fn_ctr_mask |= 1 << counter;
431 return 1;
434 /* Generate a tree to access COUNTER NO. */
436 tree
437 tree_coverage_counter_ref (unsigned counter, unsigned no)
439 tree gcov_type_node = get_gcov_type ();
441 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
443 no += fn_b_ctrs[counter];
445 /* "no" here is an array index, scaled to bytes later. */
446 return build4 (ARRAY_REF, gcov_type_node, fn_v_ctrs[counter],
447 build_int_cst (integer_type_node, no), NULL, NULL);
450 /* Generate a tree to access the address of COUNTER NO. */
452 tree
453 tree_coverage_counter_addr (unsigned counter, unsigned no)
455 tree gcov_type_node = get_gcov_type ();
457 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
458 no += fn_b_ctrs[counter];
460 /* "no" here is an array index, scaled to bytes later. */
461 return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node,
462 fn_v_ctrs[counter],
463 build_int_cst (integer_type_node, no),
464 NULL, NULL));
468 /* Generate a checksum for a string. CHKSUM is the current
469 checksum. */
471 static unsigned
472 coverage_checksum_string (unsigned chksum, const char *string)
474 int i;
475 char *dup = NULL;
477 /* Look for everything that looks if it were produced by
478 get_file_function_name and zero out the second part
479 that may result from flag_random_seed. This is not critical
480 as the checksums are used only for sanity checking. */
481 for (i = 0; string[i]; i++)
483 int offset = 0;
484 if (!strncmp (string + i, "_GLOBAL__N_", 11))
485 offset = 11;
486 if (!strncmp (string + i, "_GLOBAL__", 9))
487 offset = 9;
489 /* C++ namespaces do have scheme:
490 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
491 since filename might contain extra underscores there seems
492 to be no better chance then walk all possible offsets looking
493 for magicnumber. */
494 if (offset)
496 for (i = i + offset; string[i]; i++)
497 if (string[i]=='_')
499 int y;
501 for (y = 1; y < 9; y++)
502 if (!(string[i + y] >= '0' && string[i + y] <= '9')
503 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
504 break;
505 if (y != 9 || string[i + 9] != '_')
506 continue;
507 for (y = 10; y < 18; y++)
508 if (!(string[i + y] >= '0' && string[i + y] <= '9')
509 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
510 break;
511 if (y != 18)
512 continue;
513 if (!dup)
514 string = dup = xstrdup (string);
515 for (y = 10; y < 18; y++)
516 dup[i + y] = '0';
518 break;
522 chksum = crc32_string (chksum, string);
523 free (dup);
525 return chksum;
528 /* Compute checksum for the current function. We generate a CRC32. */
530 unsigned
531 coverage_compute_lineno_checksum (void)
533 expanded_location xloc
534 = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
535 unsigned chksum = xloc.line;
537 chksum = coverage_checksum_string (chksum, xloc.file);
538 chksum = coverage_checksum_string
539 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
541 return chksum;
544 /* Compute cfg checksum for the current function.
545 The checksum is calculated carefully so that
546 source code changes that doesn't affect the control flow graph
547 won't change the checksum.
548 This is to make the profile data useable across source code change.
549 The downside of this is that the compiler may use potentially
550 wrong profile data - that the source code change has non-trivial impact
551 on the validity of profile data (e.g. the reversed condition)
552 but the compiler won't detect the change and use the wrong profile data. */
554 unsigned
555 coverage_compute_cfg_checksum (void)
557 basic_block bb;
558 unsigned chksum = n_basic_blocks;
560 FOR_EACH_BB (bb)
562 edge e;
563 edge_iterator ei;
564 chksum = crc32_byte (chksum, bb->index);
565 FOR_EACH_EDGE (e, ei, bb->succs)
567 chksum = crc32_byte (chksum, e->dest->index);
571 return chksum;
574 /* Begin output to the notes file for the current function.
575 Writes the function header. Returns nonzero if data should be output. */
578 coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
580 expanded_location xloc;
581 unsigned long offset;
583 /* We don't need to output .gcno file unless we're under -ftest-coverage
584 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
585 if (no_coverage || !bbg_file_name)
586 return 0;
588 xloc = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
590 /* Announce function */
591 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
592 gcov_write_unsigned (current_function_funcdef_no + 1);
593 gcov_write_unsigned (lineno_checksum);
594 gcov_write_unsigned (cfg_checksum);
595 gcov_write_string (IDENTIFIER_POINTER
596 (DECL_ASSEMBLER_NAME (current_function_decl)));
597 gcov_write_string (xloc.file);
598 gcov_write_unsigned (xloc.line);
599 gcov_write_length (offset);
601 return !gcov_is_error ();
604 /* Finish coverage data for the current function. Verify no output
605 error has occurred. Save function coverage counts. */
607 void
608 coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum)
610 unsigned i;
612 if (bbg_file_name && gcov_is_error ())
614 warning (0, "error writing %qs", bbg_file_name);
615 unlink (bbg_file_name);
616 bbg_file_name = NULL;
619 if (fn_ctr_mask)
621 struct coverage_data *item = 0;
623 /* If the function is extern (i.e. extern inline), then we won't
624 be outputting it, so don't chain it onto the function
625 list. */
626 if (!DECL_EXTERNAL (current_function_decl))
628 item = ggc_alloc_coverage_data ();
630 item->ident = current_function_funcdef_no + 1;
631 item->lineno_checksum = lineno_checksum;
632 item->cfg_checksum = cfg_checksum;
634 item->fn_decl = current_function_decl;
635 item->next = 0;
636 *functions_tail = item;
637 functions_tail = &item->next;
640 for (i = 0; i != GCOV_COUNTERS; i++)
642 tree var = fn_v_ctrs[i];
644 if (item)
645 item->ctr_vars[i] = var;
646 if (var)
648 tree array_type = build_index_type (size_int (fn_n_ctrs[i] - 1));
649 array_type = build_array_type (get_gcov_type (), array_type);
650 TREE_TYPE (var) = array_type;
651 DECL_SIZE (var) = TYPE_SIZE (array_type);
652 DECL_SIZE_UNIT (var) = TYPE_SIZE_UNIT (array_type);
653 varpool_finalize_decl (var);
656 fn_b_ctrs[i] = fn_n_ctrs[i] = 0;
657 fn_v_ctrs[i] = NULL_TREE;
659 prg_ctr_mask |= fn_ctr_mask;
660 fn_ctr_mask = 0;
664 /* Build a coverage variable of TYPE for function FN_DECL. If COUNTER
665 >= 0 it is a counter array, otherwise it is the function structure. */
667 static tree
668 build_var (tree fn_decl, tree type, int counter)
670 tree var = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, type);
671 const char *fn_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn_decl));
672 char *buf;
673 size_t fn_name_len, len;
675 fn_name = targetm.strip_name_encoding (fn_name);
676 fn_name_len = strlen (fn_name);
677 buf = XALLOCAVEC (char, fn_name_len + 8 + sizeof (int) * 3);
679 if (counter < 0)
680 strcpy (buf, "__gcov__");
681 else
682 sprintf (buf, "__gcov%u_", counter);
683 len = strlen (buf);
684 #ifndef NO_DOT_IN_LABEL
685 buf[len - 1] = '.';
686 #elif !defined NO_DOLLAR_IN_LABEL
687 buf[len - 1] = '$';
688 #endif
689 memcpy (buf + len, fn_name, fn_name_len + 1);
690 DECL_NAME (var) = get_identifier (buf);
691 TREE_STATIC (var) = 1;
692 TREE_ADDRESSABLE (var) = 1;
693 DECL_ALIGN (var) = TYPE_ALIGN (type);
695 return var;
698 /* Creates the gcov_fn_info RECORD_TYPE. */
700 static void
701 build_fn_info_type (tree type, unsigned counters, tree gcov_info_type)
703 tree ctr_info = lang_hooks.types.make_type (RECORD_TYPE);
704 tree field, fields;
705 tree array_type;
707 gcc_assert (counters);
709 /* ctr_info::num */
710 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
711 get_gcov_unsigned_t ());
712 fields = field;
714 /* ctr_info::values */
715 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
716 build_pointer_type (get_gcov_type ()));
717 DECL_CHAIN (field) = fields;
718 fields = field;
720 finish_builtin_struct (ctr_info, "__gcov_ctr_info", fields, NULL_TREE);
722 /* key */
723 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
724 build_pointer_type (build_qualified_type
725 (gcov_info_type, TYPE_QUAL_CONST)));
726 fields = field;
728 /* ident */
729 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
730 get_gcov_unsigned_t ());
731 DECL_CHAIN (field) = fields;
732 fields = field;
734 /* lineno_checksum */
735 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
736 get_gcov_unsigned_t ());
737 DECL_CHAIN (field) = fields;
738 fields = field;
740 /* cfg checksum */
741 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
742 get_gcov_unsigned_t ());
743 DECL_CHAIN (field) = fields;
744 fields = field;
746 array_type = build_index_type (size_int (counters - 1));
747 array_type = build_array_type (ctr_info, array_type);
749 /* counters */
750 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, array_type);
751 DECL_CHAIN (field) = fields;
752 fields = field;
754 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
757 /* Returns a CONSTRUCTOR for a gcov_fn_info. DATA is
758 the coverage data for the function and TYPE is the gcov_fn_info
759 RECORD_TYPE. KEY is the object file key. */
761 static tree
762 build_fn_info (const struct coverage_data *data, tree type, tree key)
764 tree fields = TYPE_FIELDS (type);
765 tree ctr_type;
766 unsigned ix;
767 vec<constructor_elt, va_gc> *v1 = NULL;
768 vec<constructor_elt, va_gc> *v2 = NULL;
770 /* key */
771 CONSTRUCTOR_APPEND_ELT (v1, fields,
772 build1 (ADDR_EXPR, TREE_TYPE (fields), key));
773 fields = DECL_CHAIN (fields);
775 /* ident */
776 CONSTRUCTOR_APPEND_ELT (v1, fields,
777 build_int_cstu (get_gcov_unsigned_t (),
778 data->ident));
779 fields = DECL_CHAIN (fields);
781 /* lineno_checksum */
782 CONSTRUCTOR_APPEND_ELT (v1, fields,
783 build_int_cstu (get_gcov_unsigned_t (),
784 data->lineno_checksum));
785 fields = DECL_CHAIN (fields);
787 /* cfg_checksum */
788 CONSTRUCTOR_APPEND_ELT (v1, fields,
789 build_int_cstu (get_gcov_unsigned_t (),
790 data->cfg_checksum));
791 fields = DECL_CHAIN (fields);
793 /* counters */
794 ctr_type = TREE_TYPE (TREE_TYPE (fields));
795 for (ix = 0; ix != GCOV_COUNTERS; ix++)
796 if (prg_ctr_mask & (1 << ix))
798 vec<constructor_elt, va_gc> *ctr = NULL;
799 tree var = data->ctr_vars[ix];
800 unsigned count = 0;
802 if (var)
803 count
804 = tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var))), 0)
805 + 1;
807 CONSTRUCTOR_APPEND_ELT (ctr, TYPE_FIELDS (ctr_type),
808 build_int_cstu (get_gcov_unsigned_t (),
809 count));
811 if (var)
812 CONSTRUCTOR_APPEND_ELT (ctr, DECL_CHAIN (TYPE_FIELDS (ctr_type)),
813 build_fold_addr_expr (var));
815 CONSTRUCTOR_APPEND_ELT (v2, NULL, build_constructor (ctr_type, ctr));
818 CONSTRUCTOR_APPEND_ELT (v1, fields,
819 build_constructor (TREE_TYPE (fields), v2));
821 return build_constructor (type, v1);
824 /* Create gcov_info struct. TYPE is the incomplete RECORD_TYPE to be
825 completed, and FN_INFO_PTR_TYPE is a pointer to the function info type. */
827 static void
828 build_info_type (tree type, tree fn_info_ptr_type)
830 tree field, fields = NULL_TREE;
831 tree merge_fn_type;
833 /* Version ident */
834 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
835 get_gcov_unsigned_t ());
836 DECL_CHAIN (field) = fields;
837 fields = field;
839 /* next pointer */
840 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
841 build_pointer_type (build_qualified_type
842 (type, TYPE_QUAL_CONST)));
843 DECL_CHAIN (field) = fields;
844 fields = field;
846 /* stamp */
847 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
848 get_gcov_unsigned_t ());
849 DECL_CHAIN (field) = fields;
850 fields = field;
852 /* Filename */
853 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
854 build_pointer_type (build_qualified_type
855 (char_type_node, TYPE_QUAL_CONST)));
856 DECL_CHAIN (field) = fields;
857 fields = field;
859 /* merge fn array */
860 merge_fn_type
861 = build_function_type_list (void_type_node,
862 build_pointer_type (get_gcov_type ()),
863 get_gcov_unsigned_t (), NULL_TREE);
864 merge_fn_type
865 = build_array_type (build_pointer_type (merge_fn_type),
866 build_index_type (size_int (GCOV_COUNTERS - 1)));
867 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
868 merge_fn_type);
869 DECL_CHAIN (field) = fields;
870 fields = field;
872 /* n_functions */
873 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
874 get_gcov_unsigned_t ());
875 DECL_CHAIN (field) = fields;
876 fields = field;
878 /* function_info pointer pointer */
879 fn_info_ptr_type = build_pointer_type
880 (build_qualified_type (fn_info_ptr_type, TYPE_QUAL_CONST));
881 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
882 fn_info_ptr_type);
883 DECL_CHAIN (field) = fields;
884 fields = field;
886 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
889 /* Returns a CONSTRUCTOR for the gcov_info object. INFO_TYPE is the
890 gcov_info structure type, FN_ARY is the array of pointers to
891 function info objects. */
893 static tree
894 build_info (tree info_type, tree fn_ary)
896 tree info_fields = TYPE_FIELDS (info_type);
897 tree merge_fn_type, n_funcs;
898 unsigned ix;
899 tree filename_string;
900 int da_file_name_len;
901 vec<constructor_elt, va_gc> *v1 = NULL;
902 vec<constructor_elt, va_gc> *v2 = NULL;
904 /* Version ident */
905 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
906 build_int_cstu (TREE_TYPE (info_fields),
907 GCOV_VERSION));
908 info_fields = DECL_CHAIN (info_fields);
910 /* next -- NULL */
911 CONSTRUCTOR_APPEND_ELT (v1, info_fields, null_pointer_node);
912 info_fields = DECL_CHAIN (info_fields);
914 /* stamp */
915 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
916 build_int_cstu (TREE_TYPE (info_fields),
917 bbg_file_stamp));
918 info_fields = DECL_CHAIN (info_fields);
920 /* Filename */
921 da_file_name_len = strlen (da_file_name);
922 filename_string = build_string (da_file_name_len + 1, da_file_name);
923 TREE_TYPE (filename_string) = build_array_type
924 (char_type_node, build_index_type (size_int (da_file_name_len)));
925 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
926 build1 (ADDR_EXPR, TREE_TYPE (info_fields),
927 filename_string));
928 info_fields = DECL_CHAIN (info_fields);
930 /* merge fn array -- NULL slots indicate unmeasured counters */
931 merge_fn_type = TREE_TYPE (TREE_TYPE (info_fields));
932 for (ix = 0; ix != GCOV_COUNTERS; ix++)
934 tree ptr = null_pointer_node;
936 if ((1u << ix) & prg_ctr_mask)
938 tree merge_fn = build_decl (BUILTINS_LOCATION,
939 FUNCTION_DECL,
940 get_identifier (ctr_merge_functions[ix]),
941 TREE_TYPE (merge_fn_type));
942 DECL_EXTERNAL (merge_fn) = 1;
943 TREE_PUBLIC (merge_fn) = 1;
944 DECL_ARTIFICIAL (merge_fn) = 1;
945 TREE_NOTHROW (merge_fn) = 1;
946 /* Initialize assembler name so we can stream out. */
947 DECL_ASSEMBLER_NAME (merge_fn);
948 ptr = build1 (ADDR_EXPR, merge_fn_type, merge_fn);
950 CONSTRUCTOR_APPEND_ELT (v2, NULL, ptr);
952 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
953 build_constructor (TREE_TYPE (info_fields), v2));
954 info_fields = DECL_CHAIN (info_fields);
956 /* n_functions */
957 n_funcs = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (fn_ary)));
958 n_funcs = fold_build2 (PLUS_EXPR, TREE_TYPE (info_fields),
959 n_funcs, size_one_node);
960 CONSTRUCTOR_APPEND_ELT (v1, info_fields, n_funcs);
961 info_fields = DECL_CHAIN (info_fields);
963 /* functions */
964 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
965 build1 (ADDR_EXPR, TREE_TYPE (info_fields), fn_ary));
966 info_fields = DECL_CHAIN (info_fields);
968 gcc_assert (!info_fields);
969 return build_constructor (info_type, v1);
972 /* Create the gcov_info types and object. Generate the constructor
973 function to call __gcov_init. Does not generate the initializer
974 for the object. Returns TRUE if coverage data is being emitted. */
976 static bool
977 coverage_obj_init (void)
979 tree gcov_info_type, ctor, stmt, init_fn;
980 unsigned n_counters = 0;
981 unsigned ix;
982 struct coverage_data *fn;
983 struct coverage_data **fn_prev;
984 char name_buf[32];
986 no_coverage = 1; /* Disable any further coverage. */
988 if (!prg_ctr_mask)
989 return false;
991 if (cgraph_dump_file)
992 fprintf (cgraph_dump_file, "Using data file %s\n", da_file_name);
994 /* Prune functions. */
995 for (fn_prev = &functions_head; (fn = *fn_prev);)
996 if (DECL_STRUCT_FUNCTION (fn->fn_decl))
997 fn_prev = &fn->next;
998 else
999 /* The function is not being emitted, remove from list. */
1000 *fn_prev = fn->next;
1002 for (ix = 0; ix != GCOV_COUNTERS; ix++)
1003 if ((1u << ix) & prg_ctr_mask)
1004 n_counters++;
1006 /* Build the info and fn_info types. These are mutually recursive. */
1007 gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1008 gcov_fn_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1009 gcov_fn_info_ptr_type = build_pointer_type
1010 (build_qualified_type (gcov_fn_info_type, TYPE_QUAL_CONST));
1011 build_fn_info_type (gcov_fn_info_type, n_counters, gcov_info_type);
1012 build_info_type (gcov_info_type, gcov_fn_info_ptr_type);
1014 /* Build the gcov info var, this is referred to in its own
1015 initializer. */
1016 gcov_info_var = build_decl (BUILTINS_LOCATION,
1017 VAR_DECL, NULL_TREE, gcov_info_type);
1018 TREE_STATIC (gcov_info_var) = 1;
1019 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
1020 DECL_NAME (gcov_info_var) = get_identifier (name_buf);
1022 /* Build a decl for __gcov_init. */
1023 init_fn = build_pointer_type (gcov_info_type);
1024 init_fn = build_function_type_list (void_type_node, init_fn, NULL);
1025 init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
1026 get_identifier ("__gcov_init"), init_fn);
1027 TREE_PUBLIC (init_fn) = 1;
1028 DECL_EXTERNAL (init_fn) = 1;
1029 DECL_ASSEMBLER_NAME (init_fn);
1031 /* Generate a call to __gcov_init(&gcov_info). */
1032 ctor = NULL;
1033 stmt = build_fold_addr_expr (gcov_info_var);
1034 stmt = build_call_expr (init_fn, 1, stmt);
1035 append_to_statement_list (stmt, &ctor);
1037 /* Generate a constructor to run it. */
1038 cgraph_build_static_cdtor ('I', ctor, DEFAULT_INIT_PRIORITY);
1040 return true;
1043 /* Generate the coverage function info for FN and DATA. Append a
1044 pointer to that object to CTOR and return the appended CTOR. */
1046 static vec<constructor_elt, va_gc> *
1047 coverage_obj_fn (vec<constructor_elt, va_gc> *ctor, tree fn,
1048 struct coverage_data const *data)
1050 tree init = build_fn_info (data, gcov_fn_info_type, gcov_info_var);
1051 tree var = build_var (fn, gcov_fn_info_type, -1);
1053 DECL_INITIAL (var) = init;
1054 varpool_finalize_decl (var);
1056 CONSTRUCTOR_APPEND_ELT (ctor, NULL,
1057 build1 (ADDR_EXPR, gcov_fn_info_ptr_type, var));
1058 return ctor;
1061 /* Finalize the coverage data. Generates the array of pointers to
1062 function objects from CTOR. Generate the gcov_info initializer. */
1064 static void
1065 coverage_obj_finish (vec<constructor_elt, va_gc> *ctor)
1067 unsigned n_functions = vec_safe_length (ctor);
1068 tree fn_info_ary_type = build_array_type
1069 (build_qualified_type (gcov_fn_info_ptr_type, TYPE_QUAL_CONST),
1070 build_index_type (size_int (n_functions - 1)));
1071 tree fn_info_ary = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE,
1072 fn_info_ary_type);
1073 char name_buf[32];
1075 TREE_STATIC (fn_info_ary) = 1;
1076 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 1);
1077 DECL_NAME (fn_info_ary) = get_identifier (name_buf);
1078 DECL_INITIAL (fn_info_ary) = build_constructor (fn_info_ary_type, ctor);
1079 varpool_finalize_decl (fn_info_ary);
1081 DECL_INITIAL (gcov_info_var)
1082 = build_info (TREE_TYPE (gcov_info_var), fn_info_ary);
1083 varpool_finalize_decl (gcov_info_var);
1086 /* Perform file-level initialization. Read in data file, generate name
1087 of notes file. */
1089 void
1090 coverage_init (const char *filename)
1092 int len = strlen (filename);
1093 int prefix_len = 0;
1095 if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
1096 profile_data_prefix = getpwd ();
1098 if (profile_data_prefix)
1099 prefix_len = strlen (profile_data_prefix);
1101 /* Name of da file. */
1102 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
1103 + prefix_len + 2);
1105 if (profile_data_prefix)
1107 memcpy (da_file_name, profile_data_prefix, prefix_len);
1108 da_file_name[prefix_len++] = '/';
1110 memcpy (da_file_name + prefix_len, filename, len);
1111 strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX);
1113 bbg_file_stamp = local_tick;
1115 if (flag_branch_probabilities)
1116 read_counts_file ();
1118 /* Name of bbg file. */
1119 if (flag_test_coverage && !flag_compare_debug)
1121 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1);
1122 memcpy (bbg_file_name, filename, len);
1123 strcpy (bbg_file_name + len, GCOV_NOTE_SUFFIX);
1125 if (!gcov_open (bbg_file_name, -1))
1127 error ("cannot open %s", bbg_file_name);
1128 bbg_file_name = NULL;
1130 else
1132 gcov_write_unsigned (GCOV_NOTE_MAGIC);
1133 gcov_write_unsigned (GCOV_VERSION);
1134 gcov_write_unsigned (bbg_file_stamp);
1139 /* Performs file-level cleanup. Close notes file, generate coverage
1140 variables and constructor. */
1142 void
1143 coverage_finish (void)
1145 if (bbg_file_name && gcov_close ())
1146 unlink (bbg_file_name);
1148 if (!flag_branch_probabilities && flag_test_coverage
1149 && (!local_tick || local_tick == (unsigned)-1))
1150 /* Only remove the da file, if we're emitting coverage code and
1151 cannot uniquely stamp it. If we can stamp it, libgcov will DTRT. */
1152 unlink (da_file_name);
1154 if (coverage_obj_init ())
1156 vec<constructor_elt, va_gc> *fn_ctor = NULL;
1157 struct coverage_data *fn;
1159 for (fn = functions_head; fn; fn = fn->next)
1160 fn_ctor = coverage_obj_fn (fn_ctor, fn->fn_decl, fn);
1161 coverage_obj_finish (fn_ctor);
1165 #include "gt-coverage.h"