* arm.h (TARGET_CPU_CPP_BUILTINS): Remove Maverick support.
[official-gcc.git] / gcc / coverage.c
blob8978afc0b82bd2fa22e1fa224afce30fd2f9df4d
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 "hashtab.h"
47 #include "tree-iterator.h"
48 #include "cgraph.h"
49 #include "tree-pass.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 output file for coverage output file. If this is NULL
101 we're not writing to the notes file. */
102 static char *bbg_file_name;
104 /* File stamp for graph file. */
105 static unsigned bbg_file_stamp;
107 /* Name of the count data file. */
108 static char *da_file_name;
110 /* Hash table of count data. */
111 static htab_t counts_hash = NULL;
113 /* The names of merge functions for counters. */
114 static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
115 static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
117 /* Forward declarations. */
118 static hashval_t htab_counts_entry_hash (const void *);
119 static int htab_counts_entry_eq (const void *, const void *);
120 static void htab_counts_entry_del (void *);
121 static void read_counts_file (void);
122 static tree build_var (tree, tree, int);
123 static void build_fn_info_type (tree, unsigned, tree);
124 static void build_info_type (tree, tree);
125 static tree build_fn_info (const struct coverage_data *, tree, tree);
126 static tree build_info (tree, tree);
127 static bool coverage_obj_init (void);
128 static VEC(constructor_elt,gc) *coverage_obj_fn
129 (VEC(constructor_elt,gc) *, tree, struct coverage_data const *);
130 static void coverage_obj_finish (VEC(constructor_elt,gc) *);
132 /* Return the type node for gcov_type. */
134 tree
135 get_gcov_type (void)
137 enum machine_mode mode = smallest_mode_for_size (GCOV_TYPE_SIZE, MODE_INT);
138 return lang_hooks.types.type_for_mode (mode, false);
141 /* Return the type node for gcov_unsigned_t. */
143 static tree
144 get_gcov_unsigned_t (void)
146 enum machine_mode mode = smallest_mode_for_size (32, MODE_INT);
147 return lang_hooks.types.type_for_mode (mode, true);
150 static hashval_t
151 htab_counts_entry_hash (const void *of)
153 const counts_entry_t *const entry = (const counts_entry_t *) of;
155 return entry->ident * GCOV_COUNTERS + entry->ctr;
158 static int
159 htab_counts_entry_eq (const void *of1, const void *of2)
161 const counts_entry_t *const entry1 = (const counts_entry_t *) of1;
162 const counts_entry_t *const entry2 = (const counts_entry_t *) of2;
164 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
167 static void
168 htab_counts_entry_del (void *of)
170 counts_entry_t *const entry = (counts_entry_t *) of;
172 free (entry->counts);
173 free (entry);
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 = htab_create (10,
216 htab_counts_entry_hash, htab_counts_entry_eq,
217 htab_counts_entry_del);
218 while ((tag = gcov_read_unsigned ()))
220 gcov_unsigned_t length;
221 gcov_position_t offset;
223 length = gcov_read_unsigned ();
224 offset = gcov_position ();
225 if (tag == GCOV_TAG_FUNCTION)
227 if (length)
229 fn_ident = gcov_read_unsigned ();
230 lineno_checksum = gcov_read_unsigned ();
231 cfg_checksum = gcov_read_unsigned ();
233 else
234 fn_ident = lineno_checksum = cfg_checksum = 0;
235 new_summary = 1;
237 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
239 struct gcov_summary sum;
240 unsigned ix;
242 if (new_summary)
243 memset (&summary, 0, sizeof (summary));
245 gcov_read_summary (&sum);
246 for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++)
248 summary.ctrs[ix].runs += sum.ctrs[ix].runs;
249 summary.ctrs[ix].sum_all += sum.ctrs[ix].sum_all;
250 if (summary.ctrs[ix].run_max < sum.ctrs[ix].run_max)
251 summary.ctrs[ix].run_max = sum.ctrs[ix].run_max;
252 summary.ctrs[ix].sum_max += sum.ctrs[ix].sum_max;
254 new_summary = 0;
256 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
258 counts_entry_t **slot, *entry, elt;
259 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
260 unsigned ix;
262 elt.ident = fn_ident;
263 elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
265 slot = (counts_entry_t **) htab_find_slot
266 (counts_hash, &elt, INSERT);
267 entry = *slot;
268 if (!entry)
270 *slot = entry = XCNEW (counts_entry_t);
271 entry->ident = fn_ident;
272 entry->ctr = elt.ctr;
273 entry->lineno_checksum = lineno_checksum;
274 entry->cfg_checksum = cfg_checksum;
275 entry->summary = summary.ctrs[elt.ctr];
276 entry->summary.num = n_counts;
277 entry->counts = XCNEWVEC (gcov_type, n_counts);
279 else if (entry->lineno_checksum != lineno_checksum
280 || entry->cfg_checksum != cfg_checksum)
282 error ("Profile data for function %u is corrupted", fn_ident);
283 error ("checksum is (%x,%x) instead of (%x,%x)",
284 entry->lineno_checksum, entry->cfg_checksum,
285 lineno_checksum, cfg_checksum);
286 htab_delete (counts_hash);
287 break;
289 else if (entry->summary.num != n_counts)
291 error ("Profile data for function %u is corrupted", fn_ident);
292 error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
293 htab_delete (counts_hash);
294 break;
296 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
298 error ("cannot merge separate %s counters for function %u",
299 ctr_names[elt.ctr], fn_ident);
300 goto skip_merge;
302 else
304 entry->summary.runs += summary.ctrs[elt.ctr].runs;
305 entry->summary.sum_all += summary.ctrs[elt.ctr].sum_all;
306 if (entry->summary.run_max < summary.ctrs[elt.ctr].run_max)
307 entry->summary.run_max = summary.ctrs[elt.ctr].run_max;
308 entry->summary.sum_max += summary.ctrs[elt.ctr].sum_max;
310 for (ix = 0; ix != n_counts; ix++)
311 entry->counts[ix] += gcov_read_counter ();
312 skip_merge:;
314 gcov_sync (offset, length);
315 if ((is_error = gcov_is_error ()))
317 error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted",
318 da_file_name);
319 htab_delete (counts_hash);
320 break;
324 gcov_close ();
327 /* Returns the counters for a particular tag. */
329 gcov_type *
330 get_coverage_counts (unsigned counter, unsigned expected,
331 unsigned cfg_checksum, unsigned lineno_checksum,
332 const struct gcov_ctr_summary **summary)
334 counts_entry_t *entry, elt;
336 /* No hash table, no counts. */
337 if (!counts_hash)
339 static int warned = 0;
341 if (!warned++)
342 inform (input_location, (flag_guess_branch_prob
343 ? "file %s not found, execution counts estimated"
344 : "file %s not found, execution counts assumed to be zero"),
345 da_file_name);
346 return NULL;
349 elt.ident = current_function_funcdef_no + 1;
350 elt.ctr = counter;
351 entry = (counts_entry_t *) htab_find (counts_hash, &elt);
352 if (!entry || !entry->summary.num)
353 /* The function was not emitted, or is weak and not chosen in the
354 final executable. Silently fail, because there's nothing we
355 can do about it. */
356 return NULL;
358 if (entry->cfg_checksum != cfg_checksum
359 || entry->summary.num != expected)
361 static int warned = 0;
362 bool warning_printed = false;
363 tree id = DECL_ASSEMBLER_NAME (current_function_decl);
365 warning_printed =
366 warning_at (input_location, OPT_Wcoverage_mismatch,
367 "the control flow of function %qE does not match "
368 "its profile data (counter %qs)", id, ctr_names[counter]);
369 if (warning_printed)
371 inform (input_location, "use -Wno-error=coverage-mismatch to tolerate "
372 "the mismatch but performance may drop if the function is hot");
374 if (!seen_error ()
375 && !warned++)
377 inform (input_location, "coverage mismatch ignored");
378 inform (input_location, flag_guess_branch_prob
379 ? G_("execution counts estimated")
380 : G_("execution counts assumed to be zero"));
381 if (!flag_guess_branch_prob)
382 inform (input_location,
383 "this can result in poorly optimized code");
387 return NULL;
389 else if (entry->lineno_checksum != lineno_checksum)
391 warning (0, "source locations for function %qE have changed,"
392 " the profile data may be out of date",
393 DECL_ASSEMBLER_NAME (current_function_decl));
396 if (summary)
397 *summary = &entry->summary;
399 return entry->counts;
402 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
403 allocation succeeded. */
406 coverage_counter_alloc (unsigned counter, unsigned num)
408 if (no_coverage)
409 return 0;
411 if (!num)
412 return 1;
414 if (!fn_v_ctrs[counter])
416 tree array_type = build_array_type (get_gcov_type (), NULL_TREE);
418 fn_v_ctrs[counter]
419 = build_var (current_function_decl, array_type, counter);
422 fn_b_ctrs[counter] = fn_n_ctrs[counter];
423 fn_n_ctrs[counter] += num;
425 fn_ctr_mask |= 1 << counter;
426 return 1;
429 /* Generate a tree to access COUNTER NO. */
431 tree
432 tree_coverage_counter_ref (unsigned counter, unsigned no)
434 tree gcov_type_node = get_gcov_type ();
436 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
438 no += fn_b_ctrs[counter];
440 /* "no" here is an array index, scaled to bytes later. */
441 return build4 (ARRAY_REF, gcov_type_node, fn_v_ctrs[counter],
442 build_int_cst (integer_type_node, no), NULL, NULL);
445 /* Generate a tree to access the address of COUNTER NO. */
447 tree
448 tree_coverage_counter_addr (unsigned counter, unsigned no)
450 tree gcov_type_node = get_gcov_type ();
452 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
453 no += fn_b_ctrs[counter];
455 /* "no" here is an array index, scaled to bytes later. */
456 return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node,
457 fn_v_ctrs[counter],
458 build_int_cst (integer_type_node, no),
459 NULL, NULL));
463 /* Generate a checksum for a string. CHKSUM is the current
464 checksum. */
466 static unsigned
467 coverage_checksum_string (unsigned chksum, const char *string)
469 int i;
470 char *dup = NULL;
472 /* Look for everything that looks if it were produced by
473 get_file_function_name and zero out the second part
474 that may result from flag_random_seed. This is not critical
475 as the checksums are used only for sanity checking. */
476 for (i = 0; string[i]; i++)
478 int offset = 0;
479 if (!strncmp (string + i, "_GLOBAL__N_", 11))
480 offset = 11;
481 if (!strncmp (string + i, "_GLOBAL__", 9))
482 offset = 9;
484 /* C++ namespaces do have scheme:
485 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
486 since filename might contain extra underscores there seems
487 to be no better chance then walk all possible offsets looking
488 for magicnumber. */
489 if (offset)
491 for (i = i + offset; string[i]; i++)
492 if (string[i]=='_')
494 int y;
496 for (y = 1; y < 9; y++)
497 if (!(string[i + y] >= '0' && string[i + y] <= '9')
498 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
499 break;
500 if (y != 9 || string[i + 9] != '_')
501 continue;
502 for (y = 10; y < 18; y++)
503 if (!(string[i + y] >= '0' && string[i + y] <= '9')
504 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
505 break;
506 if (y != 18)
507 continue;
508 if (!dup)
509 string = dup = xstrdup (string);
510 for (y = 10; y < 18; y++)
511 dup[i + y] = '0';
513 break;
517 chksum = crc32_string (chksum, string);
518 free (dup);
520 return chksum;
523 /* Compute checksum for the current function. We generate a CRC32. */
525 unsigned
526 coverage_compute_lineno_checksum (void)
528 expanded_location xloc
529 = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
530 unsigned chksum = xloc.line;
532 chksum = coverage_checksum_string (chksum, xloc.file);
533 chksum = coverage_checksum_string
534 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
536 return chksum;
539 /* Compute cfg checksum for the current function.
540 The checksum is calculated carefully so that
541 source code changes that doesn't affect the control flow graph
542 won't change the checksum.
543 This is to make the profile data useable across source code change.
544 The downside of this is that the compiler may use potentially
545 wrong profile data - that the source code change has non-trivial impact
546 on the validity of profile data (e.g. the reversed condition)
547 but the compiler won't detect the change and use the wrong profile data. */
549 unsigned
550 coverage_compute_cfg_checksum (void)
552 basic_block bb;
553 unsigned chksum = n_basic_blocks;
555 FOR_EACH_BB (bb)
557 edge e;
558 edge_iterator ei;
559 chksum = crc32_byte (chksum, bb->index);
560 FOR_EACH_EDGE (e, ei, bb->succs)
562 chksum = crc32_byte (chksum, e->dest->index);
566 return chksum;
569 /* Begin output to the graph file for the current function.
570 Writes the function header. Returns nonzero if data should be output. */
573 coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
575 expanded_location xloc;
576 unsigned long offset;
578 /* We don't need to output .gcno file unless we're under -ftest-coverage
579 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
580 if (no_coverage || !bbg_file_name)
581 return 0;
583 xloc = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
585 /* Announce function */
586 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
587 gcov_write_unsigned (current_function_funcdef_no + 1);
588 gcov_write_unsigned (lineno_checksum);
589 gcov_write_unsigned (cfg_checksum);
590 gcov_write_string (IDENTIFIER_POINTER
591 (DECL_ASSEMBLER_NAME (current_function_decl)));
592 gcov_write_string (xloc.file);
593 gcov_write_unsigned (xloc.line);
594 gcov_write_length (offset);
596 return !gcov_is_error ();
599 /* Finish coverage data for the current function. Verify no output
600 error has occurred. Save function coverage counts. */
602 void
603 coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum)
605 unsigned i;
607 if (bbg_file_name && gcov_is_error ())
609 warning (0, "error writing %qs", bbg_file_name);
610 unlink (bbg_file_name);
611 bbg_file_name = NULL;
614 if (fn_ctr_mask)
616 struct coverage_data *item = 0;
618 /* If the function is extern (i.e. extern inline), then we won't
619 be outputting it, so don't chain it onto the function
620 list. */
621 if (!DECL_EXTERNAL (current_function_decl))
623 item = ggc_alloc_coverage_data ();
625 item->ident = current_function_funcdef_no + 1;
626 item->lineno_checksum = lineno_checksum;
627 item->cfg_checksum = cfg_checksum;
629 item->fn_decl = current_function_decl;
630 item->next = 0;
631 *functions_tail = item;
632 functions_tail = &item->next;
635 for (i = 0; i != GCOV_COUNTERS; i++)
637 tree var = fn_v_ctrs[i];
639 if (item)
640 item->ctr_vars[i] = var;
641 if (var)
643 tree array_type = build_index_type (size_int (fn_n_ctrs[i] - 1));
644 array_type = build_array_type (get_gcov_type (), array_type);
645 TREE_TYPE (var) = array_type;
646 DECL_SIZE (var) = TYPE_SIZE (array_type);
647 DECL_SIZE_UNIT (var) = TYPE_SIZE_UNIT (array_type);
648 varpool_finalize_decl (var);
651 fn_b_ctrs[i] = fn_n_ctrs[i] = 0;
652 fn_v_ctrs[i] = NULL_TREE;
654 prg_ctr_mask |= fn_ctr_mask;
655 fn_ctr_mask = 0;
659 /* Build a coverage variable of TYPE for function FN_DECL. If COUNTER
660 >= 0 it is a counter array, otherwise it is the function structure. */
662 static tree
663 build_var (tree fn_decl, tree type, int counter)
665 tree var = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, type);
666 const char *fn_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn_decl));
667 char *buf;
668 size_t fn_name_len, len;
670 fn_name = targetm.strip_name_encoding (fn_name);
671 fn_name_len = strlen (fn_name);
672 buf = XALLOCAVEC (char, fn_name_len + 8 + sizeof (int) * 3);
674 if (counter < 0)
675 strcpy (buf, "__gcov__");
676 else
677 sprintf (buf, "__gcov%u_", counter);
678 len = strlen (buf);
679 #ifndef NO_DOT_IN_LABEL
680 buf[len - 1] = '.';
681 #elif !defined NO_DOLLAR_IN_LABEL
682 buf[len - 1] = '$';
683 #endif
684 memcpy (buf + len, fn_name, fn_name_len + 1);
685 DECL_NAME (var) = get_identifier (buf);
686 TREE_STATIC (var) = 1;
687 TREE_ADDRESSABLE (var) = 1;
688 DECL_ALIGN (var) = TYPE_ALIGN (type);
690 return var;
693 /* Creates the gcov_fn_info RECORD_TYPE. */
695 static void
696 build_fn_info_type (tree type, unsigned counters, tree gcov_info_type)
698 tree ctr_info = lang_hooks.types.make_type (RECORD_TYPE);
699 tree field, fields;
700 tree array_type;
702 gcc_assert (counters);
704 /* ctr_info::num */
705 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
706 get_gcov_unsigned_t ());
707 fields = field;
709 /* ctr_info::values */
710 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
711 build_pointer_type (get_gcov_type ()));
712 DECL_CHAIN (field) = fields;
713 fields = field;
715 finish_builtin_struct (ctr_info, "__gcov_ctr_info", fields, NULL_TREE);
717 /* key */
718 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
719 build_pointer_type (build_qualified_type
720 (gcov_info_type, TYPE_QUAL_CONST)));
721 fields = field;
723 /* ident */
724 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
725 get_gcov_unsigned_t ());
726 DECL_CHAIN (field) = fields;
727 fields = field;
729 /* lineno_checksum */
730 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
731 get_gcov_unsigned_t ());
732 DECL_CHAIN (field) = fields;
733 fields = field;
735 /* cfg checksum */
736 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
737 get_gcov_unsigned_t ());
738 DECL_CHAIN (field) = fields;
739 fields = field;
741 array_type = build_index_type (size_int (counters - 1));
742 array_type = build_array_type (ctr_info, array_type);
744 /* counters */
745 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, array_type);
746 DECL_CHAIN (field) = fields;
747 fields = field;
749 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
752 /* Returns a CONSTRUCTOR for a gcov_fn_info. DATA is
753 the coverage data for the function and TYPE is the gcov_fn_info
754 RECORD_TYPE. KEY is the object file key. */
756 static tree
757 build_fn_info (const struct coverage_data *data, tree type, tree key)
759 tree fields = TYPE_FIELDS (type);
760 tree ctr_type;
761 unsigned ix;
762 VEC(constructor_elt,gc) *v1 = NULL;
763 VEC(constructor_elt,gc) *v2 = NULL;
765 /* key */
766 CONSTRUCTOR_APPEND_ELT (v1, fields,
767 build1 (ADDR_EXPR, TREE_TYPE (fields), key));
768 fields = DECL_CHAIN (fields);
770 /* ident */
771 CONSTRUCTOR_APPEND_ELT (v1, fields,
772 build_int_cstu (get_gcov_unsigned_t (),
773 data->ident));
774 fields = DECL_CHAIN (fields);
776 /* lineno_checksum */
777 CONSTRUCTOR_APPEND_ELT (v1, fields,
778 build_int_cstu (get_gcov_unsigned_t (),
779 data->lineno_checksum));
780 fields = DECL_CHAIN (fields);
782 /* cfg_checksum */
783 CONSTRUCTOR_APPEND_ELT (v1, fields,
784 build_int_cstu (get_gcov_unsigned_t (),
785 data->cfg_checksum));
786 fields = DECL_CHAIN (fields);
788 /* counters */
789 ctr_type = TREE_TYPE (TREE_TYPE (fields));
790 for (ix = 0; ix != GCOV_COUNTERS; ix++)
791 if (prg_ctr_mask & (1 << ix))
793 VEC(constructor_elt,gc) *ctr = NULL;
794 tree var = data->ctr_vars[ix];
795 unsigned count = 0;
797 if (var)
798 count
799 = tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var))), 0)
800 + 1;
802 CONSTRUCTOR_APPEND_ELT (ctr, TYPE_FIELDS (ctr_type),
803 build_int_cstu (get_gcov_unsigned_t (),
804 count));
806 if (var)
807 CONSTRUCTOR_APPEND_ELT (ctr, DECL_CHAIN (TYPE_FIELDS (ctr_type)),
808 build_fold_addr_expr (var));
810 CONSTRUCTOR_APPEND_ELT (v2, NULL, build_constructor (ctr_type, ctr));
813 CONSTRUCTOR_APPEND_ELT (v1, fields,
814 build_constructor (TREE_TYPE (fields), v2));
816 return build_constructor (type, v1);
819 /* Create gcov_info struct. TYPE is the incomplete RECORD_TYPE to be
820 completed, and FN_INFO_PTR_TYPE is a pointer to the function info type. */
822 static void
823 build_info_type (tree type, tree fn_info_ptr_type)
825 tree field, fields = NULL_TREE;
826 tree merge_fn_type;
828 /* Version ident */
829 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
830 get_gcov_unsigned_t ());
831 DECL_CHAIN (field) = fields;
832 fields = field;
834 /* next pointer */
835 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
836 build_pointer_type (build_qualified_type
837 (type, TYPE_QUAL_CONST)));
838 DECL_CHAIN (field) = fields;
839 fields = field;
841 /* stamp */
842 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
843 get_gcov_unsigned_t ());
844 DECL_CHAIN (field) = fields;
845 fields = field;
847 /* Filename */
848 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
849 build_pointer_type (build_qualified_type
850 (char_type_node, TYPE_QUAL_CONST)));
851 DECL_CHAIN (field) = fields;
852 fields = field;
854 /* merge fn array */
855 merge_fn_type
856 = build_function_type_list (void_type_node,
857 build_pointer_type (get_gcov_type ()),
858 get_gcov_unsigned_t (), NULL_TREE);
859 merge_fn_type
860 = build_array_type (build_pointer_type (merge_fn_type),
861 build_index_type (size_int (GCOV_COUNTERS - 1)));
862 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
863 merge_fn_type);
864 DECL_CHAIN (field) = fields;
865 fields = field;
867 /* n_functions */
868 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
869 get_gcov_unsigned_t ());
870 DECL_CHAIN (field) = fields;
871 fields = field;
873 /* function_info pointer pointer */
874 fn_info_ptr_type = build_pointer_type
875 (build_qualified_type (fn_info_ptr_type, TYPE_QUAL_CONST));
876 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
877 fn_info_ptr_type);
878 DECL_CHAIN (field) = fields;
879 fields = field;
881 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
884 /* Returns a CONSTRUCTOR for the gcov_info object. INFO_TYPE is the
885 gcov_info structure type, FN_ARY is the array of pointers to
886 function info objects. */
888 static tree
889 build_info (tree info_type, tree fn_ary)
891 tree info_fields = TYPE_FIELDS (info_type);
892 tree merge_fn_type, n_funcs;
893 unsigned ix;
894 tree filename_string;
895 int da_file_name_len;
896 VEC(constructor_elt,gc) *v1 = NULL;
897 VEC(constructor_elt,gc) *v2 = NULL;
899 /* Version ident */
900 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
901 build_int_cstu (TREE_TYPE (info_fields),
902 GCOV_VERSION));
903 info_fields = DECL_CHAIN (info_fields);
905 /* next -- NULL */
906 CONSTRUCTOR_APPEND_ELT (v1, info_fields, null_pointer_node);
907 info_fields = DECL_CHAIN (info_fields);
909 /* stamp */
910 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
911 build_int_cstu (TREE_TYPE (info_fields),
912 bbg_file_stamp));
913 info_fields = DECL_CHAIN (info_fields);
915 /* Filename */
916 da_file_name_len = strlen (da_file_name);
917 filename_string = build_string (da_file_name_len + 1, da_file_name);
918 TREE_TYPE (filename_string) = build_array_type
919 (char_type_node, build_index_type (size_int (da_file_name_len)));
920 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
921 build1 (ADDR_EXPR, TREE_TYPE (info_fields),
922 filename_string));
923 info_fields = DECL_CHAIN (info_fields);
925 /* merge fn array -- NULL slots indicate unmeasured counters */
926 merge_fn_type = TREE_TYPE (TREE_TYPE (info_fields));
927 for (ix = 0; ix != GCOV_COUNTERS; ix++)
929 tree ptr = null_pointer_node;
931 if ((1u << ix) & prg_ctr_mask)
933 tree merge_fn = build_decl (BUILTINS_LOCATION,
934 FUNCTION_DECL,
935 get_identifier (ctr_merge_functions[ix]),
936 TREE_TYPE (merge_fn_type));
937 DECL_EXTERNAL (merge_fn) = 1;
938 TREE_PUBLIC (merge_fn) = 1;
939 DECL_ARTIFICIAL (merge_fn) = 1;
940 TREE_NOTHROW (merge_fn) = 1;
941 /* Initialize assembler name so we can stream out. */
942 DECL_ASSEMBLER_NAME (merge_fn);
943 ptr = build1 (ADDR_EXPR, merge_fn_type, merge_fn);
945 CONSTRUCTOR_APPEND_ELT (v2, NULL, ptr);
947 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
948 build_constructor (TREE_TYPE (info_fields), v2));
949 info_fields = DECL_CHAIN (info_fields);
951 /* n_functions */
952 n_funcs = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (fn_ary)));
953 n_funcs = fold_build2 (PLUS_EXPR, TREE_TYPE (info_fields),
954 n_funcs, size_one_node);
955 CONSTRUCTOR_APPEND_ELT (v1, info_fields, n_funcs);
956 info_fields = DECL_CHAIN (info_fields);
958 /* functions */
959 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
960 build1 (ADDR_EXPR, TREE_TYPE (info_fields), fn_ary));
961 info_fields = DECL_CHAIN (info_fields);
963 gcc_assert (!info_fields);
964 return build_constructor (info_type, v1);
967 /* Create the gcov_info types and object. Generate the constructor
968 function to call __gcov_init. Does not generate the initializer
969 for the object. Returns TRUE if coverage data is being emitted. */
971 static bool
972 coverage_obj_init (void)
974 tree gcov_info_type, ctor, stmt, init_fn;
975 unsigned n_counters = 0;
976 unsigned ix;
977 struct coverage_data *fn;
978 struct coverage_data **fn_prev;
979 char name_buf[32];
981 no_coverage = 1; /* Disable any further coverage. */
983 if (!prg_ctr_mask)
984 return false;
986 if (cgraph_dump_file)
987 fprintf (cgraph_dump_file, "Using data file %s\n", da_file_name);
989 /* Prune functions. */
990 for (fn_prev = &functions_head; (fn = *fn_prev);)
991 if (DECL_STRUCT_FUNCTION (fn->fn_decl))
992 fn_prev = &fn->next;
993 else
994 /* The function is not being emitted, remove from list. */
995 *fn_prev = fn->next;
997 for (ix = 0; ix != GCOV_COUNTERS; ix++)
998 if ((1u << ix) & prg_ctr_mask)
999 n_counters++;
1001 /* Build the info and fn_info types. These are mutually recursive. */
1002 gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1003 gcov_fn_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1004 gcov_fn_info_ptr_type = build_pointer_type
1005 (build_qualified_type (gcov_fn_info_type, TYPE_QUAL_CONST));
1006 build_fn_info_type (gcov_fn_info_type, n_counters, gcov_info_type);
1007 build_info_type (gcov_info_type, gcov_fn_info_ptr_type);
1009 /* Build the gcov info var, this is referred to in its own
1010 initializer. */
1011 gcov_info_var = build_decl (BUILTINS_LOCATION,
1012 VAR_DECL, NULL_TREE, gcov_info_type);
1013 TREE_STATIC (gcov_info_var) = 1;
1014 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
1015 DECL_NAME (gcov_info_var) = get_identifier (name_buf);
1017 /* Build a decl for __gcov_init. */
1018 init_fn = build_pointer_type (gcov_info_type);
1019 init_fn = build_function_type_list (void_type_node, init_fn, NULL);
1020 init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
1021 get_identifier ("__gcov_init"), init_fn);
1022 TREE_PUBLIC (init_fn) = 1;
1023 DECL_EXTERNAL (init_fn) = 1;
1024 DECL_ASSEMBLER_NAME (init_fn);
1026 /* Generate a call to __gcov_init(&gcov_info). */
1027 ctor = NULL;
1028 stmt = build_fold_addr_expr (gcov_info_var);
1029 stmt = build_call_expr (init_fn, 1, stmt);
1030 append_to_statement_list (stmt, &ctor);
1032 /* Generate a constructor to run it. */
1033 cgraph_build_static_cdtor ('I', ctor, DEFAULT_INIT_PRIORITY);
1035 return true;
1038 /* Generate the coverage function info for FN and DATA. Append a
1039 pointer to that object to CTOR and return the appended CTOR. */
1041 static VEC(constructor_elt,gc) *
1042 coverage_obj_fn (VEC(constructor_elt,gc) *ctor, tree fn,
1043 struct coverage_data const *data)
1045 tree init = build_fn_info (data, gcov_fn_info_type, gcov_info_var);
1046 tree var = build_var (fn, gcov_fn_info_type, -1);
1048 DECL_INITIAL (var) = init;
1049 varpool_finalize_decl (var);
1051 CONSTRUCTOR_APPEND_ELT (ctor, NULL,
1052 build1 (ADDR_EXPR, gcov_fn_info_ptr_type, var));
1053 return ctor;
1056 /* Finalize the coverage data. Generates the array of pointers to
1057 function objects from CTOR. Generate the gcov_info initializer. */
1059 static void
1060 coverage_obj_finish (VEC(constructor_elt,gc) *ctor)
1062 unsigned n_functions = VEC_length(constructor_elt, ctor);
1063 tree fn_info_ary_type = build_array_type
1064 (build_qualified_type (gcov_fn_info_ptr_type, TYPE_QUAL_CONST),
1065 build_index_type (size_int (n_functions - 1)));
1066 tree fn_info_ary = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE,
1067 fn_info_ary_type);
1068 char name_buf[32];
1070 TREE_STATIC (fn_info_ary) = 1;
1071 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 1);
1072 DECL_NAME (fn_info_ary) = get_identifier (name_buf);
1073 DECL_INITIAL (fn_info_ary) = build_constructor (fn_info_ary_type, ctor);
1074 varpool_finalize_decl (fn_info_ary);
1076 DECL_INITIAL (gcov_info_var)
1077 = build_info (TREE_TYPE (gcov_info_var), fn_info_ary);
1078 varpool_finalize_decl (gcov_info_var);
1081 /* Perform file-level initialization. Read in data file, generate name
1082 of graph file. */
1084 void
1085 coverage_init (const char *filename)
1087 int len = strlen (filename);
1088 int prefix_len = 0;
1090 if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
1091 profile_data_prefix = getpwd ();
1093 if (profile_data_prefix)
1094 prefix_len = strlen (profile_data_prefix);
1096 /* Name of da file. */
1097 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
1098 + prefix_len + 2);
1100 if (profile_data_prefix)
1102 memcpy (da_file_name, profile_data_prefix, prefix_len);
1103 da_file_name[prefix_len++] = '/';
1105 memcpy (da_file_name + prefix_len, filename, len);
1106 strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX);
1108 bbg_file_stamp = local_tick;
1110 if (flag_branch_probabilities)
1111 read_counts_file ();
1113 /* Name of bbg file. */
1114 if (flag_test_coverage && !flag_compare_debug)
1116 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1);
1117 memcpy (bbg_file_name, filename, len);
1118 strcpy (bbg_file_name + len, GCOV_NOTE_SUFFIX);
1120 if (!gcov_open (bbg_file_name, -1))
1122 error ("cannot open %s", bbg_file_name);
1123 bbg_file_name = NULL;
1125 else
1127 gcov_write_unsigned (GCOV_NOTE_MAGIC);
1128 gcov_write_unsigned (GCOV_VERSION);
1129 gcov_write_unsigned (bbg_file_stamp);
1134 /* Performs file-level cleanup. Close graph file, generate coverage
1135 variables and constructor. */
1137 void
1138 coverage_finish (void)
1140 if (bbg_file_name && gcov_close ())
1141 unlink (bbg_file_name);
1143 if (!flag_branch_probabilities && flag_test_coverage
1144 && (!local_tick || local_tick == (unsigned)-1))
1145 /* Only remove the da file, if we're emitting coverage code and
1146 cannot uniquely stamp it. If we can stamp it, libgcov will DTRT. */
1147 unlink (da_file_name);
1149 if (coverage_obj_init ())
1151 VEC(constructor_elt,gc) *fn_ctor = NULL;
1152 struct coverage_data *fn;
1154 for (fn = functions_head; fn; fn = fn->next)
1155 fn_ctor = coverage_obj_fn (fn_ctor, fn->fn_decl, fn);
1156 coverage_obj_finish (fn_ctor);
1160 #include "gt-coverage.h"