* ChangeLog: Fix whitespace.
[official-gcc.git] / gcc / coverage.c
blob58a76cafadd4274e991d51e6f972e1f948cbec5f
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"))) coverage_data
59 struct coverage_data *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 coverage_data *functions_head = 0;
82 static struct coverage_data **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 /* Coverage info VAR_DECL and function info type nodes. */
95 static GTY(()) tree gcov_info_var;
96 static GTY(()) tree gcov_fn_info_type;
97 static GTY(()) tree gcov_fn_info_ptr_type;
99 /* Name of the output file for coverage output file. If this is NULL
100 we're not writing to the notes file. */
101 static char *bbg_file_name;
103 /* Name of the count data file. */
104 static char *da_file_name;
106 /* Hash table of count data. */
107 static htab_t counts_hash = NULL;
109 /* The names of merge functions for counters. */
110 static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
111 static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
113 /* Forward declarations. */
114 static hashval_t htab_counts_entry_hash (const void *);
115 static int htab_counts_entry_eq (const void *, const void *);
116 static void htab_counts_entry_del (void *);
117 static void read_counts_file (void);
118 static tree build_var (tree, tree, int);
119 static void build_fn_info_type (tree, unsigned, tree);
120 static void build_info_type (tree, tree);
121 static tree build_fn_info (const struct coverage_data *, tree, tree);
122 static tree build_info (tree, tree);
123 static bool coverage_obj_init (void);
124 static VEC(constructor_elt,gc) *coverage_obj_fn
125 (VEC(constructor_elt,gc) *, tree, struct coverage_data const *);
126 static void coverage_obj_finish (VEC(constructor_elt,gc) *);
128 /* Return the type node for gcov_type. */
130 tree
131 get_gcov_type (void)
133 return lang_hooks.types.type_for_size (GCOV_TYPE_SIZE, false);
136 /* Return the type node for gcov_unsigned_t. */
138 static tree
139 get_gcov_unsigned_t (void)
141 return lang_hooks.types.type_for_size (32, true);
144 static hashval_t
145 htab_counts_entry_hash (const void *of)
147 const counts_entry_t *const entry = (const counts_entry_t *) of;
149 return entry->ident * GCOV_COUNTERS + entry->ctr;
152 static int
153 htab_counts_entry_eq (const void *of1, const void *of2)
155 const counts_entry_t *const entry1 = (const counts_entry_t *) of1;
156 const counts_entry_t *const entry2 = (const counts_entry_t *) of2;
158 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
161 static void
162 htab_counts_entry_del (void *of)
164 counts_entry_t *const entry = (counts_entry_t *) of;
166 free (entry->counts);
167 free (entry);
170 /* Read in the counts file, if available. */
172 static void
173 read_counts_file (void)
175 gcov_unsigned_t fn_ident = 0;
176 struct gcov_summary summary;
177 unsigned new_summary = 1;
178 gcov_unsigned_t tag;
179 int is_error = 0;
180 unsigned lineno_checksum = 0;
181 unsigned cfg_checksum = 0;
183 if (!gcov_open (da_file_name, 1))
184 return;
186 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
188 warning (0, "%qs is not a gcov data file", da_file_name);
189 gcov_close ();
190 return;
192 else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
194 char v[4], e[4];
196 GCOV_UNSIGNED2STRING (v, tag);
197 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
199 warning (0, "%qs is version %q.*s, expected version %q.*s",
200 da_file_name, 4, v, 4, e);
201 gcov_close ();
202 return;
205 /* Read and discard the stamp. */
206 gcov_read_unsigned ();
208 counts_hash = htab_create (10,
209 htab_counts_entry_hash, htab_counts_entry_eq,
210 htab_counts_entry_del);
211 while ((tag = gcov_read_unsigned ()))
213 gcov_unsigned_t length;
214 gcov_position_t offset;
216 length = gcov_read_unsigned ();
217 offset = gcov_position ();
218 if (tag == GCOV_TAG_FUNCTION)
220 if (length)
222 fn_ident = gcov_read_unsigned ();
223 lineno_checksum = gcov_read_unsigned ();
224 cfg_checksum = gcov_read_unsigned ();
226 else
227 fn_ident = lineno_checksum = cfg_checksum = 0;
228 new_summary = 1;
230 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
232 struct gcov_summary sum;
233 unsigned ix;
235 if (new_summary)
236 memset (&summary, 0, sizeof (summary));
238 gcov_read_summary (&sum);
239 for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++)
241 summary.ctrs[ix].runs += sum.ctrs[ix].runs;
242 summary.ctrs[ix].sum_all += sum.ctrs[ix].sum_all;
243 if (summary.ctrs[ix].run_max < sum.ctrs[ix].run_max)
244 summary.ctrs[ix].run_max = sum.ctrs[ix].run_max;
245 summary.ctrs[ix].sum_max += sum.ctrs[ix].sum_max;
247 new_summary = 0;
249 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
251 counts_entry_t **slot, *entry, elt;
252 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
253 unsigned ix;
255 elt.ident = fn_ident;
256 elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
258 slot = (counts_entry_t **) htab_find_slot
259 (counts_hash, &elt, INSERT);
260 entry = *slot;
261 if (!entry)
263 *slot = entry = XCNEW (counts_entry_t);
264 entry->ident = fn_ident;
265 entry->ctr = elt.ctr;
266 entry->lineno_checksum = lineno_checksum;
267 entry->cfg_checksum = cfg_checksum;
268 entry->summary = summary.ctrs[elt.ctr];
269 entry->summary.num = n_counts;
270 entry->counts = XCNEWVEC (gcov_type, n_counts);
272 else if (entry->lineno_checksum != lineno_checksum
273 || entry->cfg_checksum != cfg_checksum)
275 error ("Profile data for function %u is corrupted", fn_ident);
276 error ("checksum is (%x,%x) instead of (%x,%x)",
277 entry->lineno_checksum, entry->cfg_checksum,
278 lineno_checksum, cfg_checksum);
279 htab_delete (counts_hash);
280 break;
282 else if (entry->summary.num != n_counts)
284 error ("Profile data for function %u is corrupted", fn_ident);
285 error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
286 htab_delete (counts_hash);
287 break;
289 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
291 error ("cannot merge separate %s counters for function %u",
292 ctr_names[elt.ctr], fn_ident);
293 goto skip_merge;
295 else
297 entry->summary.runs += summary.ctrs[elt.ctr].runs;
298 entry->summary.sum_all += summary.ctrs[elt.ctr].sum_all;
299 if (entry->summary.run_max < summary.ctrs[elt.ctr].run_max)
300 entry->summary.run_max = summary.ctrs[elt.ctr].run_max;
301 entry->summary.sum_max += summary.ctrs[elt.ctr].sum_max;
303 for (ix = 0; ix != n_counts; ix++)
304 entry->counts[ix] += gcov_read_counter ();
305 skip_merge:;
307 gcov_sync (offset, length);
308 if ((is_error = gcov_is_error ()))
310 error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted",
311 da_file_name);
312 htab_delete (counts_hash);
313 break;
317 gcov_close ();
320 /* Returns the counters for a particular tag. */
322 gcov_type *
323 get_coverage_counts (unsigned counter, unsigned expected,
324 unsigned cfg_checksum, unsigned lineno_checksum,
325 const struct gcov_ctr_summary **summary)
327 counts_entry_t *entry, elt;
329 /* No hash table, no counts. */
330 if (!counts_hash)
332 static int warned = 0;
334 if (!warned++)
335 inform (input_location, (flag_guess_branch_prob
336 ? "file %s not found, execution counts estimated"
337 : "file %s not found, execution counts assumed to be zero"),
338 da_file_name);
339 return NULL;
342 elt.ident = current_function_funcdef_no + 1;
343 elt.ctr = counter;
344 entry = (counts_entry_t *) htab_find (counts_hash, &elt);
345 if (!entry || !entry->summary.num)
346 /* The function was not emitted, or is weak and not chosen in the
347 final executable. Silently fail, because there's nothing we
348 can do about it. */
349 return NULL;
351 if (entry->cfg_checksum != cfg_checksum
352 || entry->summary.num != expected)
354 static int warned = 0;
355 bool warning_printed = false;
356 tree id = DECL_ASSEMBLER_NAME (current_function_decl);
358 warning_printed =
359 warning_at (input_location, OPT_Wcoverage_mismatch,
360 "the control flow of function %qE does not match "
361 "its profile data (counter %qs)", id, ctr_names[counter]);
362 if (warning_printed)
364 inform (input_location, "use -Wno-error=coverage-mismatch to tolerate "
365 "the mismatch but performance may drop if the function is hot");
367 if (!seen_error ()
368 && !warned++)
370 inform (input_location, "coverage mismatch ignored");
371 inform (input_location, flag_guess_branch_prob
372 ? G_("execution counts estimated")
373 : G_("execution counts assumed to be zero"));
374 if (!flag_guess_branch_prob)
375 inform (input_location,
376 "this can result in poorly optimized code");
380 return NULL;
382 else if (entry->lineno_checksum != lineno_checksum)
384 warning (0, "source locations for function %qE have changed,"
385 " the profile data may be out of date",
386 DECL_ASSEMBLER_NAME (current_function_decl));
389 if (summary)
390 *summary = &entry->summary;
392 return entry->counts;
395 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
396 allocation succeeded. */
399 coverage_counter_alloc (unsigned counter, unsigned num)
401 if (no_coverage)
402 return 0;
404 if (!num)
405 return 1;
407 if (!fn_v_ctrs[counter])
409 tree array_type = build_array_type (get_gcov_type (), NULL_TREE);
411 fn_v_ctrs[counter]
412 = build_var (current_function_decl, array_type, counter);
415 fn_b_ctrs[counter] = fn_n_ctrs[counter];
416 fn_n_ctrs[counter] += num;
418 fn_ctr_mask |= 1 << counter;
419 return 1;
422 /* Generate a tree to access COUNTER NO. */
424 tree
425 tree_coverage_counter_ref (unsigned counter, unsigned no)
427 tree gcov_type_node = get_gcov_type ();
429 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
431 no += fn_b_ctrs[counter];
433 /* "no" here is an array index, scaled to bytes later. */
434 return build4 (ARRAY_REF, gcov_type_node, fn_v_ctrs[counter],
435 build_int_cst (integer_type_node, no), NULL, NULL);
438 /* Generate a tree to access the address of COUNTER NO. */
440 tree
441 tree_coverage_counter_addr (unsigned counter, unsigned no)
443 tree gcov_type_node = get_gcov_type ();
445 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
446 no += fn_b_ctrs[counter];
448 /* "no" here is an array index, scaled to bytes later. */
449 return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node,
450 fn_v_ctrs[counter],
451 build_int_cst (integer_type_node, no),
452 NULL, NULL));
456 /* Generate a checksum for a string. CHKSUM is the current
457 checksum. */
459 static unsigned
460 coverage_checksum_string (unsigned chksum, const char *string)
462 int i;
463 char *dup = NULL;
465 /* Look for everything that looks if it were produced by
466 get_file_function_name and zero out the second part
467 that may result from flag_random_seed. This is not critical
468 as the checksums are used only for sanity checking. */
469 for (i = 0; string[i]; i++)
471 int offset = 0;
472 if (!strncmp (string + i, "_GLOBAL__N_", 11))
473 offset = 11;
474 if (!strncmp (string + i, "_GLOBAL__", 9))
475 offset = 9;
477 /* C++ namespaces do have scheme:
478 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
479 since filename might contain extra underscores there seems
480 to be no better chance then walk all possible offsets looking
481 for magicnumber. */
482 if (offset)
484 for (i = i + offset; string[i]; i++)
485 if (string[i]=='_')
487 int y;
489 for (y = 1; y < 9; y++)
490 if (!(string[i + y] >= '0' && string[i + y] <= '9')
491 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
492 break;
493 if (y != 9 || string[i + 9] != '_')
494 continue;
495 for (y = 10; y < 18; y++)
496 if (!(string[i + y] >= '0' && string[i + y] <= '9')
497 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
498 break;
499 if (y != 18)
500 continue;
501 if (!dup)
502 string = dup = xstrdup (string);
503 for (y = 10; y < 18; y++)
504 dup[i + y] = '0';
506 break;
510 chksum = crc32_string (chksum, string);
511 free (dup);
513 return chksum;
516 /* Compute checksum for the current function. We generate a CRC32. */
518 unsigned
519 coverage_compute_lineno_checksum (void)
521 expanded_location xloc
522 = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
523 unsigned chksum = xloc.line;
525 chksum = coverage_checksum_string (chksum, xloc.file);
526 chksum = coverage_checksum_string
527 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
529 return chksum;
532 /* Compute cfg checksum for the current function.
533 The checksum is calculated carefully so that
534 source code changes that doesn't affect the control flow graph
535 won't change the checksum.
536 This is to make the profile data useable across source code change.
537 The downside of this is that the compiler may use potentially
538 wrong profile data - that the source code change has non-trivial impact
539 on the validity of profile data (e.g. the reversed condition)
540 but the compiler won't detect the change and use the wrong profile data. */
542 unsigned
543 coverage_compute_cfg_checksum (void)
545 basic_block bb;
546 unsigned chksum = n_basic_blocks;
548 FOR_EACH_BB (bb)
550 edge e;
551 edge_iterator ei;
552 chksum = crc32_byte (chksum, bb->index);
553 FOR_EACH_EDGE (e, ei, bb->succs)
555 chksum = crc32_byte (chksum, e->dest->index);
559 return chksum;
562 /* Begin output to the graph file for the current function.
563 Writes the function header. Returns nonzero if data should be output. */
566 coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
568 expanded_location xloc;
569 unsigned long offset;
571 /* We don't need to output .gcno file unless we're under -ftest-coverage
572 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
573 if (no_coverage || !bbg_file_name)
574 return 0;
576 xloc = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
578 /* Announce function */
579 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
580 gcov_write_unsigned (current_function_funcdef_no + 1);
581 gcov_write_unsigned (lineno_checksum);
582 gcov_write_unsigned (cfg_checksum);
583 gcov_write_string (IDENTIFIER_POINTER
584 (DECL_ASSEMBLER_NAME (current_function_decl)));
585 gcov_write_string (xloc.file);
586 gcov_write_unsigned (xloc.line);
587 gcov_write_length (offset);
589 return !gcov_is_error ();
592 /* Finish coverage data for the current function. Verify no output
593 error has occurred. Save function coverage counts. */
595 void
596 coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum)
598 unsigned i;
600 if (bbg_file_name && gcov_is_error ())
602 warning (0, "error writing %qs", bbg_file_name);
603 unlink (bbg_file_name);
604 bbg_file_name = NULL;
607 if (fn_ctr_mask)
609 struct coverage_data *item = 0;
611 /* If the function is extern (i.e. extern inline), then we won't
612 be outputting it, so don't chain it onto the function
613 list. */
614 if (!DECL_EXTERNAL (current_function_decl))
616 item = ggc_alloc_coverage_data ();
618 item->ident = current_function_funcdef_no + 1;
619 item->lineno_checksum = lineno_checksum;
620 item->cfg_checksum = cfg_checksum;
622 item->fn_decl = current_function_decl;
623 item->next = 0;
624 *functions_tail = item;
625 functions_tail = &item->next;
628 for (i = 0; i != GCOV_COUNTERS; i++)
630 tree var = fn_v_ctrs[i];
632 if (item)
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);
644 fn_b_ctrs[i] = fn_n_ctrs[i] = 0;
645 fn_v_ctrs[i] = NULL_TREE;
647 prg_ctr_mask |= fn_ctr_mask;
648 fn_ctr_mask = 0;
652 /* Build a coverage variable of TYPE for function FN_DECL. If COUNTER
653 >= 0 it is a counter array, otherwise it is the function structure. */
655 static tree
656 build_var (tree fn_decl, tree type, int counter)
658 tree var = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, type);
659 tree fn_name = DECL_ASSEMBLER_NAME (fn_decl);
660 char *buf = (char *)alloca (IDENTIFIER_LENGTH (fn_name) + 10);
662 if (counter < 0)
663 sprintf (buf, "__gcov__%s", IDENTIFIER_POINTER (fn_name));
664 else
665 sprintf (buf, "__gcov%u_%s", counter, IDENTIFIER_POINTER (fn_name));
666 DECL_NAME (var) = get_identifier (buf);
667 TREE_STATIC (var) = 1;
668 TREE_ADDRESSABLE (var) = 1;
669 DECL_ALIGN (var) = TYPE_ALIGN (type);
671 return var;
674 /* Creates the gcov_fn_info RECORD_TYPE. */
676 static void
677 build_fn_info_type (tree type, unsigned counters, tree gcov_info_type)
679 tree ctr_info = lang_hooks.types.make_type (RECORD_TYPE);
680 tree field, fields;
681 tree array_type;
683 gcc_assert (counters);
685 /* ctr_info::num */
686 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
687 get_gcov_unsigned_t ());
688 fields = field;
690 /* ctr_info::values */
691 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
692 build_pointer_type (get_gcov_type ()));
693 DECL_CHAIN (field) = fields;
694 fields = field;
696 finish_builtin_struct (ctr_info, "__gcov_ctr_info", fields, NULL_TREE);
698 /* key */
699 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
700 build_pointer_type (build_qualified_type
701 (gcov_info_type, TYPE_QUAL_CONST)));
702 fields = field;
704 /* ident */
705 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
706 get_gcov_unsigned_t ());
707 DECL_CHAIN (field) = fields;
708 fields = field;
710 /* lineno_checksum */
711 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
712 get_gcov_unsigned_t ());
713 DECL_CHAIN (field) = fields;
714 fields = field;
716 /* cfg checksum */
717 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
718 get_gcov_unsigned_t ());
719 DECL_CHAIN (field) = fields;
720 fields = field;
722 array_type = build_index_type (size_int (counters - 1));
723 array_type = build_array_type (ctr_info, array_type);
725 /* counters */
726 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, array_type);
727 DECL_CHAIN (field) = fields;
728 fields = field;
730 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
733 /* Returns a CONSTRUCTOR for a gcov_fn_info. DATA is
734 the coverage data for the function and TYPE is the gcov_fn_info
735 RECORD_TYPE. KEY is the object file key. */
737 static tree
738 build_fn_info (const struct coverage_data *data, tree type, tree key)
740 tree fields = TYPE_FIELDS (type);
741 tree ctr_type;
742 unsigned ix;
743 VEC(constructor_elt,gc) *v1 = NULL;
744 VEC(constructor_elt,gc) *v2 = NULL;
746 /* key */
747 CONSTRUCTOR_APPEND_ELT (v1, fields,
748 build1 (ADDR_EXPR, TREE_TYPE (fields), key));
749 fields = DECL_CHAIN (fields);
751 /* ident */
752 CONSTRUCTOR_APPEND_ELT (v1, fields,
753 build_int_cstu (get_gcov_unsigned_t (),
754 data->ident));
755 fields = DECL_CHAIN (fields);
757 /* lineno_checksum */
758 CONSTRUCTOR_APPEND_ELT (v1, fields,
759 build_int_cstu (get_gcov_unsigned_t (),
760 data->lineno_checksum));
761 fields = DECL_CHAIN (fields);
763 /* cfg_checksum */
764 CONSTRUCTOR_APPEND_ELT (v1, fields,
765 build_int_cstu (get_gcov_unsigned_t (),
766 data->cfg_checksum));
767 fields = DECL_CHAIN (fields);
769 /* counters */
770 ctr_type = TREE_TYPE (TREE_TYPE (fields));
771 for (ix = 0; ix != GCOV_COUNTERS; ix++)
772 if (prg_ctr_mask & (1 << ix))
774 VEC(constructor_elt,gc) *ctr = NULL;
775 tree var = data->ctr_vars[ix];
776 unsigned count = 0;
778 if (var)
779 count
780 = tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var))), 0)
781 + 1;
783 CONSTRUCTOR_APPEND_ELT (ctr, TYPE_FIELDS (ctr_type),
784 build_int_cstu (get_gcov_unsigned_t (),
785 count));
787 if (var)
788 CONSTRUCTOR_APPEND_ELT (ctr, DECL_CHAIN (TYPE_FIELDS (ctr_type)),
789 build_fold_addr_expr (var));
791 CONSTRUCTOR_APPEND_ELT (v2, NULL, build_constructor (ctr_type, ctr));
794 CONSTRUCTOR_APPEND_ELT (v1, fields,
795 build_constructor (TREE_TYPE (fields), v2));
797 return build_constructor (type, v1);
800 /* Create gcov_info struct. TYPE is the incomplete RECORD_TYPE to be
801 completed, and FN_INFO_PTR_TYPE is a pointer to the function info type. */
803 static void
804 build_info_type (tree type, tree fn_info_ptr_type)
806 tree field, fields = NULL_TREE;
807 tree merge_fn_type;
809 /* Version ident */
810 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
811 get_gcov_unsigned_t ());
812 DECL_CHAIN (field) = fields;
813 fields = field;
815 /* next pointer */
816 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
817 build_pointer_type (build_qualified_type
818 (type, TYPE_QUAL_CONST)));
819 DECL_CHAIN (field) = fields;
820 fields = field;
822 /* stamp */
823 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
824 get_gcov_unsigned_t ());
825 DECL_CHAIN (field) = fields;
826 fields = field;
828 /* Filename */
829 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
830 build_pointer_type (build_qualified_type
831 (char_type_node, TYPE_QUAL_CONST)));
832 DECL_CHAIN (field) = fields;
833 fields = field;
835 /* merge fn array */
836 merge_fn_type
837 = build_function_type_list (void_type_node,
838 build_pointer_type (get_gcov_type ()),
839 get_gcov_unsigned_t (), NULL_TREE);
840 merge_fn_type
841 = build_array_type (build_pointer_type (merge_fn_type),
842 build_index_type (size_int (GCOV_COUNTERS - 1)));
843 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
844 merge_fn_type);
845 DECL_CHAIN (field) = fields;
846 fields = field;
848 /* n_functions */
849 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
850 get_gcov_unsigned_t ());
851 DECL_CHAIN (field) = fields;
852 fields = field;
854 /* function_info pointer pointer */
855 fn_info_ptr_type = build_pointer_type
856 (build_qualified_type (fn_info_ptr_type, TYPE_QUAL_CONST));
857 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
858 fn_info_ptr_type);
859 DECL_CHAIN (field) = fields;
860 fields = field;
862 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
865 /* Returns a CONSTRUCTOR for the gcov_info object. INFO_TYPE is the
866 gcov_info structure type, FN_ARY is the array of pointers to
867 function info objects. */
869 static tree
870 build_info (tree info_type, tree fn_ary)
872 tree info_fields = TYPE_FIELDS (info_type);
873 tree merge_fn_type, n_funcs;
874 unsigned ix;
875 tree filename_string;
876 int da_file_name_len;
877 VEC(constructor_elt,gc) *v1 = NULL;
878 VEC(constructor_elt,gc) *v2 = NULL;
880 /* Version ident */
881 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
882 build_int_cstu (TREE_TYPE (info_fields),
883 GCOV_VERSION));
884 info_fields = DECL_CHAIN (info_fields);
886 /* next -- NULL */
887 CONSTRUCTOR_APPEND_ELT (v1, info_fields, null_pointer_node);
888 info_fields = DECL_CHAIN (info_fields);
890 /* stamp */
891 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
892 build_int_cstu (TREE_TYPE (info_fields),
893 local_tick));
894 info_fields = DECL_CHAIN (info_fields);
896 /* Filename */
897 da_file_name_len = strlen (da_file_name);
898 filename_string = build_string (da_file_name_len + 1, da_file_name);
899 TREE_TYPE (filename_string) = build_array_type
900 (char_type_node, build_index_type (size_int (da_file_name_len)));
901 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
902 build1 (ADDR_EXPR, TREE_TYPE (info_fields),
903 filename_string));
904 info_fields = DECL_CHAIN (info_fields);
906 /* merge fn array -- NULL slots indicate unmeasured counters */
907 merge_fn_type = TREE_TYPE (TREE_TYPE (info_fields));
908 for (ix = 0; ix != GCOV_COUNTERS; ix++)
910 tree ptr = null_pointer_node;
912 if ((1u << ix) & prg_ctr_mask)
914 tree merge_fn = build_decl (BUILTINS_LOCATION,
915 FUNCTION_DECL,
916 get_identifier (ctr_merge_functions[ix]),
917 TREE_TYPE (merge_fn_type));
918 DECL_EXTERNAL (merge_fn) = 1;
919 TREE_PUBLIC (merge_fn) = 1;
920 DECL_ARTIFICIAL (merge_fn) = 1;
921 TREE_NOTHROW (merge_fn) = 1;
922 /* Initialize assembler name so we can stream out. */
923 DECL_ASSEMBLER_NAME (merge_fn);
924 ptr = build1 (ADDR_EXPR, merge_fn_type, merge_fn);
926 CONSTRUCTOR_APPEND_ELT (v2, NULL, ptr);
928 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
929 build_constructor (TREE_TYPE (info_fields), v2));
930 info_fields = DECL_CHAIN (info_fields);
932 /* n_functions */
933 n_funcs = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (fn_ary)));
934 n_funcs = fold_build2 (PLUS_EXPR, TREE_TYPE (info_fields),
935 n_funcs, size_one_node);
936 CONSTRUCTOR_APPEND_ELT (v1, info_fields, n_funcs);
937 info_fields = DECL_CHAIN (info_fields);
939 /* functions */
940 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
941 build1 (ADDR_EXPR, TREE_TYPE (info_fields), fn_ary));
942 info_fields = DECL_CHAIN (info_fields);
944 gcc_assert (!info_fields);
945 return build_constructor (info_type, v1);
948 /* Create the gcov_info types and object. Generate the constructor
949 function to call __gcov_init. Does not generate the initializer
950 for the object. Returns TRUE if coverage data is being emitted. */
952 static bool
953 coverage_obj_init (void)
955 tree gcov_info_type, ctor, stmt, init_fn;
956 unsigned n_counters = 0;
957 unsigned ix;
958 struct coverage_data *fn;
959 struct coverage_data **fn_prev;
960 char name_buf[32];
962 no_coverage = 1; /* Disable any further coverage. */
964 if (!prg_ctr_mask)
965 return false;
967 if (cgraph_dump_file)
968 fprintf (cgraph_dump_file, "Using data file %s\n", da_file_name);
970 /* Prune functions. */
971 for (fn_prev = &functions_head; (fn = *fn_prev);)
972 if (DECL_STRUCT_FUNCTION (fn->fn_decl))
973 fn_prev = &fn->next;
974 else
975 /* The function is not being emitted, remove from list. */
976 *fn_prev = fn->next;
978 for (ix = 0; ix != GCOV_COUNTERS; ix++)
979 if ((1u << ix) & prg_ctr_mask)
980 n_counters++;
982 /* Build the info and fn_info types. These are mutually recursive. */
983 gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
984 gcov_fn_info_type = lang_hooks.types.make_type (RECORD_TYPE);
985 gcov_fn_info_ptr_type = build_pointer_type
986 (build_qualified_type (gcov_fn_info_type, TYPE_QUAL_CONST));
987 build_fn_info_type (gcov_fn_info_type, n_counters, gcov_info_type);
988 build_info_type (gcov_info_type, gcov_fn_info_ptr_type);
990 /* Build the gcov info var, this is referred to in its own
991 initializer. */
992 gcov_info_var = build_decl (BUILTINS_LOCATION,
993 VAR_DECL, NULL_TREE, gcov_info_type);
994 TREE_STATIC (gcov_info_var) = 1;
995 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
996 DECL_NAME (gcov_info_var) = get_identifier (name_buf);
998 /* Build a decl for __gcov_init. */
999 init_fn = build_pointer_type (gcov_info_type);
1000 init_fn = build_function_type_list (void_type_node, init_fn, NULL);
1001 init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
1002 get_identifier ("__gcov_init"), init_fn);
1003 TREE_PUBLIC (init_fn) = 1;
1004 DECL_EXTERNAL (init_fn) = 1;
1005 DECL_ASSEMBLER_NAME (init_fn);
1007 /* Generate a call to __gcov_init(&gcov_info). */
1008 ctor = NULL;
1009 stmt = build_fold_addr_expr (gcov_info_var);
1010 stmt = build_call_expr (init_fn, 1, stmt);
1011 append_to_statement_list (stmt, &ctor);
1013 /* Generate a constructor to run it. */
1014 cgraph_build_static_cdtor ('I', ctor, DEFAULT_INIT_PRIORITY);
1016 return true;
1019 /* Generate the coverage function info for FN and DATA. Append a
1020 pointer to that object to CTOR and return the appended CTOR. */
1022 static VEC(constructor_elt,gc) *
1023 coverage_obj_fn (VEC(constructor_elt,gc) *ctor, tree fn,
1024 struct coverage_data const *data)
1026 tree init = build_fn_info (data, gcov_fn_info_type, gcov_info_var);
1027 tree var = build_var (fn, gcov_fn_info_type, -1);
1029 DECL_INITIAL (var) = init;
1030 varpool_finalize_decl (var);
1032 CONSTRUCTOR_APPEND_ELT (ctor, NULL,
1033 build1 (ADDR_EXPR, gcov_fn_info_ptr_type, var));
1034 return ctor;
1037 /* Finalize the coverage data. Generates the array of pointers to
1038 function objects from CTOR. Generate the gcov_info initializer. */
1040 static void
1041 coverage_obj_finish (VEC(constructor_elt,gc) *ctor)
1043 unsigned n_functions = VEC_length(constructor_elt, ctor);
1044 tree fn_info_ary_type = build_array_type
1045 (build_qualified_type (gcov_fn_info_ptr_type, TYPE_QUAL_CONST),
1046 build_index_type (size_int (n_functions - 1)));
1047 tree fn_info_ary = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE,
1048 fn_info_ary_type);
1049 char name_buf[32];
1051 TREE_STATIC (fn_info_ary) = 1;
1052 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 1);
1053 DECL_NAME (fn_info_ary) = get_identifier (name_buf);
1054 DECL_INITIAL (fn_info_ary) = build_constructor (fn_info_ary_type, ctor);
1055 varpool_finalize_decl (fn_info_ary);
1057 DECL_INITIAL (gcov_info_var)
1058 = build_info (TREE_TYPE (gcov_info_var), fn_info_ary);
1059 varpool_finalize_decl (gcov_info_var);
1062 /* Perform file-level initialization. Read in data file, generate name
1063 of graph file. */
1065 void
1066 coverage_init (const char *filename)
1068 int len = strlen (filename);
1069 int prefix_len = 0;
1071 if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
1072 profile_data_prefix = getpwd ();
1074 if (profile_data_prefix)
1075 prefix_len = strlen (profile_data_prefix);
1077 /* Name of da file. */
1078 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
1079 + prefix_len + 2);
1081 if (profile_data_prefix)
1083 memcpy (da_file_name, profile_data_prefix, prefix_len);
1084 da_file_name[prefix_len++] = '/';
1086 memcpy (da_file_name + prefix_len, filename, len);
1087 strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX);
1089 /* Name of bbg file. */
1090 if (flag_test_coverage && !flag_compare_debug)
1092 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1);
1093 memcpy (bbg_file_name, filename, len);
1094 strcpy (bbg_file_name + len, GCOV_NOTE_SUFFIX);
1096 if (!gcov_open (bbg_file_name, -1))
1098 error ("cannot open %s", bbg_file_name);
1099 bbg_file_name = NULL;
1101 else
1103 gcov_write_unsigned (GCOV_NOTE_MAGIC);
1104 gcov_write_unsigned (GCOV_VERSION);
1105 gcov_write_unsigned (local_tick);
1109 if (flag_branch_probabilities)
1110 read_counts_file ();
1113 /* Performs file-level cleanup. Close graph file, generate coverage
1114 variables and constructor. */
1116 void
1117 coverage_finish (void)
1119 if (bbg_file_name && gcov_close ())
1120 unlink (bbg_file_name);
1122 if (!local_tick)
1123 /* Only remove the da file, if we cannot stamp it. If we can
1124 stamp it, libgcov will DTRT. */
1125 unlink (da_file_name);
1127 if (coverage_obj_init ())
1129 VEC(constructor_elt,gc) *fn_ctor = NULL;
1130 struct coverage_data *fn;
1132 for (fn = functions_head; fn; fn = fn->next)
1133 fn_ctor = coverage_obj_fn (fn_ctor, fn->fn_decl, fn);
1134 coverage_obj_finish (fn_ctor);
1138 #include "gt-coverage.h"