sort - Don't live-loop threads
[dragonfly.git] / contrib / gcc-4.7 / gcc / coverage.c
blob8a113a50c2e2a55c5ec85bf26157abbf6664cd44
1 /* Read and write coverage files, and associated functionality.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
3 2000, 2001, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
4 Free Software Foundation, Inc.
5 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
6 based on some ideas from Dain Samples of UC Berkeley.
7 Further mangling by Bob Manson, Cygnus Support.
8 Further mangled by Nathan Sidwell, CodeSourcery
10 This file is part of GCC.
12 GCC is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free
14 Software Foundation; either version 3, or (at your option) any later
15 version.
17 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18 WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 for more details.
22 You should have received a copy of the GNU General Public License
23 along with GCC; see the file COPYING3. If not see
24 <http://www.gnu.org/licenses/>. */
27 #define GCOV_LINKAGE
29 #include "config.h"
30 #include "system.h"
31 #include "coretypes.h"
32 #include "tm.h"
33 #include "rtl.h"
34 #include "tree.h"
35 #include "flags.h"
36 #include "output.h"
37 #include "regs.h"
38 #include "expr.h"
39 #include "function.h"
40 #include "basic-block.h"
41 #include "toplev.h"
42 #include "tm_p.h"
43 #include "ggc.h"
44 #include "coverage.h"
45 #include "langhooks.h"
46 #include "hashtab.h"
47 #include "tree-iterator.h"
48 #include "cgraph.h"
49 #include "tree-pass.h"
50 #include "diagnostic-core.h"
51 #include "intl.h"
52 #include "filenames.h"
53 #include "target.h"
55 #include "gcov-io.h"
56 #include "gcov-io.c"
58 struct GTY((chain_next ("%h.next"))) coverage_data
60 struct coverage_data *next; /* next function */
61 unsigned ident; /* function ident */
62 unsigned lineno_checksum; /* function lineno checksum */
63 unsigned cfg_checksum; /* function cfg checksum */
64 tree fn_decl; /* the function decl */
65 tree ctr_vars[GCOV_COUNTERS]; /* counter variables. */
68 /* Counts information for a function. */
69 typedef struct counts_entry
71 /* We hash by */
72 unsigned ident;
73 unsigned ctr;
75 /* Store */
76 unsigned lineno_checksum;
77 unsigned cfg_checksum;
78 gcov_type *counts;
79 struct gcov_ctr_summary summary;
80 } counts_entry_t;
82 static GTY(()) struct coverage_data *functions_head = 0;
83 static struct coverage_data **functions_tail = &functions_head;
84 static unsigned no_coverage = 0;
86 /* Cumulative counter information for whole program. */
87 static unsigned prg_ctr_mask; /* Mask of counter types generated. */
89 /* Counter information for current function. */
90 static unsigned fn_ctr_mask; /* Mask of counters used. */
91 static GTY(()) tree fn_v_ctrs[GCOV_COUNTERS]; /* counter variables. */
92 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated. */
93 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base. */
95 /* Coverage info VAR_DECL and function info type nodes. */
96 static GTY(()) tree gcov_info_var;
97 static GTY(()) tree gcov_fn_info_type;
98 static GTY(()) tree gcov_fn_info_ptr_type;
100 /* Name of the output file for coverage output file. If this is NULL
101 we're not writing to the notes file. */
102 static char *bbg_file_name;
104 /* Name of the count data file. */
105 static char *da_file_name;
107 /* Hash table of count data. */
108 static htab_t counts_hash = NULL;
110 /* The names of merge functions for counters. */
111 static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
112 static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
114 /* Forward declarations. */
115 static hashval_t htab_counts_entry_hash (const void *);
116 static int htab_counts_entry_eq (const void *, const void *);
117 static void htab_counts_entry_del (void *);
118 static void read_counts_file (void);
119 static tree build_var (tree, tree, int);
120 static void build_fn_info_type (tree, unsigned, tree);
121 static void build_info_type (tree, tree);
122 static tree build_fn_info (const struct coverage_data *, tree, tree);
123 static tree build_info (tree, tree);
124 static bool coverage_obj_init (void);
125 static VEC(constructor_elt,gc) *coverage_obj_fn
126 (VEC(constructor_elt,gc) *, tree, struct coverage_data const *);
127 static void coverage_obj_finish (VEC(constructor_elt,gc) *);
129 /* Return the type node for gcov_type. */
131 tree
132 get_gcov_type (void)
134 return lang_hooks.types.type_for_size (GCOV_TYPE_SIZE, false);
137 /* Return the type node for gcov_unsigned_t. */
139 static tree
140 get_gcov_unsigned_t (void)
142 return lang_hooks.types.type_for_size (32, true);
145 static hashval_t
146 htab_counts_entry_hash (const void *of)
148 const counts_entry_t *const entry = (const counts_entry_t *) of;
150 return entry->ident * GCOV_COUNTERS + entry->ctr;
153 static int
154 htab_counts_entry_eq (const void *of1, const void *of2)
156 const counts_entry_t *const entry1 = (const counts_entry_t *) of1;
157 const counts_entry_t *const entry2 = (const counts_entry_t *) of2;
159 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
162 static void
163 htab_counts_entry_del (void *of)
165 counts_entry_t *const entry = (counts_entry_t *) of;
167 free (entry->counts);
168 free (entry);
171 /* Read in the counts file, if available. */
173 static void
174 read_counts_file (void)
176 gcov_unsigned_t fn_ident = 0;
177 struct gcov_summary summary;
178 unsigned new_summary = 1;
179 gcov_unsigned_t tag;
180 int is_error = 0;
181 unsigned lineno_checksum = 0;
182 unsigned cfg_checksum = 0;
184 if (!gcov_open (da_file_name, 1))
185 return;
187 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
189 warning (0, "%qs is not a gcov data file", da_file_name);
190 gcov_close ();
191 return;
193 else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
195 char v[4], e[4];
197 GCOV_UNSIGNED2STRING (v, tag);
198 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
200 warning (0, "%qs is version %q.*s, expected version %q.*s",
201 da_file_name, 4, v, 4, e);
202 gcov_close ();
203 return;
206 /* Read and discard the stamp. */
207 gcov_read_unsigned ();
209 counts_hash = htab_create (10,
210 htab_counts_entry_hash, htab_counts_entry_eq,
211 htab_counts_entry_del);
212 while ((tag = gcov_read_unsigned ()))
214 gcov_unsigned_t length;
215 gcov_position_t offset;
217 length = gcov_read_unsigned ();
218 offset = gcov_position ();
219 if (tag == GCOV_TAG_FUNCTION)
221 if (length)
223 fn_ident = gcov_read_unsigned ();
224 lineno_checksum = gcov_read_unsigned ();
225 cfg_checksum = gcov_read_unsigned ();
227 else
228 fn_ident = lineno_checksum = cfg_checksum = 0;
229 new_summary = 1;
231 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
233 struct gcov_summary sum;
234 unsigned ix;
236 if (new_summary)
237 memset (&summary, 0, sizeof (summary));
239 gcov_read_summary (&sum);
240 for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++)
242 summary.ctrs[ix].runs += sum.ctrs[ix].runs;
243 summary.ctrs[ix].sum_all += sum.ctrs[ix].sum_all;
244 if (summary.ctrs[ix].run_max < sum.ctrs[ix].run_max)
245 summary.ctrs[ix].run_max = sum.ctrs[ix].run_max;
246 summary.ctrs[ix].sum_max += sum.ctrs[ix].sum_max;
248 new_summary = 0;
250 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
252 counts_entry_t **slot, *entry, elt;
253 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
254 unsigned ix;
256 elt.ident = fn_ident;
257 elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
259 slot = (counts_entry_t **) htab_find_slot
260 (counts_hash, &elt, INSERT);
261 entry = *slot;
262 if (!entry)
264 *slot = entry = XCNEW (counts_entry_t);
265 entry->ident = fn_ident;
266 entry->ctr = elt.ctr;
267 entry->lineno_checksum = lineno_checksum;
268 entry->cfg_checksum = cfg_checksum;
269 entry->summary = summary.ctrs[elt.ctr];
270 entry->summary.num = n_counts;
271 entry->counts = XCNEWVEC (gcov_type, n_counts);
273 else if (entry->lineno_checksum != lineno_checksum
274 || entry->cfg_checksum != cfg_checksum)
276 error ("Profile data for function %u is corrupted", fn_ident);
277 error ("checksum is (%x,%x) instead of (%x,%x)",
278 entry->lineno_checksum, entry->cfg_checksum,
279 lineno_checksum, cfg_checksum);
280 htab_delete (counts_hash);
281 break;
283 else if (entry->summary.num != n_counts)
285 error ("Profile data for function %u is corrupted", fn_ident);
286 error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
287 htab_delete (counts_hash);
288 break;
290 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
292 error ("cannot merge separate %s counters for function %u",
293 ctr_names[elt.ctr], fn_ident);
294 goto skip_merge;
296 else
298 entry->summary.runs += summary.ctrs[elt.ctr].runs;
299 entry->summary.sum_all += summary.ctrs[elt.ctr].sum_all;
300 if (entry->summary.run_max < summary.ctrs[elt.ctr].run_max)
301 entry->summary.run_max = summary.ctrs[elt.ctr].run_max;
302 entry->summary.sum_max += summary.ctrs[elt.ctr].sum_max;
304 for (ix = 0; ix != n_counts; ix++)
305 entry->counts[ix] += gcov_read_counter ();
306 skip_merge:;
308 gcov_sync (offset, length);
309 if ((is_error = gcov_is_error ()))
311 error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted",
312 da_file_name);
313 htab_delete (counts_hash);
314 break;
318 gcov_close ();
321 /* Returns the counters for a particular tag. */
323 gcov_type *
324 get_coverage_counts (unsigned counter, unsigned expected,
325 unsigned cfg_checksum, unsigned lineno_checksum,
326 const struct gcov_ctr_summary **summary)
328 counts_entry_t *entry, elt;
330 /* No hash table, no counts. */
331 if (!counts_hash)
333 static int warned = 0;
335 if (!warned++)
336 inform (input_location, (flag_guess_branch_prob
337 ? "file %s not found, execution counts estimated"
338 : "file %s not found, execution counts assumed to be zero"),
339 da_file_name);
340 return NULL;
343 elt.ident = current_function_funcdef_no + 1;
344 elt.ctr = counter;
345 entry = (counts_entry_t *) htab_find (counts_hash, &elt);
346 if (!entry || !entry->summary.num)
347 /* The function was not emitted, or is weak and not chosen in the
348 final executable. Silently fail, because there's nothing we
349 can do about it. */
350 return NULL;
352 if (entry->cfg_checksum != cfg_checksum
353 || entry->summary.num != expected)
355 static int warned = 0;
356 bool warning_printed = false;
357 tree id = DECL_ASSEMBLER_NAME (current_function_decl);
359 warning_printed =
360 warning_at (input_location, OPT_Wcoverage_mismatch,
361 "the control flow of function %qE does not match "
362 "its profile data (counter %qs)", id, ctr_names[counter]);
363 if (warning_printed)
365 inform (input_location, "use -Wno-error=coverage-mismatch to tolerate "
366 "the mismatch but performance may drop if the function is hot");
368 if (!seen_error ()
369 && !warned++)
371 inform (input_location, "coverage mismatch ignored");
372 inform (input_location, flag_guess_branch_prob
373 ? G_("execution counts estimated")
374 : G_("execution counts assumed to be zero"));
375 if (!flag_guess_branch_prob)
376 inform (input_location,
377 "this can result in poorly optimized code");
381 return NULL;
383 else if (entry->lineno_checksum != lineno_checksum)
385 warning (0, "source locations for function %qE have changed,"
386 " the profile data may be out of date",
387 DECL_ASSEMBLER_NAME (current_function_decl));
390 if (summary)
391 *summary = &entry->summary;
393 return entry->counts;
396 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
397 allocation succeeded. */
400 coverage_counter_alloc (unsigned counter, unsigned num)
402 if (no_coverage)
403 return 0;
405 if (!num)
406 return 1;
408 if (!fn_v_ctrs[counter])
410 tree array_type = build_array_type (get_gcov_type (), NULL_TREE);
412 fn_v_ctrs[counter]
413 = build_var (current_function_decl, array_type, counter);
416 fn_b_ctrs[counter] = fn_n_ctrs[counter];
417 fn_n_ctrs[counter] += num;
419 fn_ctr_mask |= 1 << counter;
420 return 1;
423 /* Generate a tree to access COUNTER NO. */
425 tree
426 tree_coverage_counter_ref (unsigned counter, unsigned no)
428 tree gcov_type_node = get_gcov_type ();
430 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
432 no += fn_b_ctrs[counter];
434 /* "no" here is an array index, scaled to bytes later. */
435 return build4 (ARRAY_REF, gcov_type_node, fn_v_ctrs[counter],
436 build_int_cst (integer_type_node, no), NULL, NULL);
439 /* Generate a tree to access the address of COUNTER NO. */
441 tree
442 tree_coverage_counter_addr (unsigned counter, unsigned no)
444 tree gcov_type_node = get_gcov_type ();
446 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
447 no += fn_b_ctrs[counter];
449 /* "no" here is an array index, scaled to bytes later. */
450 return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node,
451 fn_v_ctrs[counter],
452 build_int_cst (integer_type_node, no),
453 NULL, NULL));
457 /* Generate a checksum for a string. CHKSUM is the current
458 checksum. */
460 static unsigned
461 coverage_checksum_string (unsigned chksum, const char *string)
463 int i;
464 char *dup = NULL;
466 /* Look for everything that looks if it were produced by
467 get_file_function_name and zero out the second part
468 that may result from flag_random_seed. This is not critical
469 as the checksums are used only for sanity checking. */
470 for (i = 0; string[i]; i++)
472 int offset = 0;
473 if (!strncmp (string + i, "_GLOBAL__N_", 11))
474 offset = 11;
475 if (!strncmp (string + i, "_GLOBAL__", 9))
476 offset = 9;
478 /* C++ namespaces do have scheme:
479 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
480 since filename might contain extra underscores there seems
481 to be no better chance then walk all possible offsets looking
482 for magicnumber. */
483 if (offset)
485 for (i = i + offset; string[i]; i++)
486 if (string[i]=='_')
488 int y;
490 for (y = 1; y < 9; y++)
491 if (!(string[i + y] >= '0' && string[i + y] <= '9')
492 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
493 break;
494 if (y != 9 || string[i + 9] != '_')
495 continue;
496 for (y = 10; y < 18; y++)
497 if (!(string[i + y] >= '0' && string[i + y] <= '9')
498 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
499 break;
500 if (y != 18)
501 continue;
502 if (!dup)
503 string = dup = xstrdup (string);
504 for (y = 10; y < 18; y++)
505 dup[i + y] = '0';
507 break;
511 chksum = crc32_string (chksum, string);
512 free (dup);
514 return chksum;
517 /* Compute checksum for the current function. We generate a CRC32. */
519 unsigned
520 coverage_compute_lineno_checksum (void)
522 expanded_location xloc
523 = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
524 unsigned chksum = xloc.line;
526 chksum = coverage_checksum_string (chksum, xloc.file);
527 chksum = coverage_checksum_string
528 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
530 return chksum;
533 /* Compute cfg checksum for the current function.
534 The checksum is calculated carefully so that
535 source code changes that doesn't affect the control flow graph
536 won't change the checksum.
537 This is to make the profile data useable across source code change.
538 The downside of this is that the compiler may use potentially
539 wrong profile data - that the source code change has non-trivial impact
540 on the validity of profile data (e.g. the reversed condition)
541 but the compiler won't detect the change and use the wrong profile data. */
543 unsigned
544 coverage_compute_cfg_checksum (void)
546 basic_block bb;
547 unsigned chksum = n_basic_blocks;
549 FOR_EACH_BB (bb)
551 edge e;
552 edge_iterator ei;
553 chksum = crc32_byte (chksum, bb->index);
554 FOR_EACH_EDGE (e, ei, bb->succs)
556 chksum = crc32_byte (chksum, e->dest->index);
560 return chksum;
563 /* Begin output to the graph file for the current function.
564 Writes the function header. Returns nonzero if data should be output. */
567 coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
569 expanded_location xloc;
570 unsigned long offset;
572 /* We don't need to output .gcno file unless we're under -ftest-coverage
573 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
574 if (no_coverage || !bbg_file_name)
575 return 0;
577 xloc = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
579 /* Announce function */
580 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
581 gcov_write_unsigned (current_function_funcdef_no + 1);
582 gcov_write_unsigned (lineno_checksum);
583 gcov_write_unsigned (cfg_checksum);
584 gcov_write_string (IDENTIFIER_POINTER
585 (DECL_ASSEMBLER_NAME (current_function_decl)));
586 gcov_write_string (xloc.file);
587 gcov_write_unsigned (xloc.line);
588 gcov_write_length (offset);
590 return !gcov_is_error ();
593 /* Finish coverage data for the current function. Verify no output
594 error has occurred. Save function coverage counts. */
596 void
597 coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum)
599 unsigned i;
601 if (bbg_file_name && gcov_is_error ())
603 warning (0, "error writing %qs", bbg_file_name);
604 unlink (bbg_file_name);
605 bbg_file_name = NULL;
608 if (fn_ctr_mask)
610 struct coverage_data *item = 0;
612 /* If the function is extern (i.e. extern inline), then we won't
613 be outputting it, so don't chain it onto the function
614 list. */
615 if (!DECL_EXTERNAL (current_function_decl))
617 item = ggc_alloc_coverage_data ();
619 item->ident = current_function_funcdef_no + 1;
620 item->lineno_checksum = lineno_checksum;
621 item->cfg_checksum = cfg_checksum;
623 item->fn_decl = current_function_decl;
624 item->next = 0;
625 *functions_tail = item;
626 functions_tail = &item->next;
629 for (i = 0; i != GCOV_COUNTERS; i++)
631 tree var = fn_v_ctrs[i];
633 if (item)
634 item->ctr_vars[i] = var;
635 if (var)
637 tree array_type = build_index_type (size_int (fn_n_ctrs[i] - 1));
638 array_type = build_array_type (get_gcov_type (), array_type);
639 TREE_TYPE (var) = array_type;
640 DECL_SIZE (var) = TYPE_SIZE (array_type);
641 DECL_SIZE_UNIT (var) = TYPE_SIZE_UNIT (array_type);
642 varpool_finalize_decl (var);
645 fn_b_ctrs[i] = fn_n_ctrs[i] = 0;
646 fn_v_ctrs[i] = NULL_TREE;
648 prg_ctr_mask |= fn_ctr_mask;
649 fn_ctr_mask = 0;
653 /* Build a coverage variable of TYPE for function FN_DECL. If COUNTER
654 >= 0 it is a counter array, otherwise it is the function structure. */
656 static tree
657 build_var (tree fn_decl, tree type, int counter)
659 tree var = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, type);
660 const char *fn_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn_decl));
661 char *buf;
662 size_t fn_name_len, len;
664 fn_name = targetm.strip_name_encoding (fn_name);
665 fn_name_len = strlen (fn_name);
666 buf = XALLOCAVEC (char, fn_name_len + 8 + sizeof (int) * 3);
668 if (counter < 0)
669 strcpy (buf, "__gcov__");
670 else
671 sprintf (buf, "__gcov%u_", counter);
672 len = strlen (buf);
673 #ifndef NO_DOT_IN_LABEL
674 buf[len - 1] = '.';
675 #elif !defined NO_DOLLAR_IN_LABEL
676 buf[len - 1] = '$';
677 #endif
678 memcpy (buf + len, fn_name, fn_name_len + 1);
679 DECL_NAME (var) = get_identifier (buf);
680 TREE_STATIC (var) = 1;
681 TREE_ADDRESSABLE (var) = 1;
682 DECL_ALIGN (var) = TYPE_ALIGN (type);
684 return var;
687 /* Creates the gcov_fn_info RECORD_TYPE. */
689 static void
690 build_fn_info_type (tree type, unsigned counters, tree gcov_info_type)
692 tree ctr_info = lang_hooks.types.make_type (RECORD_TYPE);
693 tree field, fields;
694 tree array_type;
696 gcc_assert (counters);
698 /* ctr_info::num */
699 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
700 get_gcov_unsigned_t ());
701 fields = field;
703 /* ctr_info::values */
704 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
705 build_pointer_type (get_gcov_type ()));
706 DECL_CHAIN (field) = fields;
707 fields = field;
709 finish_builtin_struct (ctr_info, "__gcov_ctr_info", fields, NULL_TREE);
711 /* key */
712 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
713 build_pointer_type (build_qualified_type
714 (gcov_info_type, TYPE_QUAL_CONST)));
715 fields = field;
717 /* ident */
718 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
719 get_gcov_unsigned_t ());
720 DECL_CHAIN (field) = fields;
721 fields = field;
723 /* lineno_checksum */
724 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
725 get_gcov_unsigned_t ());
726 DECL_CHAIN (field) = fields;
727 fields = field;
729 /* cfg checksum */
730 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
731 get_gcov_unsigned_t ());
732 DECL_CHAIN (field) = fields;
733 fields = field;
735 array_type = build_index_type (size_int (counters - 1));
736 array_type = build_array_type (ctr_info, array_type);
738 /* counters */
739 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, array_type);
740 DECL_CHAIN (field) = fields;
741 fields = field;
743 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
746 /* Returns a CONSTRUCTOR for a gcov_fn_info. DATA is
747 the coverage data for the function and TYPE is the gcov_fn_info
748 RECORD_TYPE. KEY is the object file key. */
750 static tree
751 build_fn_info (const struct coverage_data *data, tree type, tree key)
753 tree fields = TYPE_FIELDS (type);
754 tree ctr_type;
755 unsigned ix;
756 VEC(constructor_elt,gc) *v1 = NULL;
757 VEC(constructor_elt,gc) *v2 = NULL;
759 /* key */
760 CONSTRUCTOR_APPEND_ELT (v1, fields,
761 build1 (ADDR_EXPR, TREE_TYPE (fields), key));
762 fields = DECL_CHAIN (fields);
764 /* ident */
765 CONSTRUCTOR_APPEND_ELT (v1, fields,
766 build_int_cstu (get_gcov_unsigned_t (),
767 data->ident));
768 fields = DECL_CHAIN (fields);
770 /* lineno_checksum */
771 CONSTRUCTOR_APPEND_ELT (v1, fields,
772 build_int_cstu (get_gcov_unsigned_t (),
773 data->lineno_checksum));
774 fields = DECL_CHAIN (fields);
776 /* cfg_checksum */
777 CONSTRUCTOR_APPEND_ELT (v1, fields,
778 build_int_cstu (get_gcov_unsigned_t (),
779 data->cfg_checksum));
780 fields = DECL_CHAIN (fields);
782 /* counters */
783 ctr_type = TREE_TYPE (TREE_TYPE (fields));
784 for (ix = 0; ix != GCOV_COUNTERS; ix++)
785 if (prg_ctr_mask & (1 << ix))
787 VEC(constructor_elt,gc) *ctr = NULL;
788 tree var = data->ctr_vars[ix];
789 unsigned count = 0;
791 if (var)
792 count
793 = tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var))), 0)
794 + 1;
796 CONSTRUCTOR_APPEND_ELT (ctr, TYPE_FIELDS (ctr_type),
797 build_int_cstu (get_gcov_unsigned_t (),
798 count));
800 if (var)
801 CONSTRUCTOR_APPEND_ELT (ctr, DECL_CHAIN (TYPE_FIELDS (ctr_type)),
802 build_fold_addr_expr (var));
804 CONSTRUCTOR_APPEND_ELT (v2, NULL, build_constructor (ctr_type, ctr));
807 CONSTRUCTOR_APPEND_ELT (v1, fields,
808 build_constructor (TREE_TYPE (fields), v2));
810 return build_constructor (type, v1);
813 /* Create gcov_info struct. TYPE is the incomplete RECORD_TYPE to be
814 completed, and FN_INFO_PTR_TYPE is a pointer to the function info type. */
816 static void
817 build_info_type (tree type, tree fn_info_ptr_type)
819 tree field, fields = NULL_TREE;
820 tree merge_fn_type;
822 /* Version ident */
823 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
824 get_gcov_unsigned_t ());
825 DECL_CHAIN (field) = fields;
826 fields = field;
828 /* next pointer */
829 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
830 build_pointer_type (build_qualified_type
831 (type, TYPE_QUAL_CONST)));
832 DECL_CHAIN (field) = fields;
833 fields = field;
835 /* stamp */
836 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
837 get_gcov_unsigned_t ());
838 DECL_CHAIN (field) = fields;
839 fields = field;
841 /* Filename */
842 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
843 build_pointer_type (build_qualified_type
844 (char_type_node, TYPE_QUAL_CONST)));
845 DECL_CHAIN (field) = fields;
846 fields = field;
848 /* merge fn array */
849 merge_fn_type
850 = build_function_type_list (void_type_node,
851 build_pointer_type (get_gcov_type ()),
852 get_gcov_unsigned_t (), NULL_TREE);
853 merge_fn_type
854 = build_array_type (build_pointer_type (merge_fn_type),
855 build_index_type (size_int (GCOV_COUNTERS - 1)));
856 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
857 merge_fn_type);
858 DECL_CHAIN (field) = fields;
859 fields = field;
861 /* n_functions */
862 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
863 get_gcov_unsigned_t ());
864 DECL_CHAIN (field) = fields;
865 fields = field;
867 /* function_info pointer pointer */
868 fn_info_ptr_type = build_pointer_type
869 (build_qualified_type (fn_info_ptr_type, TYPE_QUAL_CONST));
870 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
871 fn_info_ptr_type);
872 DECL_CHAIN (field) = fields;
873 fields = field;
875 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
878 /* Returns a CONSTRUCTOR for the gcov_info object. INFO_TYPE is the
879 gcov_info structure type, FN_ARY is the array of pointers to
880 function info objects. */
882 static tree
883 build_info (tree info_type, tree fn_ary)
885 tree info_fields = TYPE_FIELDS (info_type);
886 tree merge_fn_type, n_funcs;
887 unsigned ix;
888 tree filename_string;
889 int da_file_name_len;
890 VEC(constructor_elt,gc) *v1 = NULL;
891 VEC(constructor_elt,gc) *v2 = NULL;
893 /* Version ident */
894 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
895 build_int_cstu (TREE_TYPE (info_fields),
896 GCOV_VERSION));
897 info_fields = DECL_CHAIN (info_fields);
899 /* next -- NULL */
900 CONSTRUCTOR_APPEND_ELT (v1, info_fields, null_pointer_node);
901 info_fields = DECL_CHAIN (info_fields);
903 /* stamp */
904 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
905 build_int_cstu (TREE_TYPE (info_fields),
906 local_tick));
907 info_fields = DECL_CHAIN (info_fields);
909 /* Filename */
910 da_file_name_len = strlen (da_file_name);
911 filename_string = build_string (da_file_name_len + 1, da_file_name);
912 TREE_TYPE (filename_string) = build_array_type
913 (char_type_node, build_index_type (size_int (da_file_name_len)));
914 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
915 build1 (ADDR_EXPR, TREE_TYPE (info_fields),
916 filename_string));
917 info_fields = DECL_CHAIN (info_fields);
919 /* merge fn array -- NULL slots indicate unmeasured counters */
920 merge_fn_type = TREE_TYPE (TREE_TYPE (info_fields));
921 for (ix = 0; ix != GCOV_COUNTERS; ix++)
923 tree ptr = null_pointer_node;
925 if ((1u << ix) & prg_ctr_mask)
927 tree merge_fn = build_decl (BUILTINS_LOCATION,
928 FUNCTION_DECL,
929 get_identifier (ctr_merge_functions[ix]),
930 TREE_TYPE (merge_fn_type));
931 DECL_EXTERNAL (merge_fn) = 1;
932 TREE_PUBLIC (merge_fn) = 1;
933 DECL_ARTIFICIAL (merge_fn) = 1;
934 TREE_NOTHROW (merge_fn) = 1;
935 /* Initialize assembler name so we can stream out. */
936 DECL_ASSEMBLER_NAME (merge_fn);
937 ptr = build1 (ADDR_EXPR, merge_fn_type, merge_fn);
939 CONSTRUCTOR_APPEND_ELT (v2, NULL, ptr);
941 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
942 build_constructor (TREE_TYPE (info_fields), v2));
943 info_fields = DECL_CHAIN (info_fields);
945 /* n_functions */
946 n_funcs = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (fn_ary)));
947 n_funcs = fold_build2 (PLUS_EXPR, TREE_TYPE (info_fields),
948 n_funcs, size_one_node);
949 CONSTRUCTOR_APPEND_ELT (v1, info_fields, n_funcs);
950 info_fields = DECL_CHAIN (info_fields);
952 /* functions */
953 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
954 build1 (ADDR_EXPR, TREE_TYPE (info_fields), fn_ary));
955 info_fields = DECL_CHAIN (info_fields);
957 gcc_assert (!info_fields);
958 return build_constructor (info_type, v1);
961 /* Create the gcov_info types and object. Generate the constructor
962 function to call __gcov_init. Does not generate the initializer
963 for the object. Returns TRUE if coverage data is being emitted. */
965 static bool
966 coverage_obj_init (void)
968 tree gcov_info_type, ctor, stmt, init_fn;
969 unsigned n_counters = 0;
970 unsigned ix;
971 struct coverage_data *fn;
972 struct coverage_data **fn_prev;
973 char name_buf[32];
975 no_coverage = 1; /* Disable any further coverage. */
977 if (!prg_ctr_mask)
978 return false;
980 if (cgraph_dump_file)
981 fprintf (cgraph_dump_file, "Using data file %s\n", da_file_name);
983 /* Prune functions. */
984 for (fn_prev = &functions_head; (fn = *fn_prev);)
985 if (DECL_STRUCT_FUNCTION (fn->fn_decl))
986 fn_prev = &fn->next;
987 else
988 /* The function is not being emitted, remove from list. */
989 *fn_prev = fn->next;
991 if (functions_head == NULL)
992 return false;
994 for (ix = 0; ix != GCOV_COUNTERS; ix++)
995 if ((1u << ix) & prg_ctr_mask)
996 n_counters++;
998 /* Build the info and fn_info types. These are mutually recursive. */
999 gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1000 gcov_fn_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1001 gcov_fn_info_ptr_type = build_pointer_type
1002 (build_qualified_type (gcov_fn_info_type, TYPE_QUAL_CONST));
1003 build_fn_info_type (gcov_fn_info_type, n_counters, gcov_info_type);
1004 build_info_type (gcov_info_type, gcov_fn_info_ptr_type);
1006 /* Build the gcov info var, this is referred to in its own
1007 initializer. */
1008 gcov_info_var = build_decl (BUILTINS_LOCATION,
1009 VAR_DECL, NULL_TREE, gcov_info_type);
1010 TREE_STATIC (gcov_info_var) = 1;
1011 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
1012 DECL_NAME (gcov_info_var) = get_identifier (name_buf);
1014 /* Build a decl for __gcov_init. */
1015 init_fn = build_pointer_type (gcov_info_type);
1016 init_fn = build_function_type_list (void_type_node, init_fn, NULL);
1017 init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
1018 get_identifier ("__gcov_init"), init_fn);
1019 TREE_PUBLIC (init_fn) = 1;
1020 DECL_EXTERNAL (init_fn) = 1;
1021 DECL_ASSEMBLER_NAME (init_fn);
1023 /* Generate a call to __gcov_init(&gcov_info). */
1024 ctor = NULL;
1025 stmt = build_fold_addr_expr (gcov_info_var);
1026 stmt = build_call_expr (init_fn, 1, stmt);
1027 append_to_statement_list (stmt, &ctor);
1029 /* Generate a constructor to run it. */
1030 cgraph_build_static_cdtor ('I', ctor, DEFAULT_INIT_PRIORITY);
1032 return true;
1035 /* Generate the coverage function info for FN and DATA. Append a
1036 pointer to that object to CTOR and return the appended CTOR. */
1038 static VEC(constructor_elt,gc) *
1039 coverage_obj_fn (VEC(constructor_elt,gc) *ctor, tree fn,
1040 struct coverage_data const *data)
1042 tree init = build_fn_info (data, gcov_fn_info_type, gcov_info_var);
1043 tree var = build_var (fn, gcov_fn_info_type, -1);
1045 DECL_INITIAL (var) = init;
1046 varpool_finalize_decl (var);
1048 CONSTRUCTOR_APPEND_ELT (ctor, NULL,
1049 build1 (ADDR_EXPR, gcov_fn_info_ptr_type, var));
1050 return ctor;
1053 /* Finalize the coverage data. Generates the array of pointers to
1054 function objects from CTOR. Generate the gcov_info initializer. */
1056 static void
1057 coverage_obj_finish (VEC(constructor_elt,gc) *ctor)
1059 unsigned n_functions = VEC_length(constructor_elt, ctor);
1060 tree fn_info_ary_type = build_array_type
1061 (build_qualified_type (gcov_fn_info_ptr_type, TYPE_QUAL_CONST),
1062 build_index_type (size_int (n_functions - 1)));
1063 tree fn_info_ary = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE,
1064 fn_info_ary_type);
1065 char name_buf[32];
1067 TREE_STATIC (fn_info_ary) = 1;
1068 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 1);
1069 DECL_NAME (fn_info_ary) = get_identifier (name_buf);
1070 DECL_INITIAL (fn_info_ary) = build_constructor (fn_info_ary_type, ctor);
1071 varpool_finalize_decl (fn_info_ary);
1073 DECL_INITIAL (gcov_info_var)
1074 = build_info (TREE_TYPE (gcov_info_var), fn_info_ary);
1075 varpool_finalize_decl (gcov_info_var);
1078 /* Perform file-level initialization. Read in data file, generate name
1079 of graph file. */
1081 void
1082 coverage_init (const char *filename)
1084 int len = strlen (filename);
1085 int prefix_len = 0;
1087 if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
1088 profile_data_prefix = getpwd ();
1090 if (profile_data_prefix)
1091 prefix_len = strlen (profile_data_prefix);
1093 /* Name of da file. */
1094 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
1095 + prefix_len + 2);
1097 if (profile_data_prefix)
1099 memcpy (da_file_name, profile_data_prefix, prefix_len);
1100 da_file_name[prefix_len++] = '/';
1102 memcpy (da_file_name + prefix_len, filename, len);
1103 strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX);
1105 if (flag_branch_probabilities)
1106 read_counts_file ();
1108 /* Name of bbg file. */
1109 if (flag_test_coverage && !flag_compare_debug)
1111 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1);
1112 memcpy (bbg_file_name, filename, len);
1113 strcpy (bbg_file_name + len, GCOV_NOTE_SUFFIX);
1115 if (!gcov_open (bbg_file_name, -1))
1117 error ("cannot open %s", bbg_file_name);
1118 bbg_file_name = NULL;
1120 else
1122 gcov_write_unsigned (GCOV_NOTE_MAGIC);
1123 gcov_write_unsigned (GCOV_VERSION);
1124 gcov_write_unsigned (local_tick);
1129 /* Performs file-level cleanup. Close graph file, generate coverage
1130 variables and constructor. */
1132 void
1133 coverage_finish (void)
1135 if (bbg_file_name && gcov_close ())
1136 unlink (bbg_file_name);
1138 if (!local_tick || local_tick == (unsigned)-1)
1139 /* Only remove the da file, if we cannot stamp it. If we can
1140 stamp it, libgcov will DTRT. */
1141 unlink (da_file_name);
1143 if (coverage_obj_init ())
1145 VEC(constructor_elt,gc) *fn_ctor = NULL;
1146 struct coverage_data *fn;
1148 for (fn = functions_head; fn; fn = fn->next)
1149 fn_ctor = coverage_obj_fn (fn_ctor, fn->fn_decl, fn);
1150 coverage_obj_finish (fn_ctor);
1154 #include "gt-coverage.h"