* dwarf2out.c (compare_loc_descriptor, scompare_loc_descriptor,
[official-gcc.git] / gcc / coverage.c
blob1a992973f7838aaae31d9585c80199af1d0309b7
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 (integer_type_node, 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 (integer_type_node, 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 = XCNEW (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_index_type (size_int (counters - 1));
697 array_type = build_array_type (get_gcov_unsigned_t (), array_type);
699 /* counters */
700 field = build_decl (BUILTINS_LOCATION,
701 FIELD_DECL, NULL_TREE, array_type);
702 DECL_CHAIN (field) = fields;
703 fields = field;
705 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
707 return type;
710 /* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is
711 the function being processed and TYPE is the gcov_fn_info
712 RECORD_TYPE. */
714 static tree
715 build_fn_info_value (const struct function_list *function, tree type)
717 tree fields = TYPE_FIELDS (type);
718 unsigned ix;
719 VEC(constructor_elt,gc) *v1 = NULL;
720 VEC(constructor_elt,gc) *v2 = NULL;
722 /* ident */
723 CONSTRUCTOR_APPEND_ELT (v1, fields,
724 build_int_cstu (get_gcov_unsigned_t (),
725 function->ident));
726 fields = DECL_CHAIN (fields);
728 /* lineno_checksum */
729 CONSTRUCTOR_APPEND_ELT (v1, fields,
730 build_int_cstu (get_gcov_unsigned_t (),
731 function->lineno_checksum));
732 fields = DECL_CHAIN (fields);
734 /* cfg_checksum */
735 CONSTRUCTOR_APPEND_ELT (v1, fields,
736 build_int_cstu (get_gcov_unsigned_t (),
737 function->cfg_checksum));
738 fields = DECL_CHAIN (fields);
740 /* counters */
741 for (ix = 0; ix != GCOV_COUNTERS; ix++)
742 if (prg_ctr_mask & (1 << ix))
743 CONSTRUCTOR_APPEND_ELT (v2, NULL,
744 build_int_cstu (get_gcov_unsigned_t (),
745 function->n_ctrs[ix]));
747 CONSTRUCTOR_APPEND_ELT (v1, fields,
748 build_constructor (TREE_TYPE (fields), v2));
750 return build_constructor (type, v1);
753 /* Creates the gcov_ctr_info RECORD_TYPE. */
755 static tree
756 build_ctr_info_type (void)
758 tree type = lang_hooks.types.make_type (RECORD_TYPE);
759 tree field, fields = NULL_TREE;
760 tree gcov_ptr_type = build_pointer_type (get_gcov_type ());
761 tree gcov_merge_fn_type;
763 /* counters */
764 field = build_decl (BUILTINS_LOCATION,
765 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
766 DECL_CHAIN (field) = fields;
767 fields = field;
769 /* values */
770 field = build_decl (BUILTINS_LOCATION,
771 FIELD_DECL, NULL_TREE, gcov_ptr_type);
772 DECL_CHAIN (field) = fields;
773 fields = field;
775 /* merge */
776 gcov_merge_fn_type =
777 build_function_type_list (void_type_node,
778 gcov_ptr_type, get_gcov_unsigned_t (),
779 NULL_TREE);
780 field = build_decl (BUILTINS_LOCATION,
781 FIELD_DECL, NULL_TREE,
782 build_pointer_type (gcov_merge_fn_type));
783 DECL_CHAIN (field) = fields;
784 fields = field;
786 finish_builtin_struct (type, "__gcov_ctr_info", fields, NULL_TREE);
788 return type;
791 /* Creates a CONSTRUCTOR for a gcov_ctr_info. COUNTER is
792 the counter being processed and TYPE is the gcov_ctr_info
793 RECORD_TYPE. */
795 static tree
796 build_ctr_info_value (unsigned int counter, tree type)
798 tree fields = TYPE_FIELDS (type);
799 tree fn;
800 VEC(constructor_elt,gc) *v = NULL;
802 /* counters */
803 CONSTRUCTOR_APPEND_ELT (v, fields,
804 build_int_cstu (get_gcov_unsigned_t (),
805 prg_n_ctrs[counter]));
806 fields = DECL_CHAIN (fields);
808 if (prg_n_ctrs[counter])
810 tree array_type;
812 array_type = build_int_cstu (get_gcov_unsigned_t (),
813 prg_n_ctrs[counter] - 1);
814 array_type = build_index_type (array_type);
815 array_type = build_array_type (TREE_TYPE (TREE_TYPE (fields)),
816 array_type);
818 TREE_TYPE (tree_ctr_tables[counter]) = array_type;
819 DECL_SIZE (tree_ctr_tables[counter]) = TYPE_SIZE (array_type);
820 DECL_SIZE_UNIT (tree_ctr_tables[counter]) = TYPE_SIZE_UNIT (array_type);
821 varpool_finalize_decl (tree_ctr_tables[counter]);
823 CONSTRUCTOR_APPEND_ELT (v, fields,
824 build1 (ADDR_EXPR, TREE_TYPE (fields),
825 tree_ctr_tables[counter]));
827 else
828 CONSTRUCTOR_APPEND_ELT (v, fields, null_pointer_node);
829 fields = DECL_CHAIN (fields);
831 fn = build_decl (BUILTINS_LOCATION,
832 FUNCTION_DECL,
833 get_identifier (ctr_merge_functions[counter]),
834 TREE_TYPE (TREE_TYPE (fields)));
835 DECL_EXTERNAL (fn) = 1;
836 TREE_PUBLIC (fn) = 1;
837 DECL_ARTIFICIAL (fn) = 1;
838 TREE_NOTHROW (fn) = 1;
839 DECL_ASSEMBLER_NAME (fn); /* Initialize assembler name so we can stream out. */
840 CONSTRUCTOR_APPEND_ELT (v, fields, build1 (ADDR_EXPR, TREE_TYPE (fields), fn));
842 return build_constructor (type, v);
845 /* Creates the gcov_info RECORD_TYPE and initializer for it. Returns a
846 CONSTRUCTOR. */
848 static tree
849 build_gcov_info (void)
851 unsigned n_ctr_types, ix;
852 tree type, const_type;
853 tree fn_info_type, fn_info_value = NULL_TREE;
854 tree fn_info_ptr_type;
855 tree ctr_info_type, ctr_info_ary_type, ctr_info_value = NULL_TREE;
856 tree field, fields = NULL_TREE;
857 tree filename_string;
858 int da_file_name_len;
859 unsigned n_fns;
860 const struct function_list *fn;
861 tree string_type;
862 VEC(constructor_elt,gc) *v1 = NULL;
863 VEC(constructor_elt,gc) *v2 = NULL;
865 /* Count the number of active counters. */
866 for (n_ctr_types = 0, ix = 0; ix != GCOV_COUNTERS; ix++)
867 if (prg_ctr_mask & (1 << ix))
868 n_ctr_types++;
870 type = lang_hooks.types.make_type (RECORD_TYPE);
871 const_type = build_qualified_type (type, TYPE_QUAL_CONST);
873 /* Version ident */
874 field = build_decl (BUILTINS_LOCATION,
875 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
876 DECL_CHAIN (field) = fields;
877 fields = field;
878 CONSTRUCTOR_APPEND_ELT (v1, field,
879 build_int_cstu (TREE_TYPE (field), GCOV_VERSION));
881 /* next -- NULL */
882 field = build_decl (BUILTINS_LOCATION,
883 FIELD_DECL, NULL_TREE, build_pointer_type (const_type));
884 DECL_CHAIN (field) = fields;
885 fields = field;
886 CONSTRUCTOR_APPEND_ELT (v1, field, null_pointer_node);
888 /* stamp */
889 field = build_decl (BUILTINS_LOCATION,
890 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
891 DECL_CHAIN (field) = fields;
892 fields = field;
893 CONSTRUCTOR_APPEND_ELT (v1, field,
894 build_int_cstu (TREE_TYPE (field), local_tick));
896 /* Filename */
897 string_type = build_pointer_type (build_qualified_type (char_type_node,
898 TYPE_QUAL_CONST));
899 field = build_decl (BUILTINS_LOCATION,
900 FIELD_DECL, NULL_TREE, string_type);
901 DECL_CHAIN (field) = fields;
902 fields = field;
903 da_file_name_len = strlen (da_file_name);
904 filename_string = build_string (da_file_name_len + 1, da_file_name);
905 TREE_TYPE (filename_string) = build_array_type
906 (char_type_node, build_index_type (size_int (da_file_name_len)));
907 CONSTRUCTOR_APPEND_ELT (v1, field,
908 build1 (ADDR_EXPR, string_type, filename_string));
910 /* Build the fn_info type and initializer. */
911 fn_info_type = build_fn_info_type (n_ctr_types);
912 fn_info_ptr_type = build_pointer_type (build_qualified_type
913 (fn_info_type, TYPE_QUAL_CONST));
914 for (fn = functions_head, n_fns = 0; fn; fn = fn->next, n_fns++)
915 CONSTRUCTOR_APPEND_ELT (v2, NULL_TREE,
916 build_fn_info_value (fn, fn_info_type));
918 if (n_fns)
920 tree array_type;
922 array_type = build_index_type (size_int (n_fns - 1));
923 array_type = build_array_type (fn_info_type, array_type);
925 fn_info_value = build_constructor (array_type, v2);
926 fn_info_value = build1 (ADDR_EXPR, fn_info_ptr_type, fn_info_value);
928 else
929 fn_info_value = null_pointer_node;
931 /* number of functions */
932 field = build_decl (BUILTINS_LOCATION,
933 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
934 DECL_CHAIN (field) = fields;
935 fields = field;
936 CONSTRUCTOR_APPEND_ELT (v1, field,
937 build_int_cstu (get_gcov_unsigned_t (), n_fns));
939 /* fn_info table */
940 field = build_decl (BUILTINS_LOCATION,
941 FIELD_DECL, NULL_TREE, fn_info_ptr_type);
942 DECL_CHAIN (field) = fields;
943 fields = field;
944 CONSTRUCTOR_APPEND_ELT (v1, field, fn_info_value);
946 /* counter_mask */
947 field = build_decl (BUILTINS_LOCATION,
948 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
949 DECL_CHAIN (field) = fields;
950 fields = field;
951 CONSTRUCTOR_APPEND_ELT (v1, field,
952 build_int_cstu (get_gcov_unsigned_t (),
953 prg_ctr_mask));
955 /* counters */
956 ctr_info_type = build_ctr_info_type ();
957 ctr_info_ary_type = build_index_type (size_int (n_ctr_types));
958 ctr_info_ary_type = build_array_type (ctr_info_type, ctr_info_ary_type);
959 v2 = NULL;
960 for (ix = 0; ix != GCOV_COUNTERS; ix++)
961 if (prg_ctr_mask & (1 << ix))
962 CONSTRUCTOR_APPEND_ELT (v2, NULL_TREE,
963 build_ctr_info_value (ix, ctr_info_type));
964 ctr_info_value = build_constructor (ctr_info_ary_type, v2);
966 field = build_decl (BUILTINS_LOCATION,
967 FIELD_DECL, NULL_TREE, ctr_info_ary_type);
968 DECL_CHAIN (field) = fields;
969 fields = field;
970 CONSTRUCTOR_APPEND_ELT (v1, field, ctr_info_value);
972 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
974 return build_constructor (type, v1);
977 /* Write out the structure which libgcov uses to locate all the
978 counters. The structures used here must match those defined in
979 gcov-io.h. Write out the constructor to call __gcov_init. */
981 static void
982 create_coverage (void)
984 tree gcov_info, gcov_init, body, t;
985 char name_buf[32];
987 no_coverage = 1; /* Disable any further coverage. */
989 if (!prg_ctr_mask)
990 return;
992 t = build_gcov_info ();
994 gcov_info = build_decl (BUILTINS_LOCATION,
995 VAR_DECL, NULL_TREE, TREE_TYPE (t));
996 TREE_STATIC (gcov_info) = 1;
997 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
998 DECL_NAME (gcov_info) = get_identifier (name_buf);
999 DECL_INITIAL (gcov_info) = t;
1001 /* Build structure. */
1002 varpool_finalize_decl (gcov_info);
1004 /* Build a decl for __gcov_init. */
1005 t = build_pointer_type (TREE_TYPE (gcov_info));
1006 t = build_function_type_list (void_type_node, t, NULL);
1007 t = build_decl (BUILTINS_LOCATION,
1008 FUNCTION_DECL, get_identifier ("__gcov_init"), t);
1009 TREE_PUBLIC (t) = 1;
1010 DECL_EXTERNAL (t) = 1;
1011 DECL_ASSEMBLER_NAME (t); /* Initialize assembler name so we can stream out. */
1012 gcov_init = t;
1014 /* Generate a call to __gcov_init(&gcov_info). */
1015 body = NULL;
1016 t = build_fold_addr_expr (gcov_info);
1017 t = build_call_expr (gcov_init, 1, t);
1018 append_to_statement_list (t, &body);
1020 /* Generate a constructor to run it. */
1021 cgraph_build_static_cdtor ('I', body, DEFAULT_INIT_PRIORITY);
1024 /* Perform file-level initialization. Read in data file, generate name
1025 of graph file. */
1027 void
1028 coverage_init (const char *filename)
1030 int len = strlen (filename);
1031 /* + 1 for extra '/', in case prefix doesn't end with /. */
1032 int prefix_len;
1034 if (profile_data_prefix == 0 && !IS_ABSOLUTE_PATH(&filename[0]))
1035 profile_data_prefix = getpwd ();
1037 prefix_len = (profile_data_prefix) ? strlen (profile_data_prefix) + 1 : 0;
1039 /* Name of da file. */
1040 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
1041 + prefix_len + 1);
1043 if (profile_data_prefix)
1045 strcpy (da_file_name, profile_data_prefix);
1046 da_file_name[prefix_len - 1] = '/';
1047 da_file_name[prefix_len] = 0;
1049 else
1050 da_file_name[0] = 0;
1051 strcat (da_file_name, filename);
1052 strcat (da_file_name, GCOV_DATA_SUFFIX);
1054 /* Name of bbg file. */
1055 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1);
1056 strcpy (bbg_file_name, filename);
1057 strcat (bbg_file_name, GCOV_NOTE_SUFFIX);
1059 if (flag_profile_use)
1060 read_counts_file ();
1063 /* Performs file-level cleanup. Close graph file, generate coverage
1064 variables and constructor. */
1066 void
1067 coverage_finish (void)
1069 create_coverage ();
1070 if (bbg_file_opened)
1072 int error = gcov_close ();
1074 if (error)
1075 unlink (bbg_file_name);
1076 if (!local_tick)
1077 /* Only remove the da file, if we cannot stamp it. If we can
1078 stamp it, libgcov will DTRT. */
1079 unlink (da_file_name);
1083 #include "gt-coverage.h"