2012-09-15 Tom de Vries <tom@codesourcery.com>
[official-gcc.git] / gcc / coverage.c
blobf9b12e8b6f64450b74b1dd9f11d4efdd59ef847a
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 T;
83 static inline hashval_t hash (const counts_entry *);
84 static int equal (const counts_entry *, const counts_entry *);
85 static void remove (counts_entry *);
86 } counts_entry_t;
88 static GTY(()) struct coverage_data *functions_head = 0;
89 static struct coverage_data **functions_tail = &functions_head;
90 static unsigned no_coverage = 0;
92 /* Cumulative counter information for whole program. */
93 static unsigned prg_ctr_mask; /* Mask of counter types generated. */
95 /* Counter information for current function. */
96 static unsigned fn_ctr_mask; /* Mask of counters used. */
97 static GTY(()) tree fn_v_ctrs[GCOV_COUNTERS]; /* counter variables. */
98 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated. */
99 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base. */
101 /* Coverage info VAR_DECL and function info type nodes. */
102 static GTY(()) tree gcov_info_var;
103 static GTY(()) tree gcov_fn_info_type;
104 static GTY(()) tree gcov_fn_info_ptr_type;
106 /* Name of the notes (gcno) output file. The "bbg" prefix is for
107 historical reasons, when the notes file contained only the
108 basic block graph notes.
109 If this is NULL we're not writing to the notes file. */
110 static char *bbg_file_name;
112 /* File stamp for notes file. */
113 static unsigned bbg_file_stamp;
115 /* Name of the count data (gcda) file. */
116 static char *da_file_name;
118 /* The names of merge functions for counters. */
119 static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
120 static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
122 /* Forward declarations. */
123 static void read_counts_file (void);
124 static tree build_var (tree, tree, int);
125 static void build_fn_info_type (tree, unsigned, tree);
126 static void build_info_type (tree, tree);
127 static tree build_fn_info (const struct coverage_data *, tree, tree);
128 static tree build_info (tree, tree);
129 static bool coverage_obj_init (void);
130 static VEC(constructor_elt,gc) *coverage_obj_fn
131 (VEC(constructor_elt,gc) *, tree, struct coverage_data const *);
132 static void coverage_obj_finish (VEC(constructor_elt,gc) *);
134 /* Return the type node for gcov_type. */
136 tree
137 get_gcov_type (void)
139 enum machine_mode mode = smallest_mode_for_size (GCOV_TYPE_SIZE, MODE_INT);
140 return lang_hooks.types.type_for_mode (mode, false);
143 /* Return the type node for gcov_unsigned_t. */
145 static tree
146 get_gcov_unsigned_t (void)
148 enum machine_mode mode = smallest_mode_for_size (32, MODE_INT);
149 return lang_hooks.types.type_for_mode (mode, true);
152 inline hashval_t
153 counts_entry::hash (const counts_entry_t *entry)
155 return entry->ident * GCOV_COUNTERS + entry->ctr;
158 inline int
159 counts_entry::equal (const counts_entry_t *entry1,
160 const counts_entry_t *entry2)
162 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
165 inline void
166 counts_entry::remove (counts_entry_t *entry)
168 free (entry->counts);
169 free (entry);
172 /* Hash table of count data. */
173 static hash_table <counts_entry> counts_hash;
175 /* Read in the counts file, if available. */
177 static void
178 read_counts_file (void)
180 gcov_unsigned_t fn_ident = 0;
181 struct gcov_summary summary;
182 unsigned new_summary = 1;
183 gcov_unsigned_t tag;
184 int is_error = 0;
185 unsigned lineno_checksum = 0;
186 unsigned cfg_checksum = 0;
188 if (!gcov_open (da_file_name, 1))
189 return;
191 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
193 warning (0, "%qs is not a gcov data file", da_file_name);
194 gcov_close ();
195 return;
197 else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
199 char v[4], e[4];
201 GCOV_UNSIGNED2STRING (v, tag);
202 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
204 warning (0, "%qs is version %q.*s, expected version %q.*s",
205 da_file_name, 4, v, 4, e);
206 gcov_close ();
207 return;
210 /* Read the stamp, used for creating a generation count. */
211 tag = gcov_read_unsigned ();
212 bbg_file_stamp = crc32_unsigned (bbg_file_stamp, tag);
214 counts_hash.create (10);
215 while ((tag = gcov_read_unsigned ()))
217 gcov_unsigned_t length;
218 gcov_position_t offset;
220 length = gcov_read_unsigned ();
221 offset = gcov_position ();
222 if (tag == GCOV_TAG_FUNCTION)
224 if (length)
226 fn_ident = gcov_read_unsigned ();
227 lineno_checksum = gcov_read_unsigned ();
228 cfg_checksum = gcov_read_unsigned ();
230 else
231 fn_ident = lineno_checksum = cfg_checksum = 0;
232 new_summary = 1;
234 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
236 struct gcov_summary sum;
237 unsigned ix;
239 if (new_summary)
240 memset (&summary, 0, sizeof (summary));
242 gcov_read_summary (&sum);
243 for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++)
245 summary.ctrs[ix].runs += sum.ctrs[ix].runs;
246 summary.ctrs[ix].sum_all += sum.ctrs[ix].sum_all;
247 if (summary.ctrs[ix].run_max < sum.ctrs[ix].run_max)
248 summary.ctrs[ix].run_max = sum.ctrs[ix].run_max;
249 summary.ctrs[ix].sum_max += sum.ctrs[ix].sum_max;
251 if (new_summary)
252 memcpy (summary.ctrs[GCOV_COUNTER_ARCS].histogram,
253 sum.ctrs[GCOV_COUNTER_ARCS].histogram,
254 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
255 else
256 gcov_histogram_merge (summary.ctrs[GCOV_COUNTER_ARCS].histogram,
257 sum.ctrs[GCOV_COUNTER_ARCS].histogram);
258 new_summary = 0;
260 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
262 counts_entry_t **slot, *entry, elt;
263 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
264 unsigned ix;
266 elt.ident = fn_ident;
267 elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
269 slot = counts_hash.find_slot (&elt, INSERT);
270 entry = *slot;
271 if (!entry)
273 *slot = entry = XCNEW (counts_entry_t);
274 entry->ident = fn_ident;
275 entry->ctr = elt.ctr;
276 entry->lineno_checksum = lineno_checksum;
277 entry->cfg_checksum = cfg_checksum;
278 if (elt.ctr < GCOV_COUNTERS_SUMMABLE)
279 entry->summary = summary.ctrs[elt.ctr];
280 entry->summary.num = n_counts;
281 entry->counts = XCNEWVEC (gcov_type, n_counts);
283 else if (entry->lineno_checksum != lineno_checksum
284 || entry->cfg_checksum != cfg_checksum)
286 error ("Profile data for function %u is corrupted", fn_ident);
287 error ("checksum is (%x,%x) instead of (%x,%x)",
288 entry->lineno_checksum, entry->cfg_checksum,
289 lineno_checksum, cfg_checksum);
290 counts_hash.dispose ();
291 break;
293 else if (entry->summary.num != n_counts)
295 error ("Profile data for function %u is corrupted", fn_ident);
296 error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
297 counts_hash.dispose ();
298 break;
300 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
302 error ("cannot merge separate %s counters for function %u",
303 ctr_names[elt.ctr], fn_ident);
304 goto skip_merge;
306 else
308 entry->summary.runs += summary.ctrs[elt.ctr].runs;
309 entry->summary.sum_all += summary.ctrs[elt.ctr].sum_all;
310 if (entry->summary.run_max < summary.ctrs[elt.ctr].run_max)
311 entry->summary.run_max = summary.ctrs[elt.ctr].run_max;
312 entry->summary.sum_max += summary.ctrs[elt.ctr].sum_max;
314 for (ix = 0; ix != n_counts; ix++)
315 entry->counts[ix] += gcov_read_counter ();
316 skip_merge:;
318 gcov_sync (offset, length);
319 if ((is_error = gcov_is_error ()))
321 error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted",
322 da_file_name);
323 counts_hash.dispose ();
324 break;
328 gcov_close ();
331 /* Returns the counters for a particular tag. */
333 gcov_type *
334 get_coverage_counts (unsigned counter, unsigned expected,
335 unsigned cfg_checksum, unsigned lineno_checksum,
336 const struct gcov_ctr_summary **summary)
338 counts_entry_t *entry, elt;
340 /* No hash table, no counts. */
341 if (!counts_hash.is_created ())
343 static int warned = 0;
345 if (!warned++)
346 inform (input_location, (flag_guess_branch_prob
347 ? "file %s not found, execution counts estimated"
348 : "file %s not found, execution counts assumed to be zero"),
349 da_file_name);
350 return NULL;
353 elt.ident = current_function_funcdef_no + 1;
354 elt.ctr = counter;
355 entry = counts_hash.find (&elt);
356 if (!entry || !entry->summary.num)
357 /* The function was not emitted, or is weak and not chosen in the
358 final executable. Silently fail, because there's nothing we
359 can do about it. */
360 return NULL;
362 if (entry->cfg_checksum != cfg_checksum
363 || entry->summary.num != expected)
365 static int warned = 0;
366 bool warning_printed = false;
367 tree id = DECL_ASSEMBLER_NAME (current_function_decl);
369 warning_printed =
370 warning_at (input_location, OPT_Wcoverage_mismatch,
371 "the control flow of function %qE does not match "
372 "its profile data (counter %qs)", id, ctr_names[counter]);
373 if (warning_printed)
375 inform (input_location, "use -Wno-error=coverage-mismatch to tolerate "
376 "the mismatch but performance may drop if the function is hot");
378 if (!seen_error ()
379 && !warned++)
381 inform (input_location, "coverage mismatch ignored");
382 inform (input_location, flag_guess_branch_prob
383 ? G_("execution counts estimated")
384 : G_("execution counts assumed to be zero"));
385 if (!flag_guess_branch_prob)
386 inform (input_location,
387 "this can result in poorly optimized code");
391 return NULL;
393 else if (entry->lineno_checksum != lineno_checksum)
395 warning (0, "source locations for function %qE have changed,"
396 " the profile data may be out of date",
397 DECL_ASSEMBLER_NAME (current_function_decl));
400 if (summary)
401 *summary = &entry->summary;
403 return entry->counts;
406 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
407 allocation succeeded. */
410 coverage_counter_alloc (unsigned counter, unsigned num)
412 if (no_coverage)
413 return 0;
415 if (!num)
416 return 1;
418 if (!fn_v_ctrs[counter])
420 tree array_type = build_array_type (get_gcov_type (), NULL_TREE);
422 fn_v_ctrs[counter]
423 = build_var (current_function_decl, array_type, counter);
426 fn_b_ctrs[counter] = fn_n_ctrs[counter];
427 fn_n_ctrs[counter] += num;
429 fn_ctr_mask |= 1 << counter;
430 return 1;
433 /* Generate a tree to access COUNTER NO. */
435 tree
436 tree_coverage_counter_ref (unsigned counter, unsigned no)
438 tree gcov_type_node = get_gcov_type ();
440 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
442 no += fn_b_ctrs[counter];
444 /* "no" here is an array index, scaled to bytes later. */
445 return build4 (ARRAY_REF, gcov_type_node, fn_v_ctrs[counter],
446 build_int_cst (integer_type_node, no), NULL, NULL);
449 /* Generate a tree to access the address of COUNTER NO. */
451 tree
452 tree_coverage_counter_addr (unsigned counter, unsigned no)
454 tree gcov_type_node = get_gcov_type ();
456 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
457 no += fn_b_ctrs[counter];
459 /* "no" here is an array index, scaled to bytes later. */
460 return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node,
461 fn_v_ctrs[counter],
462 build_int_cst (integer_type_node, no),
463 NULL, NULL));
467 /* Generate a checksum for a string. CHKSUM is the current
468 checksum. */
470 static unsigned
471 coverage_checksum_string (unsigned chksum, const char *string)
473 int i;
474 char *dup = NULL;
476 /* Look for everything that looks if it were produced by
477 get_file_function_name and zero out the second part
478 that may result from flag_random_seed. This is not critical
479 as the checksums are used only for sanity checking. */
480 for (i = 0; string[i]; i++)
482 int offset = 0;
483 if (!strncmp (string + i, "_GLOBAL__N_", 11))
484 offset = 11;
485 if (!strncmp (string + i, "_GLOBAL__", 9))
486 offset = 9;
488 /* C++ namespaces do have scheme:
489 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
490 since filename might contain extra underscores there seems
491 to be no better chance then walk all possible offsets looking
492 for magicnumber. */
493 if (offset)
495 for (i = i + offset; string[i]; i++)
496 if (string[i]=='_')
498 int y;
500 for (y = 1; y < 9; y++)
501 if (!(string[i + y] >= '0' && string[i + y] <= '9')
502 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
503 break;
504 if (y != 9 || string[i + 9] != '_')
505 continue;
506 for (y = 10; y < 18; y++)
507 if (!(string[i + y] >= '0' && string[i + y] <= '9')
508 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
509 break;
510 if (y != 18)
511 continue;
512 if (!dup)
513 string = dup = xstrdup (string);
514 for (y = 10; y < 18; y++)
515 dup[i + y] = '0';
517 break;
521 chksum = crc32_string (chksum, string);
522 free (dup);
524 return chksum;
527 /* Compute checksum for the current function. We generate a CRC32. */
529 unsigned
530 coverage_compute_lineno_checksum (void)
532 expanded_location xloc
533 = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
534 unsigned chksum = xloc.line;
536 chksum = coverage_checksum_string (chksum, xloc.file);
537 chksum = coverage_checksum_string
538 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
540 return chksum;
543 /* Compute cfg checksum for the current function.
544 The checksum is calculated carefully so that
545 source code changes that doesn't affect the control flow graph
546 won't change the checksum.
547 This is to make the profile data useable across source code change.
548 The downside of this is that the compiler may use potentially
549 wrong profile data - that the source code change has non-trivial impact
550 on the validity of profile data (e.g. the reversed condition)
551 but the compiler won't detect the change and use the wrong profile data. */
553 unsigned
554 coverage_compute_cfg_checksum (void)
556 basic_block bb;
557 unsigned chksum = n_basic_blocks;
559 FOR_EACH_BB (bb)
561 edge e;
562 edge_iterator ei;
563 chksum = crc32_byte (chksum, bb->index);
564 FOR_EACH_EDGE (e, ei, bb->succs)
566 chksum = crc32_byte (chksum, e->dest->index);
570 return chksum;
573 /* Begin output to the notes file for the current function.
574 Writes the function header. Returns nonzero if data should be output. */
577 coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
579 expanded_location xloc;
580 unsigned long offset;
582 /* We don't need to output .gcno file unless we're under -ftest-coverage
583 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
584 if (no_coverage || !bbg_file_name)
585 return 0;
587 xloc = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
589 /* Announce function */
590 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
591 gcov_write_unsigned (current_function_funcdef_no + 1);
592 gcov_write_unsigned (lineno_checksum);
593 gcov_write_unsigned (cfg_checksum);
594 gcov_write_string (IDENTIFIER_POINTER
595 (DECL_ASSEMBLER_NAME (current_function_decl)));
596 gcov_write_string (xloc.file);
597 gcov_write_unsigned (xloc.line);
598 gcov_write_length (offset);
600 return !gcov_is_error ();
603 /* Finish coverage data for the current function. Verify no output
604 error has occurred. Save function coverage counts. */
606 void
607 coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum)
609 unsigned i;
611 if (bbg_file_name && gcov_is_error ())
613 warning (0, "error writing %qs", bbg_file_name);
614 unlink (bbg_file_name);
615 bbg_file_name = NULL;
618 if (fn_ctr_mask)
620 struct coverage_data *item = 0;
622 /* If the function is extern (i.e. extern inline), then we won't
623 be outputting it, so don't chain it onto the function
624 list. */
625 if (!DECL_EXTERNAL (current_function_decl))
627 item = ggc_alloc_coverage_data ();
629 item->ident = current_function_funcdef_no + 1;
630 item->lineno_checksum = lineno_checksum;
631 item->cfg_checksum = cfg_checksum;
633 item->fn_decl = current_function_decl;
634 item->next = 0;
635 *functions_tail = item;
636 functions_tail = &item->next;
639 for (i = 0; i != GCOV_COUNTERS; i++)
641 tree var = fn_v_ctrs[i];
643 if (item)
644 item->ctr_vars[i] = var;
645 if (var)
647 tree array_type = build_index_type (size_int (fn_n_ctrs[i] - 1));
648 array_type = build_array_type (get_gcov_type (), array_type);
649 TREE_TYPE (var) = array_type;
650 DECL_SIZE (var) = TYPE_SIZE (array_type);
651 DECL_SIZE_UNIT (var) = TYPE_SIZE_UNIT (array_type);
652 varpool_finalize_decl (var);
655 fn_b_ctrs[i] = fn_n_ctrs[i] = 0;
656 fn_v_ctrs[i] = NULL_TREE;
658 prg_ctr_mask |= fn_ctr_mask;
659 fn_ctr_mask = 0;
663 /* Build a coverage variable of TYPE for function FN_DECL. If COUNTER
664 >= 0 it is a counter array, otherwise it is the function structure. */
666 static tree
667 build_var (tree fn_decl, tree type, int counter)
669 tree var = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, type);
670 const char *fn_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn_decl));
671 char *buf;
672 size_t fn_name_len, len;
674 fn_name = targetm.strip_name_encoding (fn_name);
675 fn_name_len = strlen (fn_name);
676 buf = XALLOCAVEC (char, fn_name_len + 8 + sizeof (int) * 3);
678 if (counter < 0)
679 strcpy (buf, "__gcov__");
680 else
681 sprintf (buf, "__gcov%u_", counter);
682 len = strlen (buf);
683 #ifndef NO_DOT_IN_LABEL
684 buf[len - 1] = '.';
685 #elif !defined NO_DOLLAR_IN_LABEL
686 buf[len - 1] = '$';
687 #endif
688 memcpy (buf + len, fn_name, fn_name_len + 1);
689 DECL_NAME (var) = get_identifier (buf);
690 TREE_STATIC (var) = 1;
691 TREE_ADDRESSABLE (var) = 1;
692 DECL_ALIGN (var) = TYPE_ALIGN (type);
694 return var;
697 /* Creates the gcov_fn_info RECORD_TYPE. */
699 static void
700 build_fn_info_type (tree type, unsigned counters, tree gcov_info_type)
702 tree ctr_info = lang_hooks.types.make_type (RECORD_TYPE);
703 tree field, fields;
704 tree array_type;
706 gcc_assert (counters);
708 /* ctr_info::num */
709 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
710 get_gcov_unsigned_t ());
711 fields = field;
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;
717 fields = field;
719 finish_builtin_struct (ctr_info, "__gcov_ctr_info", fields, NULL_TREE);
721 /* key */
722 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
723 build_pointer_type (build_qualified_type
724 (gcov_info_type, TYPE_QUAL_CONST)));
725 fields = field;
727 /* ident */
728 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
729 get_gcov_unsigned_t ());
730 DECL_CHAIN (field) = fields;
731 fields = field;
733 /* lineno_checksum */
734 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
735 get_gcov_unsigned_t ());
736 DECL_CHAIN (field) = fields;
737 fields = field;
739 /* cfg checksum */
740 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
741 get_gcov_unsigned_t ());
742 DECL_CHAIN (field) = fields;
743 fields = field;
745 array_type = build_index_type (size_int (counters - 1));
746 array_type = build_array_type (ctr_info, array_type);
748 /* counters */
749 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, array_type);
750 DECL_CHAIN (field) = fields;
751 fields = field;
753 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
756 /* Returns a CONSTRUCTOR for a gcov_fn_info. DATA is
757 the coverage data for the function and TYPE is the gcov_fn_info
758 RECORD_TYPE. KEY is the object file key. */
760 static tree
761 build_fn_info (const struct coverage_data *data, tree type, tree key)
763 tree fields = TYPE_FIELDS (type);
764 tree ctr_type;
765 unsigned ix;
766 VEC(constructor_elt,gc) *v1 = NULL;
767 VEC(constructor_elt,gc) *v2 = NULL;
769 /* key */
770 CONSTRUCTOR_APPEND_ELT (v1, fields,
771 build1 (ADDR_EXPR, TREE_TYPE (fields), key));
772 fields = DECL_CHAIN (fields);
774 /* ident */
775 CONSTRUCTOR_APPEND_ELT (v1, fields,
776 build_int_cstu (get_gcov_unsigned_t (),
777 data->ident));
778 fields = DECL_CHAIN (fields);
780 /* lineno_checksum */
781 CONSTRUCTOR_APPEND_ELT (v1, fields,
782 build_int_cstu (get_gcov_unsigned_t (),
783 data->lineno_checksum));
784 fields = DECL_CHAIN (fields);
786 /* cfg_checksum */
787 CONSTRUCTOR_APPEND_ELT (v1, fields,
788 build_int_cstu (get_gcov_unsigned_t (),
789 data->cfg_checksum));
790 fields = DECL_CHAIN (fields);
792 /* counters */
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 = data->ctr_vars[ix];
799 unsigned count = 0;
801 if (var)
802 count
803 = tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var))), 0)
804 + 1;
806 CONSTRUCTOR_APPEND_ELT (ctr, TYPE_FIELDS (ctr_type),
807 build_int_cstu (get_gcov_unsigned_t (),
808 count));
810 if (var)
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 /* Create gcov_info struct. TYPE is the incomplete RECORD_TYPE to be
824 completed, and FN_INFO_PTR_TYPE is a pointer to the function info type. */
826 static void
827 build_info_type (tree type, tree fn_info_ptr_type)
829 tree field, fields = NULL_TREE;
830 tree merge_fn_type;
832 /* Version ident */
833 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
834 get_gcov_unsigned_t ());
835 DECL_CHAIN (field) = fields;
836 fields = field;
838 /* next pointer */
839 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
840 build_pointer_type (build_qualified_type
841 (type, TYPE_QUAL_CONST)));
842 DECL_CHAIN (field) = fields;
843 fields = field;
845 /* stamp */
846 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
847 get_gcov_unsigned_t ());
848 DECL_CHAIN (field) = fields;
849 fields = field;
851 /* Filename */
852 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
853 build_pointer_type (build_qualified_type
854 (char_type_node, TYPE_QUAL_CONST)));
855 DECL_CHAIN (field) = fields;
856 fields = field;
858 /* merge fn array */
859 merge_fn_type
860 = build_function_type_list (void_type_node,
861 build_pointer_type (get_gcov_type ()),
862 get_gcov_unsigned_t (), NULL_TREE);
863 merge_fn_type
864 = build_array_type (build_pointer_type (merge_fn_type),
865 build_index_type (size_int (GCOV_COUNTERS - 1)));
866 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
867 merge_fn_type);
868 DECL_CHAIN (field) = fields;
869 fields = field;
871 /* n_functions */
872 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
873 get_gcov_unsigned_t ());
874 DECL_CHAIN (field) = fields;
875 fields = field;
877 /* function_info pointer pointer */
878 fn_info_ptr_type = build_pointer_type
879 (build_qualified_type (fn_info_ptr_type, TYPE_QUAL_CONST));
880 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
881 fn_info_ptr_type);
882 DECL_CHAIN (field) = fields;
883 fields = field;
885 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
888 /* Returns a CONSTRUCTOR for the gcov_info object. INFO_TYPE is the
889 gcov_info structure type, FN_ARY is the array of pointers to
890 function info objects. */
892 static tree
893 build_info (tree info_type, tree fn_ary)
895 tree info_fields = TYPE_FIELDS (info_type);
896 tree merge_fn_type, n_funcs;
897 unsigned ix;
898 tree filename_string;
899 int da_file_name_len;
900 VEC(constructor_elt,gc) *v1 = NULL;
901 VEC(constructor_elt,gc) *v2 = NULL;
903 /* Version ident */
904 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
905 build_int_cstu (TREE_TYPE (info_fields),
906 GCOV_VERSION));
907 info_fields = DECL_CHAIN (info_fields);
909 /* next -- NULL */
910 CONSTRUCTOR_APPEND_ELT (v1, info_fields, null_pointer_node);
911 info_fields = DECL_CHAIN (info_fields);
913 /* stamp */
914 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
915 build_int_cstu (TREE_TYPE (info_fields),
916 bbg_file_stamp));
917 info_fields = DECL_CHAIN (info_fields);
919 /* Filename */
920 da_file_name_len = strlen (da_file_name);
921 filename_string = build_string (da_file_name_len + 1, da_file_name);
922 TREE_TYPE (filename_string) = build_array_type
923 (char_type_node, build_index_type (size_int (da_file_name_len)));
924 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
925 build1 (ADDR_EXPR, TREE_TYPE (info_fields),
926 filename_string));
927 info_fields = DECL_CHAIN (info_fields);
929 /* merge fn array -- NULL slots indicate unmeasured counters */
930 merge_fn_type = TREE_TYPE (TREE_TYPE (info_fields));
931 for (ix = 0; ix != GCOV_COUNTERS; ix++)
933 tree ptr = null_pointer_node;
935 if ((1u << ix) & prg_ctr_mask)
937 tree merge_fn = build_decl (BUILTINS_LOCATION,
938 FUNCTION_DECL,
939 get_identifier (ctr_merge_functions[ix]),
940 TREE_TYPE (merge_fn_type));
941 DECL_EXTERNAL (merge_fn) = 1;
942 TREE_PUBLIC (merge_fn) = 1;
943 DECL_ARTIFICIAL (merge_fn) = 1;
944 TREE_NOTHROW (merge_fn) = 1;
945 /* Initialize assembler name so we can stream out. */
946 DECL_ASSEMBLER_NAME (merge_fn);
947 ptr = build1 (ADDR_EXPR, merge_fn_type, merge_fn);
949 CONSTRUCTOR_APPEND_ELT (v2, NULL, ptr);
951 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
952 build_constructor (TREE_TYPE (info_fields), v2));
953 info_fields = DECL_CHAIN (info_fields);
955 /* n_functions */
956 n_funcs = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (fn_ary)));
957 n_funcs = fold_build2 (PLUS_EXPR, TREE_TYPE (info_fields),
958 n_funcs, size_one_node);
959 CONSTRUCTOR_APPEND_ELT (v1, info_fields, n_funcs);
960 info_fields = DECL_CHAIN (info_fields);
962 /* functions */
963 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
964 build1 (ADDR_EXPR, TREE_TYPE (info_fields), fn_ary));
965 info_fields = DECL_CHAIN (info_fields);
967 gcc_assert (!info_fields);
968 return build_constructor (info_type, v1);
971 /* Create the gcov_info types and object. Generate the constructor
972 function to call __gcov_init. Does not generate the initializer
973 for the object. Returns TRUE if coverage data is being emitted. */
975 static bool
976 coverage_obj_init (void)
978 tree gcov_info_type, ctor, stmt, init_fn;
979 unsigned n_counters = 0;
980 unsigned ix;
981 struct coverage_data *fn;
982 struct coverage_data **fn_prev;
983 char name_buf[32];
985 no_coverage = 1; /* Disable any further coverage. */
987 if (!prg_ctr_mask)
988 return false;
990 if (cgraph_dump_file)
991 fprintf (cgraph_dump_file, "Using data file %s\n", da_file_name);
993 /* Prune functions. */
994 for (fn_prev = &functions_head; (fn = *fn_prev);)
995 if (DECL_STRUCT_FUNCTION (fn->fn_decl))
996 fn_prev = &fn->next;
997 else
998 /* The function is not being emitted, remove from list. */
999 *fn_prev = fn->next;
1001 for (ix = 0; ix != GCOV_COUNTERS; ix++)
1002 if ((1u << ix) & prg_ctr_mask)
1003 n_counters++;
1005 /* Build the info and fn_info types. These are mutually recursive. */
1006 gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1007 gcov_fn_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1008 gcov_fn_info_ptr_type = build_pointer_type
1009 (build_qualified_type (gcov_fn_info_type, TYPE_QUAL_CONST));
1010 build_fn_info_type (gcov_fn_info_type, n_counters, gcov_info_type);
1011 build_info_type (gcov_info_type, gcov_fn_info_ptr_type);
1013 /* Build the gcov info var, this is referred to in its own
1014 initializer. */
1015 gcov_info_var = build_decl (BUILTINS_LOCATION,
1016 VAR_DECL, NULL_TREE, gcov_info_type);
1017 TREE_STATIC (gcov_info_var) = 1;
1018 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
1019 DECL_NAME (gcov_info_var) = get_identifier (name_buf);
1021 /* Build a decl for __gcov_init. */
1022 init_fn = build_pointer_type (gcov_info_type);
1023 init_fn = build_function_type_list (void_type_node, init_fn, NULL);
1024 init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
1025 get_identifier ("__gcov_init"), init_fn);
1026 TREE_PUBLIC (init_fn) = 1;
1027 DECL_EXTERNAL (init_fn) = 1;
1028 DECL_ASSEMBLER_NAME (init_fn);
1030 /* Generate a call to __gcov_init(&gcov_info). */
1031 ctor = NULL;
1032 stmt = build_fold_addr_expr (gcov_info_var);
1033 stmt = build_call_expr (init_fn, 1, stmt);
1034 append_to_statement_list (stmt, &ctor);
1036 /* Generate a constructor to run it. */
1037 cgraph_build_static_cdtor ('I', ctor, DEFAULT_INIT_PRIORITY);
1039 return true;
1042 /* Generate the coverage function info for FN and DATA. Append a
1043 pointer to that object to CTOR and return the appended CTOR. */
1045 static VEC(constructor_elt,gc) *
1046 coverage_obj_fn (VEC(constructor_elt,gc) *ctor, tree fn,
1047 struct coverage_data const *data)
1049 tree init = build_fn_info (data, gcov_fn_info_type, gcov_info_var);
1050 tree var = build_var (fn, gcov_fn_info_type, -1);
1052 DECL_INITIAL (var) = init;
1053 varpool_finalize_decl (var);
1055 CONSTRUCTOR_APPEND_ELT (ctor, NULL,
1056 build1 (ADDR_EXPR, gcov_fn_info_ptr_type, var));
1057 return ctor;
1060 /* Finalize the coverage data. Generates the array of pointers to
1061 function objects from CTOR. Generate the gcov_info initializer. */
1063 static void
1064 coverage_obj_finish (VEC(constructor_elt,gc) *ctor)
1066 unsigned n_functions = VEC_length(constructor_elt, ctor);
1067 tree fn_info_ary_type = build_array_type
1068 (build_qualified_type (gcov_fn_info_ptr_type, TYPE_QUAL_CONST),
1069 build_index_type (size_int (n_functions - 1)));
1070 tree fn_info_ary = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE,
1071 fn_info_ary_type);
1072 char name_buf[32];
1074 TREE_STATIC (fn_info_ary) = 1;
1075 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 1);
1076 DECL_NAME (fn_info_ary) = get_identifier (name_buf);
1077 DECL_INITIAL (fn_info_ary) = build_constructor (fn_info_ary_type, ctor);
1078 varpool_finalize_decl (fn_info_ary);
1080 DECL_INITIAL (gcov_info_var)
1081 = build_info (TREE_TYPE (gcov_info_var), fn_info_ary);
1082 varpool_finalize_decl (gcov_info_var);
1085 /* Perform file-level initialization. Read in data file, generate name
1086 of notes file. */
1088 void
1089 coverage_init (const char *filename)
1091 int len = strlen (filename);
1092 int prefix_len = 0;
1094 if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
1095 profile_data_prefix = getpwd ();
1097 if (profile_data_prefix)
1098 prefix_len = strlen (profile_data_prefix);
1100 /* Name of da file. */
1101 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
1102 + prefix_len + 2);
1104 if (profile_data_prefix)
1106 memcpy (da_file_name, profile_data_prefix, prefix_len);
1107 da_file_name[prefix_len++] = '/';
1109 memcpy (da_file_name + prefix_len, filename, len);
1110 strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX);
1112 bbg_file_stamp = local_tick;
1114 if (flag_branch_probabilities)
1115 read_counts_file ();
1117 /* Name of bbg file. */
1118 if (flag_test_coverage && !flag_compare_debug)
1120 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1);
1121 memcpy (bbg_file_name, filename, len);
1122 strcpy (bbg_file_name + len, GCOV_NOTE_SUFFIX);
1124 if (!gcov_open (bbg_file_name, -1))
1126 error ("cannot open %s", bbg_file_name);
1127 bbg_file_name = NULL;
1129 else
1131 gcov_write_unsigned (GCOV_NOTE_MAGIC);
1132 gcov_write_unsigned (GCOV_VERSION);
1133 gcov_write_unsigned (bbg_file_stamp);
1138 /* Performs file-level cleanup. Close notes file, generate coverage
1139 variables and constructor. */
1141 void
1142 coverage_finish (void)
1144 if (bbg_file_name && gcov_close ())
1145 unlink (bbg_file_name);
1147 if (!flag_branch_probabilities && flag_test_coverage
1148 && (!local_tick || local_tick == (unsigned)-1))
1149 /* Only remove the da file, if we're emitting coverage code and
1150 cannot uniquely stamp it. If we can stamp it, libgcov will DTRT. */
1151 unlink (da_file_name);
1153 if (coverage_obj_init ())
1155 VEC(constructor_elt,gc) *fn_ctor = NULL;
1156 struct coverage_data *fn;
1158 for (fn = functions_head; fn; fn = fn->next)
1159 fn_ctor = coverage_obj_fn (fn_ctor, fn->fn_decl, fn);
1160 coverage_obj_finish (fn_ctor);
1164 #include "gt-coverage.h"