2011-11-16 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
[official-gcc.git] / gcc / coverage.c
blob520652b1e71112c328cd913a77907773b6411456
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
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 GTY((chain_next ("%h.next"))) 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 tree fn_decl; /* the function decl */
64 tree ctr_vars[GCOV_COUNTERS]; /* counter variables. */
67 /* Counts information for a function. */
68 typedef struct counts_entry
70 /* We hash by */
71 unsigned ident;
72 unsigned ctr;
74 /* Store */
75 unsigned lineno_checksum;
76 unsigned cfg_checksum;
77 gcov_type *counts;
78 struct gcov_ctr_summary summary;
79 } counts_entry_t;
81 static GTY(()) struct function_list *functions_head = 0;
82 static struct function_list **functions_tail = &functions_head;
83 static unsigned no_coverage = 0;
85 /* Cumulative counter information for whole program. */
86 static unsigned prg_ctr_mask; /* Mask of counter types generated. */
88 /* Counter information for current function. */
89 static unsigned fn_ctr_mask; /* Mask of counters used. */
90 static GTY(()) tree fn_v_ctrs[GCOV_COUNTERS]; /* counter variables. */
91 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated. */
92 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base. */
94 /* Name of the output file for coverage output file. */
95 static char *bbg_file_name;
96 static unsigned bbg_file_opened;
97 static int bbg_function_announced;
99 /* Name of the count data file. */
100 static char *da_file_name;
102 /* Hash table of count data. */
103 static htab_t counts_hash = NULL;
105 /* The names of merge functions for counters. */
106 static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
107 static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
109 /* Forward declarations. */
110 static hashval_t htab_counts_entry_hash (const void *);
111 static int htab_counts_entry_eq (const void *, const void *);
112 static void htab_counts_entry_del (void *);
113 static void read_counts_file (void);
114 static tree build_var (tree, tree, int);
115 static void build_fn_info_type (tree, unsigned, tree);
116 static tree build_fn_info (const struct function_list *, tree, tree);
117 static void build_info_type (tree, unsigned, tree);
118 static tree build_info (tree, tree, tree, unsigned);
119 static void create_coverage (void);
121 /* Return the type node for gcov_type. */
123 tree
124 get_gcov_type (void)
126 return lang_hooks.types.type_for_size (GCOV_TYPE_SIZE, false);
129 /* Return the type node for gcov_unsigned_t. */
131 static tree
132 get_gcov_unsigned_t (void)
134 return lang_hooks.types.type_for_size (32, true);
137 static hashval_t
138 htab_counts_entry_hash (const void *of)
140 const counts_entry_t *const entry = (const counts_entry_t *) of;
142 return entry->ident * GCOV_COUNTERS + entry->ctr;
145 static int
146 htab_counts_entry_eq (const void *of1, const void *of2)
148 const counts_entry_t *const entry1 = (const counts_entry_t *) of1;
149 const counts_entry_t *const entry2 = (const counts_entry_t *) of2;
151 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
154 static void
155 htab_counts_entry_del (void *of)
157 counts_entry_t *const entry = (counts_entry_t *) of;
159 free (entry->counts);
160 free (entry);
163 /* Read in the counts file, if available. */
165 static void
166 read_counts_file (void)
168 gcov_unsigned_t fn_ident = 0;
169 struct gcov_summary summary;
170 unsigned new_summary = 1;
171 gcov_unsigned_t tag;
172 int is_error = 0;
173 unsigned lineno_checksum = 0;
174 unsigned cfg_checksum = 0;
176 if (!gcov_open (da_file_name, 1))
177 return;
179 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
181 warning (0, "%qs is not a gcov data file", da_file_name);
182 gcov_close ();
183 return;
185 else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
187 char v[4], e[4];
189 GCOV_UNSIGNED2STRING (v, tag);
190 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
192 warning (0, "%qs is version %q.*s, expected version %q.*s",
193 da_file_name, 4, v, 4, e);
194 gcov_close ();
195 return;
198 /* Read and discard the stamp. */
199 gcov_read_unsigned ();
201 counts_hash = htab_create (10,
202 htab_counts_entry_hash, htab_counts_entry_eq,
203 htab_counts_entry_del);
204 while ((tag = gcov_read_unsigned ()))
206 gcov_unsigned_t length;
207 gcov_position_t offset;
209 length = gcov_read_unsigned ();
210 offset = gcov_position ();
211 if (tag == GCOV_TAG_FUNCTION)
213 if (length)
215 fn_ident = gcov_read_unsigned ();
216 lineno_checksum = gcov_read_unsigned ();
217 cfg_checksum = gcov_read_unsigned ();
219 else
220 fn_ident = lineno_checksum = cfg_checksum = 0;
221 new_summary = 1;
223 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
225 struct gcov_summary sum;
226 unsigned ix;
228 if (new_summary)
229 memset (&summary, 0, sizeof (summary));
231 gcov_read_summary (&sum);
232 for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++)
234 summary.ctrs[ix].runs += sum.ctrs[ix].runs;
235 summary.ctrs[ix].sum_all += sum.ctrs[ix].sum_all;
236 if (summary.ctrs[ix].run_max < sum.ctrs[ix].run_max)
237 summary.ctrs[ix].run_max = sum.ctrs[ix].run_max;
238 summary.ctrs[ix].sum_max += sum.ctrs[ix].sum_max;
240 new_summary = 0;
242 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
244 counts_entry_t **slot, *entry, elt;
245 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
246 unsigned ix;
248 elt.ident = fn_ident;
249 elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
251 slot = (counts_entry_t **) htab_find_slot
252 (counts_hash, &elt, INSERT);
253 entry = *slot;
254 if (!entry)
256 *slot = entry = XCNEW (counts_entry_t);
257 entry->ident = fn_ident;
258 entry->ctr = elt.ctr;
259 entry->lineno_checksum = lineno_checksum;
260 entry->cfg_checksum = cfg_checksum;
261 entry->summary = summary.ctrs[elt.ctr];
262 entry->summary.num = n_counts;
263 entry->counts = XCNEWVEC (gcov_type, n_counts);
265 else if (entry->lineno_checksum != lineno_checksum
266 || entry->cfg_checksum != cfg_checksum)
268 error ("Profile data for function %u is corrupted", fn_ident);
269 error ("checksum is (%x,%x) instead of (%x,%x)",
270 entry->lineno_checksum, entry->cfg_checksum,
271 lineno_checksum, cfg_checksum);
272 htab_delete (counts_hash);
273 break;
275 else if (entry->summary.num != n_counts)
277 error ("Profile data for function %u is corrupted", fn_ident);
278 error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
279 htab_delete (counts_hash);
280 break;
282 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
284 error ("cannot merge separate %s counters for function %u",
285 ctr_names[elt.ctr], fn_ident);
286 goto skip_merge;
288 else
290 entry->summary.runs += summary.ctrs[elt.ctr].runs;
291 entry->summary.sum_all += summary.ctrs[elt.ctr].sum_all;
292 if (entry->summary.run_max < summary.ctrs[elt.ctr].run_max)
293 entry->summary.run_max = summary.ctrs[elt.ctr].run_max;
294 entry->summary.sum_max += summary.ctrs[elt.ctr].sum_max;
296 for (ix = 0; ix != n_counts; ix++)
297 entry->counts[ix] += gcov_read_counter ();
298 skip_merge:;
300 gcov_sync (offset, length);
301 if ((is_error = gcov_is_error ()))
303 error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted",
304 da_file_name);
305 htab_delete (counts_hash);
306 break;
310 gcov_close ();
313 /* Returns the counters for a particular tag. */
315 gcov_type *
316 get_coverage_counts (unsigned counter, unsigned expected,
317 unsigned cfg_checksum, unsigned lineno_checksum,
318 const struct gcov_ctr_summary **summary)
320 counts_entry_t *entry, elt;
322 /* No hash table, no counts. */
323 if (!counts_hash)
325 static int warned = 0;
327 if (!warned++)
328 inform (input_location, (flag_guess_branch_prob
329 ? "file %s not found, execution counts estimated"
330 : "file %s not found, execution counts assumed to be zero"),
331 da_file_name);
332 return NULL;
335 elt.ident = current_function_funcdef_no + 1;
336 elt.ctr = counter;
337 entry = (counts_entry_t *) htab_find (counts_hash, &elt);
338 if (!entry || !entry->summary.num)
339 /* The function was not emitted, or is weak and not chosen in the
340 final executable. Silently fail, because there's nothing we
341 can do about it. */
342 return NULL;
344 if (entry->cfg_checksum != cfg_checksum
345 || entry->summary.num != expected)
347 static int warned = 0;
348 bool warning_printed = false;
349 tree id = DECL_ASSEMBLER_NAME (current_function_decl);
351 warning_printed =
352 warning_at (input_location, OPT_Wcoverage_mismatch,
353 "the control flow of function %qE does not match "
354 "its profile data (counter %qs)", id, ctr_names[counter]);
355 if (warning_printed)
357 inform (input_location, "use -Wno-error=coverage-mismatch to tolerate "
358 "the mismatch but performance may drop if the function is hot");
360 if (!seen_error ()
361 && !warned++)
363 inform (input_location, "coverage mismatch ignored");
364 inform (input_location, flag_guess_branch_prob
365 ? G_("execution counts estimated")
366 : G_("execution counts assumed to be zero"));
367 if (!flag_guess_branch_prob)
368 inform (input_location,
369 "this can result in poorly optimized code");
373 return NULL;
375 else if (entry->lineno_checksum != lineno_checksum)
377 warning (0, "source location for function %qE have changed,"
378 " the profile data may be out of date",
379 DECL_ASSEMBLER_NAME (current_function_decl));
382 if (summary)
383 *summary = &entry->summary;
385 return entry->counts;
388 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
389 allocation succeeded. */
392 coverage_counter_alloc (unsigned counter, unsigned num)
394 if (no_coverage)
395 return 0;
397 if (!num)
398 return 1;
400 if (!fn_v_ctrs[counter])
402 tree array_type = build_array_type (get_gcov_type (), NULL_TREE);
404 fn_v_ctrs[counter]
405 = build_var (current_function_decl, array_type, counter);
408 fn_b_ctrs[counter] = fn_n_ctrs[counter];
409 fn_n_ctrs[counter] += num;
411 fn_ctr_mask |= 1 << counter;
412 return 1;
415 /* Generate a tree to access COUNTER NO. */
417 tree
418 tree_coverage_counter_ref (unsigned counter, unsigned no)
420 tree gcov_type_node = get_gcov_type ();
422 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
424 no += fn_b_ctrs[counter];
426 /* "no" here is an array index, scaled to bytes later. */
427 return build4 (ARRAY_REF, gcov_type_node, fn_v_ctrs[counter],
428 build_int_cst (integer_type_node, no), NULL, NULL);
431 /* Generate a tree to access the address of COUNTER NO. */
433 tree
434 tree_coverage_counter_addr (unsigned counter, unsigned no)
436 tree gcov_type_node = get_gcov_type ();
438 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
439 no += fn_b_ctrs[counter];
441 /* "no" here is an array index, scaled to bytes later. */
442 return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node,
443 fn_v_ctrs[counter],
444 build_int_cst (integer_type_node, no),
445 NULL, NULL));
449 /* Generate a checksum for a string. CHKSUM is the current
450 checksum. */
452 static unsigned
453 coverage_checksum_string (unsigned chksum, const char *string)
455 int i;
456 char *dup = NULL;
458 /* Look for everything that looks if it were produced by
459 get_file_function_name and zero out the second part
460 that may result from flag_random_seed. This is not critical
461 as the checksums are used only for sanity checking. */
462 for (i = 0; string[i]; i++)
464 int offset = 0;
465 if (!strncmp (string + i, "_GLOBAL__N_", 11))
466 offset = 11;
467 if (!strncmp (string + i, "_GLOBAL__", 9))
468 offset = 9;
470 /* C++ namespaces do have scheme:
471 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
472 since filename might contain extra underscores there seems
473 to be no better chance then walk all possible offsets looking
474 for magicnumber. */
475 if (offset)
477 for (i = i + offset; string[i]; i++)
478 if (string[i]=='_')
480 int y;
482 for (y = 1; y < 9; y++)
483 if (!(string[i + y] >= '0' && string[i + y] <= '9')
484 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
485 break;
486 if (y != 9 || string[i + 9] != '_')
487 continue;
488 for (y = 10; y < 18; y++)
489 if (!(string[i + y] >= '0' && string[i + y] <= '9')
490 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
491 break;
492 if (y != 18)
493 continue;
494 if (!dup)
495 string = dup = xstrdup (string);
496 for (y = 10; y < 18; y++)
497 dup[i + y] = '0';
499 break;
503 chksum = crc32_string (chksum, string);
504 free (dup);
506 return chksum;
509 /* Compute checksum for the current function. We generate a CRC32. */
511 unsigned
512 coverage_compute_lineno_checksum (void)
514 expanded_location xloc
515 = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
516 unsigned chksum = xloc.line;
518 chksum = coverage_checksum_string (chksum, xloc.file);
519 chksum = coverage_checksum_string
520 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
522 return chksum;
525 /* Compute cfg checksum for the current function.
526 The checksum is calculated carefully so that
527 source code changes that doesn't affect the control flow graph
528 won't change the checksum.
529 This is to make the profile data useable across source code change.
530 The downside of this is that the compiler may use potentially
531 wrong profile data - that the source code change has non-trivial impact
532 on the validity of profile data (e.g. the reversed condition)
533 but the compiler won't detect the change and use the wrong profile data. */
535 unsigned
536 coverage_compute_cfg_checksum (void)
538 basic_block bb;
539 unsigned chksum = n_basic_blocks;
541 FOR_EACH_BB (bb)
543 edge e;
544 edge_iterator ei;
545 chksum = crc32_byte (chksum, bb->index);
546 FOR_EACH_EDGE (e, ei, bb->succs)
548 chksum = crc32_byte (chksum, e->dest->index);
552 return chksum;
555 /* Begin output to the graph file for the current function.
556 Opens the output file, if not already done. Writes the
557 function header, if not already done. Returns nonzero if data
558 should be output. */
561 coverage_begin_output (unsigned lineno_checksum, unsigned cfg_checksum)
563 /* We don't need to output .gcno file unless we're under -ftest-coverage
564 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
565 if (no_coverage || !flag_test_coverage || flag_compare_debug)
566 return 0;
568 if (!bbg_function_announced)
570 expanded_location xloc
571 = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
572 unsigned long offset;
574 if (!bbg_file_opened)
576 if (!gcov_open (bbg_file_name, -1))
577 error ("cannot open %s", bbg_file_name);
578 else
580 gcov_write_unsigned (GCOV_NOTE_MAGIC);
581 gcov_write_unsigned (GCOV_VERSION);
582 gcov_write_unsigned (local_tick);
584 bbg_file_opened = 1;
588 /* Announce function */
589 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
590 gcov_write_unsigned (current_function_funcdef_no + 1);
591 gcov_write_unsigned (lineno_checksum);
592 gcov_write_unsigned (cfg_checksum);
593 gcov_write_string (IDENTIFIER_POINTER
594 (DECL_ASSEMBLER_NAME (current_function_decl)));
595 gcov_write_string (xloc.file);
596 gcov_write_unsigned (xloc.line);
597 gcov_write_length (offset);
599 bbg_function_announced = 1;
601 return !gcov_is_error ();
604 /* Finish coverage data for the current function. Verify no output
605 error has occurred. Save function coverage counts. */
607 void
608 coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum)
610 unsigned i;
612 if (bbg_file_opened > 1 && gcov_is_error ())
614 warning (0, "error writing %qs", bbg_file_name);
615 bbg_file_opened = -1;
618 if (fn_ctr_mask)
620 struct function_list *item;
622 item = ggc_alloc_function_list ();
624 item->next = 0;
625 item->ident = current_function_funcdef_no + 1;
626 item->lineno_checksum = lineno_checksum;
627 item->cfg_checksum = cfg_checksum;
628 item->fn_decl = current_function_decl;
629 for (i = 0; i != GCOV_COUNTERS; i++)
631 tree var = fn_v_ctrs[i];
633 item->ctr_vars[i] = var;
634 if (var)
636 tree array_type = build_index_type (size_int (fn_n_ctrs[i] - 1));
637 array_type = build_array_type (get_gcov_type (), array_type);
638 TREE_TYPE (var) = array_type;
639 DECL_SIZE (var) = TYPE_SIZE (array_type);
640 DECL_SIZE_UNIT (var) = TYPE_SIZE_UNIT (array_type);
641 varpool_finalize_decl (var);
643 fn_b_ctrs[i] = fn_n_ctrs[i] = 0;
644 fn_v_ctrs[i] = NULL_TREE;
646 prg_ctr_mask |= fn_ctr_mask;
647 fn_ctr_mask = 0;
648 /* If the function is extern (i.e. extern inline), then we won't
649 be outputting it, so don't chain it onto the function list. */
650 if (!DECL_EXTERNAL (item->fn_decl))
652 *functions_tail = item;
653 functions_tail = &item->next;
656 bbg_function_announced = 0;
659 /* Build a coverage variable of TYPE for function FN_DECL. If COUNTER
660 >= 0 it is a counter array, and thus local. Otherwise it is the
661 function structure and needs to be globalized. All cases must be
662 in the same comdat group as FN_DECL. */
664 static tree
665 build_var (tree fn_decl, tree type, int counter)
667 tree var = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, type);
668 tree fn_name = DECL_ASSEMBLER_NAME (fn_decl);
669 char *buf = (char *)alloca (IDENTIFIER_LENGTH (fn_name) + 10);
671 if (counter >= 0)
672 TREE_STATIC (var) = 1;
673 else
675 TREE_PUBLIC (var) = TREE_PUBLIC (fn_decl);
676 TREE_STATIC (var) = TREE_STATIC (fn_decl);
678 TREE_ADDRESSABLE (var) = 1;
679 DECL_ALIGN (var) = TYPE_ALIGN (type);
681 if (counter < 0)
682 sprintf (buf, "__gcov__%s", IDENTIFIER_POINTER (fn_name));
683 else
684 sprintf (buf, "__gcov%u_%s", counter, IDENTIFIER_POINTER (fn_name));
685 DECL_NAME (var) = get_identifier (buf);
687 /* Initialize assembler name so we can stream out. */
688 if (TREE_PUBLIC (var))
689 DECL_ASSEMBLER_NAME (var);
691 DECL_WEAK (var) = TREE_PUBLIC (var) && DECL_WEAK (fn_decl);
692 DECL_COMDAT (var) = DECL_COMDAT (fn_decl);
693 DECL_COMDAT_GROUP (var) = DECL_COMDAT_GROUP (fn_decl);
695 return var;
698 /* Creates the gcov_fn_info RECORD_TYPE. */
700 static void
701 build_fn_info_type (tree type, unsigned counters, tree gcov_info_type)
703 tree ctr_info = lang_hooks.types.make_type (RECORD_TYPE);
704 tree field, fields;
705 tree array_type;
707 gcc_assert (counters);
709 /* ctr_info::num */
710 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
711 get_gcov_unsigned_t ());
712 fields = field;
714 /* ctr_info::values */
715 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
716 build_pointer_type (get_gcov_type ()));
717 DECL_CHAIN (field) = fields;
718 fields = field;
720 finish_builtin_struct (ctr_info, "__gcov_ctr_info", fields, NULL_TREE);
722 /* key */
723 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
724 build_pointer_type (build_qualified_type
725 (gcov_info_type, TYPE_QUAL_CONST)));
726 fields = field;
728 /* ident */
729 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
730 get_gcov_unsigned_t ());
731 DECL_CHAIN (field) = fields;
732 fields = field;
734 /* lineno_checksum */
735 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
736 get_gcov_unsigned_t ());
737 DECL_CHAIN (field) = fields;
738 fields = field;
740 /* cfg checksum */
741 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
742 get_gcov_unsigned_t ());
743 DECL_CHAIN (field) = fields;
744 fields = field;
746 array_type = build_index_type (size_int (counters - 1));
747 array_type = build_array_type (ctr_info, array_type);
749 /* counters */
750 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, array_type);
751 DECL_CHAIN (field) = fields;
752 fields = field;
754 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
757 /* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is
758 the function being processed and TYPE is the gcov_fn_info
759 RECORD_TYPE. KEY is the object file key. */
761 static tree
762 build_fn_info (const struct function_list *function, tree type, tree key)
764 tree fields = TYPE_FIELDS (type);
765 tree ctr_type;
766 unsigned ix;
767 VEC(constructor_elt,gc) *v1 = NULL;
768 VEC(constructor_elt,gc) *v2 = NULL;
770 /* key */
771 CONSTRUCTOR_APPEND_ELT (v1, fields,
772 build1 (ADDR_EXPR, TREE_TYPE (fields), key));
773 fields = DECL_CHAIN (fields);
775 /* ident */
776 CONSTRUCTOR_APPEND_ELT (v1, fields,
777 build_int_cstu (get_gcov_unsigned_t (),
778 function->ident));
779 fields = DECL_CHAIN (fields);
781 /* lineno_checksum */
782 CONSTRUCTOR_APPEND_ELT (v1, fields,
783 build_int_cstu (get_gcov_unsigned_t (),
784 function->lineno_checksum));
785 fields = DECL_CHAIN (fields);
787 /* cfg_checksum */
788 CONSTRUCTOR_APPEND_ELT (v1, fields,
789 build_int_cstu (get_gcov_unsigned_t (),
790 function->cfg_checksum));
791 fields = DECL_CHAIN (fields);
793 /* counters */
794 ctr_type = TREE_TYPE (TREE_TYPE (fields));
795 for (ix = 0; ix != GCOV_COUNTERS; ix++)
796 if (prg_ctr_mask & (1 << ix))
798 VEC(constructor_elt,gc) *ctr = NULL;
799 tree var = function->ctr_vars[ix];
800 unsigned count = 0;
802 if (var)
803 count
804 = tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var))), 0)
805 + 1;
807 CONSTRUCTOR_APPEND_ELT (ctr, TYPE_FIELDS (ctr_type),
808 build_int_cstu (get_gcov_unsigned_t (),
809 count));
811 if (var)
812 CONSTRUCTOR_APPEND_ELT (ctr, DECL_CHAIN (TYPE_FIELDS (ctr_type)),
813 build_fold_addr_expr (var));
815 CONSTRUCTOR_APPEND_ELT (v2, NULL, build_constructor (ctr_type, ctr));
818 CONSTRUCTOR_APPEND_ELT (v1, fields,
819 build_constructor (TREE_TYPE (fields), v2));
821 return build_constructor (type, v1);
824 /* Creaste gcov_info_struct. N_FUNCS is the number of functions in
825 the trailing array. */
827 static void
828 build_info_type (tree type, unsigned n_funcs, tree fn_info_type)
830 tree field, fields = NULL_TREE;
831 tree merge_fn_type, fn_info_array;
833 gcc_assert (n_funcs);
835 /* Version ident */
836 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
837 get_gcov_unsigned_t ());
838 DECL_CHAIN (field) = fields;
839 fields = field;
841 /* next pointer */
842 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
843 build_pointer_type (build_qualified_type
844 (type, TYPE_QUAL_CONST)));
845 DECL_CHAIN (field) = fields;
846 fields = field;
848 /* stamp */
849 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
850 get_gcov_unsigned_t ());
851 DECL_CHAIN (field) = fields;
852 fields = field;
854 /* Filename */
855 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
856 build_pointer_type (build_qualified_type
857 (char_type_node, TYPE_QUAL_CONST)));
858 DECL_CHAIN (field) = fields;
859 fields = field;
861 /* merge fn array */
862 merge_fn_type
863 = build_function_type_list (void_type_node,
864 build_pointer_type (get_gcov_type ()),
865 get_gcov_unsigned_t (), NULL_TREE);
866 merge_fn_type
867 = build_array_type (build_pointer_type (merge_fn_type),
868 build_index_type (size_int (GCOV_COUNTERS - 1)));
869 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
870 merge_fn_type);
871 DECL_CHAIN (field) = fields;
872 fields = field;
874 /* n_functions */
875 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
876 get_gcov_unsigned_t ());
877 DECL_CHAIN (field) = fields;
878 fields = field;
880 /* function_info pointer array */
881 fn_info_type = build_pointer_type
882 (build_qualified_type (fn_info_type, TYPE_QUAL_CONST));
883 fn_info_array = build_index_type (size_int (n_funcs));
884 fn_info_array = build_array_type (fn_info_type, fn_info_array);
885 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
886 fn_info_array);
887 DECL_CHAIN (field) = fields;
888 fields = field;
890 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
893 /* Creates the gcov_info initializer. Returns a CONSTRUCTOR. */
895 static tree
896 build_info (tree info_type, tree fn_type, tree key_var, unsigned n_funcs)
898 tree info_fields = TYPE_FIELDS (info_type);
899 tree merge_fn_type, fn_info_ptr_type;
900 unsigned ix;
901 tree filename_string;
902 int da_file_name_len;
903 const struct function_list *fn;
904 VEC(constructor_elt,gc) *v1 = NULL;
905 VEC(constructor_elt,gc) *v2 = NULL;
906 VEC(constructor_elt,gc) *v3 = NULL;
908 /* Version ident */
909 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
910 build_int_cstu (TREE_TYPE (info_fields),
911 GCOV_VERSION));
912 info_fields = DECL_CHAIN (info_fields);
914 /* next -- NULL */
915 CONSTRUCTOR_APPEND_ELT (v1, info_fields, null_pointer_node);
916 info_fields = DECL_CHAIN (info_fields);
918 /* stamp */
919 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
920 build_int_cstu (TREE_TYPE (info_fields),
921 local_tick));
922 info_fields = DECL_CHAIN (info_fields);
924 /* Filename */
925 da_file_name_len = strlen (da_file_name);
926 filename_string = build_string (da_file_name_len + 1, da_file_name);
927 TREE_TYPE (filename_string) = build_array_type
928 (char_type_node, build_index_type (size_int (da_file_name_len)));
929 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
930 build1 (ADDR_EXPR, TREE_TYPE (info_fields),
931 filename_string));
932 info_fields = DECL_CHAIN (info_fields);
934 /* merge fn array -- NULL slots indicate unmeasured counters */
935 merge_fn_type = TREE_TYPE (TREE_TYPE (info_fields));
936 for (ix = 0; ix != GCOV_COUNTERS; ix++)
938 tree ptr = null_pointer_node;
940 if ((1u << ix) & prg_ctr_mask)
942 tree merge_fn = build_decl (BUILTINS_LOCATION,
943 FUNCTION_DECL,
944 get_identifier (ctr_merge_functions[ix]),
945 TREE_TYPE (merge_fn_type));
946 DECL_EXTERNAL (merge_fn) = 1;
947 TREE_PUBLIC (merge_fn) = 1;
948 DECL_ARTIFICIAL (merge_fn) = 1;
949 TREE_NOTHROW (merge_fn) = 1;
950 /* Initialize assembler name so we can stream out. */
951 DECL_ASSEMBLER_NAME (merge_fn);
952 ptr = build1 (ADDR_EXPR, merge_fn_type, merge_fn);
954 CONSTRUCTOR_APPEND_ELT (v2, NULL, ptr);
956 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
957 build_constructor (TREE_TYPE (info_fields), v2));
958 info_fields = DECL_CHAIN (info_fields);
960 /* n_functions */
961 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
962 build_int_cstu (TREE_TYPE (info_fields), n_funcs));
963 info_fields = DECL_CHAIN (info_fields);
965 /* Build the fn_info type and initializer. */
966 fn_info_ptr_type = TREE_TYPE (TREE_TYPE (info_fields));
968 for (fn = functions_head; fn; fn = fn->next)
970 tree init = build_fn_info (fn, fn_type, key_var);
971 tree var = build_var (fn->fn_decl, fn_type, -1);
973 DECL_INITIAL (var) = init;
974 varpool_finalize_decl (var);
976 CONSTRUCTOR_APPEND_ELT (v3, NULL,
977 build1 (ADDR_EXPR, fn_info_ptr_type, var));
979 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
980 build_constructor (TREE_TYPE (info_fields), v3));
981 return build_constructor (info_type, v1);
984 /* Write out the structure which libgcov uses to locate all the
985 counters. The structures used here must match those defined in
986 gcov-io.h. Write out the constructor to call __gcov_init. */
988 static void
989 create_coverage (void)
991 tree gcov_info, gcov_init, body, t;
992 tree gcov_info_type, gcov_fn_type;
993 unsigned n_counters = 0, n_functions = 0;
994 struct function_list *fn;
995 struct function_list **fn_prev;
996 unsigned ix;
997 char name_buf[32];
999 no_coverage = 1; /* Disable any further coverage. */
1001 if (!prg_ctr_mask)
1002 return;
1004 if (cgraph_dump_file)
1005 fprintf (cgraph_dump_file, "Using data file %s\n", da_file_name);
1007 for (ix = 0; ix != GCOV_COUNTERS; ix++)
1008 if ((1u << ix) & prg_ctr_mask)
1009 n_counters++;
1010 for (fn_prev = &functions_head; (fn = *fn_prev);)
1011 if (DECL_STRUCT_FUNCTION (fn->fn_decl))
1013 n_functions++;
1014 fn_prev = &fn->next;
1016 else
1017 /* The function is not being emitted, remove from list. */
1018 *fn_prev = fn->next;
1020 /* Build the info and fn_info types. These are mutually recursive. */
1021 gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1022 gcov_fn_type = lang_hooks.types.make_type (RECORD_TYPE);
1023 build_fn_info_type (gcov_fn_type, n_counters, gcov_info_type);
1024 build_info_type (gcov_info_type, n_functions, gcov_fn_type);
1026 /* Build the gcov info var, this is referred to in its own
1027 initializer. */
1028 gcov_info = build_decl (BUILTINS_LOCATION,
1029 VAR_DECL, NULL_TREE, gcov_info_type);
1030 TREE_STATIC (gcov_info) = 1;
1031 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
1032 DECL_NAME (gcov_info) = get_identifier (name_buf);
1033 DECL_INITIAL (gcov_info) = build_info (gcov_info_type, gcov_fn_type,
1034 gcov_info, n_functions);
1036 /* Build structure. */
1037 varpool_finalize_decl (gcov_info);
1039 /* Build a decl for __gcov_init. */
1040 t = build_pointer_type (TREE_TYPE (gcov_info));
1041 t = build_function_type_list (void_type_node, t, NULL);
1042 t = build_decl (BUILTINS_LOCATION,
1043 FUNCTION_DECL, get_identifier ("__gcov_init"), t);
1044 TREE_PUBLIC (t) = 1;
1045 DECL_EXTERNAL (t) = 1;
1046 DECL_ASSEMBLER_NAME (t); /* Initialize assembler name so we can stream out. */
1047 gcov_init = t;
1049 /* Generate a call to __gcov_init(&gcov_info). */
1050 body = NULL;
1051 t = build_fold_addr_expr (gcov_info);
1052 t = build_call_expr (gcov_init, 1, t);
1053 append_to_statement_list (t, &body);
1055 /* Generate a constructor to run it. */
1056 cgraph_build_static_cdtor ('I', body, DEFAULT_INIT_PRIORITY);
1059 /* Perform file-level initialization. Read in data file, generate name
1060 of graph file. */
1062 void
1063 coverage_init (const char *filename)
1065 int len = strlen (filename);
1066 /* + 1 for extra '/', in case prefix doesn't end with /. */
1067 int prefix_len;
1069 if (profile_data_prefix == 0 && !IS_ABSOLUTE_PATH(&filename[0]))
1070 profile_data_prefix = getpwd ();
1072 prefix_len = (profile_data_prefix) ? strlen (profile_data_prefix) + 1 : 0;
1074 /* Name of da file. */
1075 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
1076 + prefix_len + 1);
1078 if (profile_data_prefix)
1080 strcpy (da_file_name, profile_data_prefix);
1081 da_file_name[prefix_len - 1] = '/';
1082 da_file_name[prefix_len] = 0;
1084 else
1085 da_file_name[0] = 0;
1086 strcat (da_file_name, filename);
1087 strcat (da_file_name, GCOV_DATA_SUFFIX);
1089 /* Name of bbg file. */
1090 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1);
1091 strcpy (bbg_file_name, filename);
1092 strcat (bbg_file_name, GCOV_NOTE_SUFFIX);
1094 if (flag_branch_probabilities)
1095 read_counts_file ();
1098 /* Performs file-level cleanup. Close graph file, generate coverage
1099 variables and constructor. */
1101 void
1102 coverage_finish (void)
1104 create_coverage ();
1105 if (bbg_file_opened)
1107 int error = gcov_close ();
1109 if (error)
1110 unlink (bbg_file_name);
1111 if (!local_tick)
1112 /* Only remove the da file, if we cannot stamp it. If we can
1113 stamp it, libgcov will DTRT. */
1114 unlink (da_file_name);
1118 #include "gt-coverage.h"