split checksum into cfg checksum and line checksum
[official-gcc.git] / gcc / coverage.c
blob1efd714c94091222f44cffc1926ff8431e632612
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
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"
54 #include "gcov-io.h"
55 #include "gcov-io.c"
57 struct function_list
59 struct function_list *next; /* next function */
60 unsigned ident; /* function ident */
61 unsigned lineno_checksum; /* function lineno checksum */
62 unsigned cfg_checksum; /* function cfg checksum */
63 unsigned n_ctrs[GCOV_COUNTERS];/* number of counters. */
66 /* Counts information for a function. */
67 typedef struct counts_entry
69 /* We hash by */
70 unsigned ident;
71 unsigned ctr;
73 /* Store */
74 unsigned lineno_checksum;
75 unsigned cfg_checksum;
76 gcov_type *counts;
77 struct gcov_ctr_summary summary;
79 /* Workspace */
80 struct counts_entry *chain;
82 } counts_entry_t;
84 static struct function_list *functions_head = 0;
85 static struct function_list **functions_tail = &functions_head;
86 static unsigned no_coverage = 0;
88 /* Cumulative counter information for whole program. */
89 static unsigned prg_ctr_mask; /* Mask of counter types generated. */
90 static unsigned prg_n_ctrs[GCOV_COUNTERS]; /* Total counters allocated. */
92 /* Counter information for current function. */
93 static unsigned fn_ctr_mask; /* Mask of counters used. */
94 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated. */
95 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base. */
97 /* Name of the output file for coverage output file. */
98 static char *bbg_file_name;
99 static unsigned bbg_file_opened;
100 static int bbg_function_announced;
102 /* Name of the count data file. */
103 static char *da_file_name;
105 /* Hash table of count data. */
106 static htab_t counts_hash = NULL;
108 /* Trees representing the counter table arrays. */
109 static GTY(()) tree tree_ctr_tables[GCOV_COUNTERS];
111 /* The names of merge functions for counters. */
112 static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
113 static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
115 /* Forward declarations. */
116 static hashval_t htab_counts_entry_hash (const void *);
117 static int htab_counts_entry_eq (const void *, const void *);
118 static void htab_counts_entry_del (void *);
119 static void read_counts_file (void);
120 static tree build_fn_info_type (unsigned);
121 static tree build_fn_info_value (const struct function_list *, tree);
122 static tree build_ctr_info_type (void);
123 static tree build_ctr_info_value (unsigned, tree);
124 static tree build_gcov_info (void);
125 static void create_coverage (void);
127 /* Return the type node for gcov_type. */
129 tree
130 get_gcov_type (void)
132 return lang_hooks.types.type_for_size (GCOV_TYPE_SIZE, false);
135 /* Return the type node for gcov_unsigned_t. */
137 static tree
138 get_gcov_unsigned_t (void)
140 return lang_hooks.types.type_for_size (32, true);
143 static hashval_t
144 htab_counts_entry_hash (const void *of)
146 const counts_entry_t *const entry = (const counts_entry_t *) of;
148 return entry->ident * GCOV_COUNTERS + entry->ctr;
151 static int
152 htab_counts_entry_eq (const void *of1, const void *of2)
154 const counts_entry_t *const entry1 = (const counts_entry_t *) of1;
155 const counts_entry_t *const entry2 = (const counts_entry_t *) of2;
157 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
160 static void
161 htab_counts_entry_del (void *of)
163 counts_entry_t *const entry = (counts_entry_t *) of;
165 free (entry->counts);
166 free (entry);
169 /* Read in the counts file, if available. */
171 static void
172 read_counts_file (void)
174 gcov_unsigned_t fn_ident = 0;
175 counts_entry_t *summaried = NULL;
176 unsigned seen_summary = 0;
177 gcov_unsigned_t tag;
178 int is_error = 0;
179 unsigned lineno_checksum = 0;
180 unsigned cfg_checksum = 0;
182 if (!gcov_open (da_file_name, 1))
183 return;
185 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
187 warning (0, "%qs is not a gcov data file", da_file_name);
188 gcov_close ();
189 return;
191 else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
193 char v[4], e[4];
195 GCOV_UNSIGNED2STRING (v, tag);
196 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
198 warning (0, "%qs is version %q.*s, expected version %q.*s",
199 da_file_name, 4, v, 4, e);
200 gcov_close ();
201 return;
204 /* Read and discard the stamp. */
205 gcov_read_unsigned ();
207 counts_hash = htab_create (10,
208 htab_counts_entry_hash, htab_counts_entry_eq,
209 htab_counts_entry_del);
210 while ((tag = gcov_read_unsigned ()))
212 gcov_unsigned_t length;
213 gcov_position_t offset;
215 length = gcov_read_unsigned ();
216 offset = gcov_position ();
217 if (tag == GCOV_TAG_FUNCTION)
219 fn_ident = gcov_read_unsigned ();
220 lineno_checksum = gcov_read_unsigned ();
221 cfg_checksum = gcov_read_unsigned ();
222 if (seen_summary)
224 /* We have already seen a summary, this means that this
225 new function begins a new set of program runs. We
226 must unlink the summaried chain. */
227 counts_entry_t *entry, *chain;
229 for (entry = summaried; entry; entry = chain)
231 chain = entry->chain;
232 entry->chain = NULL;
234 summaried = NULL;
235 seen_summary = 0;
238 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
240 counts_entry_t *entry;
241 struct gcov_summary summary;
243 gcov_read_summary (&summary);
244 seen_summary = 1;
245 for (entry = summaried; entry; entry = entry->chain)
247 struct gcov_ctr_summary *csum = &summary.ctrs[entry->ctr];
249 entry->summary.runs += csum->runs;
250 entry->summary.sum_all += csum->sum_all;
251 if (entry->summary.run_max < csum->run_max)
252 entry->summary.run_max = csum->run_max;
253 entry->summary.sum_max += csum->sum_max;
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.num = n_counts;
276 entry->counts = XCNEWVEC (gcov_type, n_counts);
278 else if (entry->lineno_checksum != lineno_checksum
279 || entry->cfg_checksum != cfg_checksum)
281 error ("Profile data for function %u is corrupted", fn_ident);
282 error ("checksum is (%x,%x) instead of (%x,%x)",
283 entry->lineno_checksum, entry->cfg_checksum,
284 lineno_checksum, cfg_checksum);
285 htab_delete (counts_hash);
286 break;
288 else if (entry->summary.num != n_counts)
290 error ("Profile data for function %u is corrupted", fn_ident);
291 error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
292 htab_delete (counts_hash);
293 break;
295 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
297 error ("cannot merge separate %s counters for function %u",
298 ctr_names[elt.ctr], fn_ident);
299 goto skip_merge;
302 if (elt.ctr < GCOV_COUNTERS_SUMMABLE
303 /* This should always be true for a just allocated entry,
304 and always false for an existing one. Check this way, in
305 case the gcov file is corrupt. */
306 && (!entry->chain || summaried != entry))
308 entry->chain = summaried;
309 summaried = entry;
311 for (ix = 0; ix != n_counts; ix++)
312 entry->counts[ix] += gcov_read_counter ();
313 skip_merge:;
315 gcov_sync (offset, length);
316 if ((is_error = gcov_is_error ()))
318 error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted",
319 da_file_name);
320 htab_delete (counts_hash);
321 break;
325 gcov_close ();
328 /* Returns the counters for a particular tag. */
330 gcov_type *
331 get_coverage_counts (unsigned counter, unsigned expected,
332 unsigned cfg_checksum, unsigned lineno_checksum,
333 const struct gcov_ctr_summary **summary)
335 counts_entry_t *entry, elt;
337 /* No hash table, no counts. */
338 if (!counts_hash)
340 static int warned = 0;
342 if (!warned++)
343 inform (input_location, (flag_guess_branch_prob
344 ? "file %s not found, execution counts estimated"
345 : "file %s not found, execution counts assumed to be zero"),
346 da_file_name);
347 return NULL;
350 elt.ident = current_function_funcdef_no + 1;
351 elt.ctr = counter;
352 entry = (counts_entry_t *) htab_find (counts_hash, &elt);
353 if (!entry)
355 warning (0, "no coverage for function %qE found",
356 DECL_ASSEMBLER_NAME (current_function_decl));
357 return NULL;
360 if (entry->cfg_checksum != cfg_checksum
361 || entry->summary.num != expected)
363 static int warned = 0;
364 bool warning_printed = false;
365 tree id = DECL_ASSEMBLER_NAME (current_function_decl);
367 warning_printed =
368 warning_at (input_location, OPT_Wcoverage_mismatch,
369 "The control flow of function %qE does not match "
370 "its profile data (counter %qs)", id, ctr_names[counter]);
371 if (warning_printed)
373 inform (input_location, "Use -Wno-error=coverage-mismatch to tolerate "
374 "the mismatch but performance may drop if the function is hot");
376 if (!seen_error ()
377 && !warned++)
379 inform (input_location, "coverage mismatch ignored");
380 inform (input_location, flag_guess_branch_prob
381 ? G_("execution counts estimated")
382 : G_("execution counts assumed to be zero"));
383 if (!flag_guess_branch_prob)
384 inform (input_location,
385 "this can result in poorly optimized code");
389 return NULL;
391 else if (entry->lineno_checksum != lineno_checksum)
393 warning (0, "Source location for function %qE have changed,"
394 " the profile data may be out of date",
395 DECL_ASSEMBLER_NAME (current_function_decl));
398 if (summary)
399 *summary = &entry->summary;
401 return entry->counts;
404 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
405 allocation succeeded. */
408 coverage_counter_alloc (unsigned counter, unsigned num)
410 if (no_coverage)
411 return 0;
413 if (!num)
414 return 1;
416 if (!tree_ctr_tables[counter])
418 /* Generate and save a copy of this so it can be shared. Leave
419 the index type unspecified for now; it will be set after all
420 functions have been compiled. */
421 char buf[20];
422 tree gcov_type_node = get_gcov_type ();
423 tree gcov_type_array_type
424 = build_array_type (gcov_type_node, NULL_TREE);
425 tree_ctr_tables[counter]
426 = build_decl (BUILTINS_LOCATION,
427 VAR_DECL, NULL_TREE, gcov_type_array_type);
428 TREE_STATIC (tree_ctr_tables[counter]) = 1;
429 ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", counter + 1);
430 DECL_NAME (tree_ctr_tables[counter]) = get_identifier (buf);
431 DECL_ALIGN (tree_ctr_tables[counter]) = TYPE_ALIGN (gcov_type_node);
433 if (dump_file)
434 fprintf (dump_file, "Using data file %s\n", da_file_name);
436 fn_b_ctrs[counter] = fn_n_ctrs[counter];
437 fn_n_ctrs[counter] += num;
438 fn_ctr_mask |= 1 << counter;
439 return 1;
442 /* Generate a tree to access COUNTER NO. */
444 tree
445 tree_coverage_counter_ref (unsigned counter, unsigned no)
447 tree gcov_type_node = get_gcov_type ();
449 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
450 no += prg_n_ctrs[counter] + fn_b_ctrs[counter];
452 /* "no" here is an array index, scaled to bytes later. */
453 return build4 (ARRAY_REF, gcov_type_node, tree_ctr_tables[counter],
454 build_int_cst (NULL_TREE, no), NULL, NULL);
457 /* Generate a tree to access the address of COUNTER NO. */
459 tree
460 tree_coverage_counter_addr (unsigned counter, unsigned no)
462 tree gcov_type_node = get_gcov_type ();
464 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
465 no += prg_n_ctrs[counter] + fn_b_ctrs[counter];
467 TREE_ADDRESSABLE (tree_ctr_tables[counter]) = 1;
469 /* "no" here is an array index, scaled to bytes later. */
470 return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node,
471 tree_ctr_tables[counter],
472 build_int_cst (NULL_TREE, no),
473 NULL, NULL));
477 /* Generate a checksum for a string. CHKSUM is the current
478 checksum. */
480 static unsigned
481 coverage_checksum_string (unsigned chksum, const char *string)
483 int i;
484 char *dup = NULL;
486 /* Look for everything that looks if it were produced by
487 get_file_function_name and zero out the second part
488 that may result from flag_random_seed. This is not critical
489 as the checksums are used only for sanity checking. */
490 for (i = 0; string[i]; i++)
492 int offset = 0;
493 if (!strncmp (string + i, "_GLOBAL__N_", 11))
494 offset = 11;
495 if (!strncmp (string + i, "_GLOBAL__", 9))
496 offset = 9;
498 /* C++ namespaces do have scheme:
499 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
500 since filename might contain extra underscores there seems
501 to be no better chance then walk all possible offsets looking
502 for magicnumber. */
503 if (offset)
505 for (i = i + offset; string[i]; i++)
506 if (string[i]=='_')
508 int y;
510 for (y = 1; y < 9; y++)
511 if (!(string[i + y] >= '0' && string[i + y] <= '9')
512 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
513 break;
514 if (y != 9 || string[i + 9] != '_')
515 continue;
516 for (y = 10; y < 18; y++)
517 if (!(string[i + y] >= '0' && string[i + y] <= '9')
518 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
519 break;
520 if (y != 18)
521 continue;
522 if (!dup)
523 string = dup = xstrdup (string);
524 for (y = 10; y < 18; y++)
525 dup[i + y] = '0';
527 break;
531 chksum = crc32_string (chksum, string);
532 free (dup);
534 return chksum;
537 /* Compute checksum for the current function. We generate a CRC32. */
539 unsigned
540 coverage_compute_lineno_checksum (void)
542 expanded_location xloc
543 = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
544 unsigned chksum = xloc.line;
546 chksum = coverage_checksum_string (chksum, xloc.file);
547 chksum = coverage_checksum_string
548 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
550 return chksum;
553 /* Compute cfg checksum for the current function.
554 The checksum is calculated carefully so that
555 source code changes that doesn't affect the control flow graph
556 won't change the checksum.
557 This is to make the profile data useable across source code change.
558 The downside of this is that the compiler may use potentially
559 wrong profile data - that the source code change has non-trivial impact
560 on the validity of profile data (e.g. the reversed condition)
561 but the compiler won't detect the change and use the wrong profile data. */
563 unsigned
564 coverage_compute_cfg_checksum (void)
566 basic_block bb;
567 unsigned chksum = n_basic_blocks;
569 FOR_EACH_BB (bb)
571 edge e;
572 edge_iterator ei;
573 chksum = crc32_byte (chksum, bb->index);
574 FOR_EACH_EDGE (e, ei, bb->succs)
576 chksum = crc32_byte (chksum, e->dest->index);
580 return chksum;
583 /* Begin output to the graph file for the current function.
584 Opens the output file, if not already done. Writes the
585 function header, if not already done. Returns nonzero if data
586 should be output. */
589 coverage_begin_output (unsigned lineno_checksum, unsigned cfg_checksum)
591 /* We don't need to output .gcno file unless we're under -ftest-coverage
592 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
593 if (no_coverage || !flag_test_coverage || flag_compare_debug)
594 return 0;
596 if (!bbg_function_announced)
598 expanded_location xloc
599 = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
600 unsigned long offset;
602 if (!bbg_file_opened)
604 if (!gcov_open (bbg_file_name, -1))
605 error ("cannot open %s", bbg_file_name);
606 else
608 gcov_write_unsigned (GCOV_NOTE_MAGIC);
609 gcov_write_unsigned (GCOV_VERSION);
610 gcov_write_unsigned (local_tick);
612 bbg_file_opened = 1;
616 /* Announce function */
617 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
618 gcov_write_unsigned (current_function_funcdef_no + 1);
619 gcov_write_unsigned (lineno_checksum);
620 gcov_write_unsigned (cfg_checksum);
621 gcov_write_string (IDENTIFIER_POINTER
622 (DECL_ASSEMBLER_NAME (current_function_decl)));
623 gcov_write_string (xloc.file);
624 gcov_write_unsigned (xloc.line);
625 gcov_write_length (offset);
627 bbg_function_announced = 1;
629 return !gcov_is_error ();
632 /* Finish coverage data for the current function. Verify no output
633 error has occurred. Save function coverage counts. */
635 void
636 coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum)
638 unsigned i;
640 if (bbg_file_opened > 1 && gcov_is_error ())
642 warning (0, "error writing %qs", bbg_file_name);
643 bbg_file_opened = -1;
646 if (fn_ctr_mask)
648 struct function_list *item;
650 item = XNEW (struct function_list);
652 *functions_tail = item;
653 functions_tail = &item->next;
656 item->next = 0;
657 item->ident = current_function_funcdef_no + 1;
658 item->lineno_checksum = lineno_checksum;
659 item->cfg_checksum = cfg_checksum;
660 for (i = 0; i != GCOV_COUNTERS; i++)
662 item->n_ctrs[i] = fn_n_ctrs[i];
663 prg_n_ctrs[i] += fn_n_ctrs[i];
664 fn_n_ctrs[i] = fn_b_ctrs[i] = 0;
666 prg_ctr_mask |= fn_ctr_mask;
667 fn_ctr_mask = 0;
669 bbg_function_announced = 0;
672 /* Creates the gcov_fn_info RECORD_TYPE. */
674 static tree
675 build_fn_info_type (unsigned int counters)
677 tree type = lang_hooks.types.make_type (RECORD_TYPE);
678 tree field, fields;
679 tree array_type;
681 /* ident */
682 fields = build_decl (BUILTINS_LOCATION,
683 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
684 /* lineno_checksum */
685 field = build_decl (BUILTINS_LOCATION,
686 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
687 DECL_CHAIN (field) = fields;
688 fields = field;
690 /* cfg checksum */
691 field = build_decl (BUILTINS_LOCATION,
692 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
693 DECL_CHAIN (field) = fields;
694 fields = field;
696 array_type = build_int_cst (NULL_TREE, counters - 1);
697 array_type = build_index_type (array_type);
698 array_type = build_array_type (get_gcov_unsigned_t (), array_type);
700 /* counters */
701 field = build_decl (BUILTINS_LOCATION,
702 FIELD_DECL, NULL_TREE, array_type);
703 DECL_CHAIN (field) = fields;
704 fields = field;
706 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
708 return type;
711 /* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is
712 the function being processed and TYPE is the gcov_fn_info
713 RECORD_TYPE. */
715 static tree
716 build_fn_info_value (const struct function_list *function, tree type)
718 tree fields = TYPE_FIELDS (type);
719 unsigned ix;
720 VEC(constructor_elt,gc) *v1 = NULL;
721 VEC(constructor_elt,gc) *v2 = NULL;
723 /* ident */
724 CONSTRUCTOR_APPEND_ELT (v1, fields,
725 build_int_cstu (get_gcov_unsigned_t (),
726 function->ident));
727 fields = DECL_CHAIN (fields);
729 /* lineno_checksum */
730 CONSTRUCTOR_APPEND_ELT (v1, fields,
731 build_int_cstu (get_gcov_unsigned_t (),
732 function->lineno_checksum));
733 fields = DECL_CHAIN (fields);
735 /* cfg_checksum */
736 CONSTRUCTOR_APPEND_ELT (v1, fields,
737 build_int_cstu (get_gcov_unsigned_t (),
738 function->cfg_checksum));
739 fields = DECL_CHAIN (fields);
741 /* counters */
742 for (ix = 0; ix != GCOV_COUNTERS; ix++)
743 if (prg_ctr_mask & (1 << ix))
744 CONSTRUCTOR_APPEND_ELT (v2, NULL,
745 build_int_cstu (get_gcov_unsigned_t (),
746 function->n_ctrs[ix]));
748 CONSTRUCTOR_APPEND_ELT (v1, fields,
749 build_constructor (TREE_TYPE (fields), v2));
751 return build_constructor (type, v1);
754 /* Creates the gcov_ctr_info RECORD_TYPE. */
756 static tree
757 build_ctr_info_type (void)
759 tree type = lang_hooks.types.make_type (RECORD_TYPE);
760 tree field, fields = NULL_TREE;
761 tree gcov_ptr_type = build_pointer_type (get_gcov_type ());
762 tree gcov_merge_fn_type;
764 /* counters */
765 field = build_decl (BUILTINS_LOCATION,
766 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
767 DECL_CHAIN (field) = fields;
768 fields = field;
770 /* values */
771 field = build_decl (BUILTINS_LOCATION,
772 FIELD_DECL, NULL_TREE, gcov_ptr_type);
773 DECL_CHAIN (field) = fields;
774 fields = field;
776 /* merge */
777 gcov_merge_fn_type =
778 build_function_type_list (void_type_node,
779 gcov_ptr_type, get_gcov_unsigned_t (),
780 NULL_TREE);
781 field = build_decl (BUILTINS_LOCATION,
782 FIELD_DECL, NULL_TREE,
783 build_pointer_type (gcov_merge_fn_type));
784 DECL_CHAIN (field) = fields;
785 fields = field;
787 finish_builtin_struct (type, "__gcov_ctr_info", fields, NULL_TREE);
789 return type;
792 /* Creates a CONSTRUCTOR for a gcov_ctr_info. COUNTER is
793 the counter being processed and TYPE is the gcov_ctr_info
794 RECORD_TYPE. */
796 static tree
797 build_ctr_info_value (unsigned int counter, tree type)
799 tree fields = TYPE_FIELDS (type);
800 tree fn;
801 VEC(constructor_elt,gc) *v = NULL;
803 /* counters */
804 CONSTRUCTOR_APPEND_ELT (v, fields,
805 build_int_cstu (get_gcov_unsigned_t (),
806 prg_n_ctrs[counter]));
807 fields = DECL_CHAIN (fields);
809 if (prg_n_ctrs[counter])
811 tree array_type;
813 array_type = build_int_cstu (get_gcov_unsigned_t (),
814 prg_n_ctrs[counter] - 1);
815 array_type = build_index_type (array_type);
816 array_type = build_array_type (TREE_TYPE (TREE_TYPE (fields)),
817 array_type);
819 TREE_TYPE (tree_ctr_tables[counter]) = array_type;
820 DECL_SIZE (tree_ctr_tables[counter]) = TYPE_SIZE (array_type);
821 DECL_SIZE_UNIT (tree_ctr_tables[counter]) = TYPE_SIZE_UNIT (array_type);
822 varpool_finalize_decl (tree_ctr_tables[counter]);
824 CONSTRUCTOR_APPEND_ELT (v, fields,
825 build1 (ADDR_EXPR, TREE_TYPE (fields),
826 tree_ctr_tables[counter]));
828 else
829 CONSTRUCTOR_APPEND_ELT (v, fields, null_pointer_node);
830 fields = DECL_CHAIN (fields);
832 fn = build_decl (BUILTINS_LOCATION,
833 FUNCTION_DECL,
834 get_identifier (ctr_merge_functions[counter]),
835 TREE_TYPE (TREE_TYPE (fields)));
836 DECL_EXTERNAL (fn) = 1;
837 TREE_PUBLIC (fn) = 1;
838 DECL_ARTIFICIAL (fn) = 1;
839 TREE_NOTHROW (fn) = 1;
840 DECL_ASSEMBLER_NAME (fn); /* Initialize assembler name so we can stream out. */
841 CONSTRUCTOR_APPEND_ELT (v, fields, build1 (ADDR_EXPR, TREE_TYPE (fields), fn));
843 return build_constructor (type, v);
846 /* Creates the gcov_info RECORD_TYPE and initializer for it. Returns a
847 CONSTRUCTOR. */
849 static tree
850 build_gcov_info (void)
852 unsigned n_ctr_types, ix;
853 tree type, const_type;
854 tree fn_info_type, fn_info_value = NULL_TREE;
855 tree fn_info_ptr_type;
856 tree ctr_info_type, ctr_info_ary_type, ctr_info_value = NULL_TREE;
857 tree field, fields = NULL_TREE;
858 tree filename_string;
859 int da_file_name_len;
860 unsigned n_fns;
861 const struct function_list *fn;
862 tree string_type;
863 VEC(constructor_elt,gc) *v1 = NULL;
864 VEC(constructor_elt,gc) *v2 = NULL;
866 /* Count the number of active counters. */
867 for (n_ctr_types = 0, ix = 0; ix != GCOV_COUNTERS; ix++)
868 if (prg_ctr_mask & (1 << ix))
869 n_ctr_types++;
871 type = lang_hooks.types.make_type (RECORD_TYPE);
872 const_type = build_qualified_type (type, TYPE_QUAL_CONST);
874 /* Version ident */
875 field = build_decl (BUILTINS_LOCATION,
876 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
877 DECL_CHAIN (field) = fields;
878 fields = field;
879 CONSTRUCTOR_APPEND_ELT (v1, field,
880 build_int_cstu (TREE_TYPE (field), GCOV_VERSION));
882 /* next -- NULL */
883 field = build_decl (BUILTINS_LOCATION,
884 FIELD_DECL, NULL_TREE, build_pointer_type (const_type));
885 DECL_CHAIN (field) = fields;
886 fields = field;
887 CONSTRUCTOR_APPEND_ELT (v1, field, null_pointer_node);
889 /* stamp */
890 field = build_decl (BUILTINS_LOCATION,
891 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
892 DECL_CHAIN (field) = fields;
893 fields = field;
894 CONSTRUCTOR_APPEND_ELT (v1, field,
895 build_int_cstu (TREE_TYPE (field), local_tick));
897 /* Filename */
898 string_type = build_pointer_type (build_qualified_type (char_type_node,
899 TYPE_QUAL_CONST));
900 field = build_decl (BUILTINS_LOCATION,
901 FIELD_DECL, NULL_TREE, string_type);
902 DECL_CHAIN (field) = fields;
903 fields = field;
904 da_file_name_len = strlen (da_file_name);
905 filename_string = build_string (da_file_name_len + 1, da_file_name);
906 TREE_TYPE (filename_string) = build_array_type
907 (char_type_node, build_index_type
908 (build_int_cst (NULL_TREE, da_file_name_len)));
909 CONSTRUCTOR_APPEND_ELT (v1, field,
910 build1 (ADDR_EXPR, string_type, filename_string));
912 /* Build the fn_info type and initializer. */
913 fn_info_type = build_fn_info_type (n_ctr_types);
914 fn_info_ptr_type = build_pointer_type (build_qualified_type
915 (fn_info_type, TYPE_QUAL_CONST));
916 for (fn = functions_head, n_fns = 0; fn; fn = fn->next, n_fns++)
917 CONSTRUCTOR_APPEND_ELT (v2, NULL_TREE,
918 build_fn_info_value (fn, fn_info_type));
920 if (n_fns)
922 tree array_type;
924 array_type = build_index_type (build_int_cst (NULL_TREE, n_fns - 1));
925 array_type = build_array_type (fn_info_type, array_type);
927 fn_info_value = build_constructor (array_type, v2);
928 fn_info_value = build1 (ADDR_EXPR, fn_info_ptr_type, fn_info_value);
930 else
931 fn_info_value = null_pointer_node;
933 /* number of functions */
934 field = build_decl (BUILTINS_LOCATION,
935 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
936 DECL_CHAIN (field) = fields;
937 fields = field;
938 CONSTRUCTOR_APPEND_ELT (v1, field,
939 build_int_cstu (get_gcov_unsigned_t (), n_fns));
941 /* fn_info table */
942 field = build_decl (BUILTINS_LOCATION,
943 FIELD_DECL, NULL_TREE, fn_info_ptr_type);
944 DECL_CHAIN (field) = fields;
945 fields = field;
946 CONSTRUCTOR_APPEND_ELT (v1, field, fn_info_value);
948 /* counter_mask */
949 field = build_decl (BUILTINS_LOCATION,
950 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
951 DECL_CHAIN (field) = fields;
952 fields = field;
953 CONSTRUCTOR_APPEND_ELT (v1, field,
954 build_int_cstu (get_gcov_unsigned_t (),
955 prg_ctr_mask));
957 /* counters */
958 ctr_info_type = build_ctr_info_type ();
959 ctr_info_ary_type = build_index_type (build_int_cst (NULL_TREE,
960 n_ctr_types));
961 ctr_info_ary_type = build_array_type (ctr_info_type, ctr_info_ary_type);
962 v2 = NULL;
963 for (ix = 0; ix != GCOV_COUNTERS; ix++)
964 if (prg_ctr_mask & (1 << ix))
965 CONSTRUCTOR_APPEND_ELT (v2, NULL_TREE,
966 build_ctr_info_value (ix, ctr_info_type));
967 ctr_info_value = build_constructor (ctr_info_ary_type, v2);
969 field = build_decl (BUILTINS_LOCATION,
970 FIELD_DECL, NULL_TREE, ctr_info_ary_type);
971 DECL_CHAIN (field) = fields;
972 fields = field;
973 CONSTRUCTOR_APPEND_ELT (v1, field, ctr_info_value);
975 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
977 return build_constructor (type, v1);
980 /* Write out the structure which libgcov uses to locate all the
981 counters. The structures used here must match those defined in
982 gcov-io.h. Write out the constructor to call __gcov_init. */
984 static void
985 create_coverage (void)
987 tree gcov_info, gcov_init, body, t;
988 char name_buf[32];
990 no_coverage = 1; /* Disable any further coverage. */
992 if (!prg_ctr_mask)
993 return;
995 t = build_gcov_info ();
997 gcov_info = build_decl (BUILTINS_LOCATION,
998 VAR_DECL, NULL_TREE, TREE_TYPE (t));
999 TREE_STATIC (gcov_info) = 1;
1000 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
1001 DECL_NAME (gcov_info) = get_identifier (name_buf);
1002 DECL_INITIAL (gcov_info) = t;
1004 /* Build structure. */
1005 varpool_finalize_decl (gcov_info);
1007 /* Build a decl for __gcov_init. */
1008 t = build_pointer_type (TREE_TYPE (gcov_info));
1009 t = build_function_type_list (void_type_node, t, NULL);
1010 t = build_decl (BUILTINS_LOCATION,
1011 FUNCTION_DECL, get_identifier ("__gcov_init"), t);
1012 TREE_PUBLIC (t) = 1;
1013 DECL_EXTERNAL (t) = 1;
1014 DECL_ASSEMBLER_NAME (t); /* Initialize assembler name so we can stream out. */
1015 gcov_init = t;
1017 /* Generate a call to __gcov_init(&gcov_info). */
1018 body = NULL;
1019 t = build_fold_addr_expr (gcov_info);
1020 t = build_call_expr (gcov_init, 1, t);
1021 append_to_statement_list (t, &body);
1023 /* Generate a constructor to run it. */
1024 cgraph_build_static_cdtor ('I', body, DEFAULT_INIT_PRIORITY);
1027 /* Perform file-level initialization. Read in data file, generate name
1028 of graph file. */
1030 void
1031 coverage_init (const char *filename)
1033 int len = strlen (filename);
1034 /* + 1 for extra '/', in case prefix doesn't end with /. */
1035 int prefix_len;
1037 if (profile_data_prefix == 0 && !IS_ABSOLUTE_PATH(&filename[0]))
1038 profile_data_prefix = getpwd ();
1040 prefix_len = (profile_data_prefix) ? strlen (profile_data_prefix) + 1 : 0;
1042 /* Name of da file. */
1043 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
1044 + prefix_len + 1);
1046 if (profile_data_prefix)
1048 strcpy (da_file_name, profile_data_prefix);
1049 da_file_name[prefix_len - 1] = '/';
1050 da_file_name[prefix_len] = 0;
1052 else
1053 da_file_name[0] = 0;
1054 strcat (da_file_name, filename);
1055 strcat (da_file_name, GCOV_DATA_SUFFIX);
1057 /* Name of bbg file. */
1058 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1);
1059 strcpy (bbg_file_name, filename);
1060 strcat (bbg_file_name, GCOV_NOTE_SUFFIX);
1062 if (flag_profile_use)
1063 read_counts_file ();
1066 /* Performs file-level cleanup. Close graph file, generate coverage
1067 variables and constructor. */
1069 void
1070 coverage_finish (void)
1072 create_coverage ();
1073 if (bbg_file_opened)
1075 int error = gcov_close ();
1077 if (error)
1078 unlink (bbg_file_name);
1079 if (!local_tick)
1080 /* Only remove the da file, if we cannot stamp it. If we can
1081 stamp it, libgcov will DTRT. */
1082 unlink (da_file_name);
1086 #include "gt-coverage.h"