PR sanitizer/59009
[official-gcc.git] / gcc / coverage.c
blob9b0fc8b3d1437c81d76bfaa5422a70d3196ea1bc
1 /* Read and write coverage files, and associated functionality.
2 Copyright (C) 1990-2013 Free Software Foundation, Inc.
3 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
4 based on some ideas from Dain Samples of UC Berkeley.
5 Further mangling by Bob Manson, Cygnus Support.
6 Further mangled by Nathan Sidwell, CodeSourcery
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
25 #define GCOV_LINKAGE
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
30 #include "tm.h"
31 #include "rtl.h"
32 #include "tree.h"
33 #include "flags.h"
34 #include "output.h"
35 #include "regs.h"
36 #include "expr.h"
37 #include "function.h"
38 #include "basic-block.h"
39 #include "toplev.h"
40 #include "tm_p.h"
41 #include "ggc.h"
42 #include "coverage.h"
43 #include "langhooks.h"
44 #include "hash-table.h"
45 #include "tree-iterator.h"
46 #include "context.h"
47 #include "pass_manager.h"
48 #include "tree-pass.h"
49 #include "cgraph.h"
50 #include "dumpfile.h"
51 #include "diagnostic-core.h"
52 #include "intl.h"
53 #include "filenames.h"
54 #include "target.h"
56 #include "gcov-io.h"
57 #include "gcov-io.c"
59 struct GTY((chain_next ("%h.next"))) coverage_data
61 struct coverage_data *next; /* next function */
62 unsigned ident; /* function ident */
63 unsigned lineno_checksum; /* function lineno checksum */
64 unsigned cfg_checksum; /* function cfg checksum */
65 tree fn_decl; /* the function decl */
66 tree ctr_vars[GCOV_COUNTERS]; /* counter variables. */
69 /* Counts information for a function. */
70 typedef struct counts_entry
72 /* We hash by */
73 unsigned ident;
74 unsigned ctr;
76 /* Store */
77 unsigned lineno_checksum;
78 unsigned cfg_checksum;
79 gcov_type *counts;
80 struct gcov_ctr_summary summary;
82 /* hash_table support. */
83 typedef counts_entry value_type;
84 typedef counts_entry compare_type;
85 static inline hashval_t hash (const value_type *);
86 static int equal (const value_type *, const compare_type *);
87 static void remove (value_type *);
88 } counts_entry_t;
90 static GTY(()) struct coverage_data *functions_head = 0;
91 static struct coverage_data **functions_tail = &functions_head;
92 static unsigned no_coverage = 0;
94 /* Cumulative counter information for whole program. */
95 static unsigned prg_ctr_mask; /* Mask of counter types generated. */
97 /* Counter information for current function. */
98 static unsigned fn_ctr_mask; /* Mask of counters used. */
99 static GTY(()) tree fn_v_ctrs[GCOV_COUNTERS]; /* counter variables. */
100 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated. */
101 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base. */
103 /* Coverage info VAR_DECL and function info type nodes. */
104 static GTY(()) tree gcov_info_var;
105 static GTY(()) tree gcov_fn_info_type;
106 static GTY(()) tree gcov_fn_info_ptr_type;
108 /* Name of the notes (gcno) output file. The "bbg" prefix is for
109 historical reasons, when the notes file contained only the
110 basic block graph notes.
111 If this is NULL we're not writing to the notes file. */
112 static char *bbg_file_name;
114 /* File stamp for notes file. */
115 static unsigned bbg_file_stamp;
117 /* Name of the count data (gcda) file. */
118 static char *da_file_name;
120 /* The names of merge functions for counters. */
121 static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
122 static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
124 /* Forward declarations. */
125 static void read_counts_file (void);
126 static tree build_var (tree, tree, int);
127 static void build_fn_info_type (tree, unsigned, tree);
128 static void build_info_type (tree, tree);
129 static tree build_fn_info (const struct coverage_data *, tree, tree);
130 static tree build_info (tree, tree);
131 static bool coverage_obj_init (void);
132 static vec<constructor_elt, va_gc> *coverage_obj_fn
133 (vec<constructor_elt, va_gc> *, tree, struct coverage_data const *);
134 static void coverage_obj_finish (vec<constructor_elt, va_gc> *);
136 /* Return the type node for gcov_type. */
138 tree
139 get_gcov_type (void)
141 enum machine_mode mode = smallest_mode_for_size (GCOV_TYPE_SIZE, MODE_INT);
142 return lang_hooks.types.type_for_mode (mode, false);
145 /* Return the type node for gcov_unsigned_t. */
147 static tree
148 get_gcov_unsigned_t (void)
150 enum machine_mode mode = smallest_mode_for_size (32, MODE_INT);
151 return lang_hooks.types.type_for_mode (mode, true);
154 inline hashval_t
155 counts_entry::hash (const value_type *entry)
157 return entry->ident * GCOV_COUNTERS + entry->ctr;
160 inline int
161 counts_entry::equal (const value_type *entry1,
162 const compare_type *entry2)
164 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
167 inline void
168 counts_entry::remove (value_type *entry)
170 free (entry->counts);
171 free (entry);
174 /* Hash table of count data. */
175 static hash_table <counts_entry> counts_hash;
177 /* Read in the counts file, if available. */
179 static void
180 read_counts_file (void)
182 gcov_unsigned_t fn_ident = 0;
183 struct gcov_summary summary;
184 unsigned new_summary = 1;
185 gcov_unsigned_t tag;
186 int is_error = 0;
187 unsigned lineno_checksum = 0;
188 unsigned cfg_checksum = 0;
190 if (!gcov_open (da_file_name, 1))
191 return;
193 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
195 warning (0, "%qs is not a gcov data file", da_file_name);
196 gcov_close ();
197 return;
199 else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
201 char v[4], e[4];
203 GCOV_UNSIGNED2STRING (v, tag);
204 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
206 warning (0, "%qs is version %q.*s, expected version %q.*s",
207 da_file_name, 4, v, 4, e);
208 gcov_close ();
209 return;
212 /* Read the stamp, used for creating a generation count. */
213 tag = gcov_read_unsigned ();
214 bbg_file_stamp = crc32_unsigned (bbg_file_stamp, tag);
216 counts_hash.create (10);
217 while ((tag = gcov_read_unsigned ()))
219 gcov_unsigned_t length;
220 gcov_position_t offset;
222 length = gcov_read_unsigned ();
223 offset = gcov_position ();
224 if (tag == GCOV_TAG_FUNCTION)
226 if (length)
228 fn_ident = gcov_read_unsigned ();
229 lineno_checksum = gcov_read_unsigned ();
230 cfg_checksum = gcov_read_unsigned ();
232 else
233 fn_ident = lineno_checksum = cfg_checksum = 0;
234 new_summary = 1;
236 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
238 struct gcov_summary sum;
239 unsigned ix;
241 if (new_summary)
242 memset (&summary, 0, sizeof (summary));
244 gcov_read_summary (&sum);
245 for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++)
247 summary.ctrs[ix].runs += sum.ctrs[ix].runs;
248 summary.ctrs[ix].sum_all += sum.ctrs[ix].sum_all;
249 if (summary.ctrs[ix].run_max < sum.ctrs[ix].run_max)
250 summary.ctrs[ix].run_max = sum.ctrs[ix].run_max;
251 summary.ctrs[ix].sum_max += sum.ctrs[ix].sum_max;
253 if (new_summary)
254 memcpy (summary.ctrs[GCOV_COUNTER_ARCS].histogram,
255 sum.ctrs[GCOV_COUNTER_ARCS].histogram,
256 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
257 else
258 gcov_histogram_merge (summary.ctrs[GCOV_COUNTER_ARCS].histogram,
259 sum.ctrs[GCOV_COUNTER_ARCS].histogram);
260 new_summary = 0;
262 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
264 counts_entry_t **slot, *entry, elt;
265 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
266 unsigned ix;
268 elt.ident = fn_ident;
269 elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
271 slot = counts_hash.find_slot (&elt, INSERT);
272 entry = *slot;
273 if (!entry)
275 *slot = entry = XCNEW (counts_entry_t);
276 entry->ident = fn_ident;
277 entry->ctr = elt.ctr;
278 entry->lineno_checksum = lineno_checksum;
279 entry->cfg_checksum = cfg_checksum;
280 if (elt.ctr < GCOV_COUNTERS_SUMMABLE)
281 entry->summary = summary.ctrs[elt.ctr];
282 entry->summary.num = n_counts;
283 entry->counts = XCNEWVEC (gcov_type, n_counts);
285 else if (entry->lineno_checksum != lineno_checksum
286 || entry->cfg_checksum != cfg_checksum)
288 error ("Profile data for function %u is corrupted", fn_ident);
289 error ("checksum is (%x,%x) instead of (%x,%x)",
290 entry->lineno_checksum, entry->cfg_checksum,
291 lineno_checksum, cfg_checksum);
292 counts_hash.dispose ();
293 break;
295 else if (entry->summary.num != n_counts)
297 error ("Profile data for function %u is corrupted", fn_ident);
298 error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
299 counts_hash.dispose ();
300 break;
302 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
304 error ("cannot merge separate %s counters for function %u",
305 ctr_names[elt.ctr], fn_ident);
306 goto skip_merge;
308 else
310 entry->summary.runs += summary.ctrs[elt.ctr].runs;
311 entry->summary.sum_all += summary.ctrs[elt.ctr].sum_all;
312 if (entry->summary.run_max < summary.ctrs[elt.ctr].run_max)
313 entry->summary.run_max = summary.ctrs[elt.ctr].run_max;
314 entry->summary.sum_max += summary.ctrs[elt.ctr].sum_max;
316 for (ix = 0; ix != n_counts; ix++)
317 entry->counts[ix] += gcov_read_counter ();
318 skip_merge:;
320 gcov_sync (offset, length);
321 if ((is_error = gcov_is_error ()))
323 error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted",
324 da_file_name);
325 counts_hash.dispose ();
326 break;
330 gcov_close ();
333 /* Returns the counters for a particular tag. */
335 gcov_type *
336 get_coverage_counts (unsigned counter, unsigned expected,
337 unsigned cfg_checksum, unsigned lineno_checksum,
338 const struct gcov_ctr_summary **summary)
340 counts_entry_t *entry, elt;
342 /* No hash table, no counts. */
343 if (!counts_hash.is_created ())
345 static int warned = 0;
347 if (!warned++ && dump_enabled_p ())
348 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
349 (flag_guess_branch_prob
350 ? "file %s not found, execution counts estimated\n"
351 : "file %s not found, execution counts assumed to "
352 "be zero\n"),
353 da_file_name);
354 return NULL;
357 elt.ident = current_function_funcdef_no + 1;
358 elt.ctr = counter;
359 entry = counts_hash.find (&elt);
360 if (!entry || !entry->summary.num)
361 /* The function was not emitted, or is weak and not chosen in the
362 final executable. Silently fail, because there's nothing we
363 can do about it. */
364 return NULL;
366 if (entry->cfg_checksum != cfg_checksum
367 || entry->summary.num != expected)
369 static int warned = 0;
370 bool warning_printed = false;
371 tree id = DECL_ASSEMBLER_NAME (current_function_decl);
373 warning_printed =
374 warning_at (input_location, OPT_Wcoverage_mismatch,
375 "the control flow of function %qE does not match "
376 "its profile data (counter %qs)", id, ctr_names[counter]);
377 if (warning_printed && dump_enabled_p ())
379 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
380 "use -Wno-error=coverage-mismatch to tolerate "
381 "the mismatch but performance may drop if the "
382 "function is hot\n");
384 if (!seen_error ()
385 && !warned++)
387 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
388 "coverage mismatch ignored\n");
389 dump_printf (MSG_OPTIMIZED_LOCATIONS,
390 flag_guess_branch_prob
391 ? G_("execution counts estimated\n")
392 : G_("execution counts assumed to be zero\n"));
393 if (!flag_guess_branch_prob)
394 dump_printf (MSG_OPTIMIZED_LOCATIONS,
395 "this can result in poorly optimized code\n");
399 return NULL;
401 else if (entry->lineno_checksum != lineno_checksum)
403 warning (0, "source locations for function %qE have changed,"
404 " the profile data may be out of date",
405 DECL_ASSEMBLER_NAME (current_function_decl));
408 if (summary)
409 *summary = &entry->summary;
411 return entry->counts;
414 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
415 allocation succeeded. */
418 coverage_counter_alloc (unsigned counter, unsigned num)
420 if (no_coverage)
421 return 0;
423 if (!num)
424 return 1;
426 if (!fn_v_ctrs[counter])
428 tree array_type = build_array_type (get_gcov_type (), NULL_TREE);
430 fn_v_ctrs[counter]
431 = build_var (current_function_decl, array_type, counter);
434 fn_b_ctrs[counter] = fn_n_ctrs[counter];
435 fn_n_ctrs[counter] += num;
437 fn_ctr_mask |= 1 << counter;
438 return 1;
441 /* Generate a tree to access COUNTER NO. */
443 tree
444 tree_coverage_counter_ref (unsigned counter, unsigned no)
446 tree gcov_type_node = get_gcov_type ();
448 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
450 no += fn_b_ctrs[counter];
452 /* "no" here is an array index, scaled to bytes later. */
453 return build4 (ARRAY_REF, gcov_type_node, fn_v_ctrs[counter],
454 build_int_cst (integer_type_node, no), NULL, NULL);
457 /* Generate a tree to access the address of COUNTER NO. */
459 tree
460 tree_coverage_counter_addr (unsigned counter, unsigned no)
462 tree gcov_type_node = get_gcov_type ();
464 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
465 no += fn_b_ctrs[counter];
467 /* "no" here is an array index, scaled to bytes later. */
468 return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node,
469 fn_v_ctrs[counter],
470 build_int_cst (integer_type_node, no),
471 NULL, NULL));
475 /* Generate a checksum for a string. CHKSUM is the current
476 checksum. */
478 static unsigned
479 coverage_checksum_string (unsigned chksum, const char *string)
481 int i;
482 char *dup = NULL;
484 /* Look for everything that looks if it were produced by
485 get_file_function_name and zero out the second part
486 that may result from flag_random_seed. This is not critical
487 as the checksums are used only for sanity checking. */
488 for (i = 0; string[i]; i++)
490 int offset = 0;
491 if (!strncmp (string + i, "_GLOBAL__N_", 11))
492 offset = 11;
493 if (!strncmp (string + i, "_GLOBAL__", 9))
494 offset = 9;
496 /* C++ namespaces do have scheme:
497 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
498 since filename might contain extra underscores there seems
499 to be no better chance then walk all possible offsets looking
500 for magicnumber. */
501 if (offset)
503 for (i = i + offset; string[i]; i++)
504 if (string[i]=='_')
506 int y;
508 for (y = 1; y < 9; y++)
509 if (!(string[i + y] >= '0' && string[i + y] <= '9')
510 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
511 break;
512 if (y != 9 || string[i + 9] != '_')
513 continue;
514 for (y = 10; y < 18; y++)
515 if (!(string[i + y] >= '0' && string[i + y] <= '9')
516 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
517 break;
518 if (y != 18)
519 continue;
520 if (!dup)
521 string = dup = xstrdup (string);
522 for (y = 10; y < 18; y++)
523 dup[i + y] = '0';
525 break;
529 chksum = crc32_string (chksum, string);
530 free (dup);
532 return chksum;
535 /* Compute checksum for the current function. We generate a CRC32. */
537 unsigned
538 coverage_compute_lineno_checksum (void)
540 expanded_location xloc
541 = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
542 unsigned chksum = xloc.line;
544 chksum = coverage_checksum_string (chksum, xloc.file);
545 chksum = coverage_checksum_string
546 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
548 return chksum;
551 /* Compute profile ID. This is better to be unique in whole program. */
553 unsigned
554 coverage_compute_profile_id (struct cgraph_node *n)
556 expanded_location xloc
557 = expand_location (DECL_SOURCE_LOCATION (n->decl));
558 unsigned chksum = xloc.line;
560 chksum = coverage_checksum_string (chksum, xloc.file);
561 chksum = coverage_checksum_string
562 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl)));
563 if (first_global_object_name)
564 chksum = coverage_checksum_string
565 (chksum, first_global_object_name);
566 chksum = coverage_checksum_string
567 (chksum, aux_base_name);
569 /* Non-negative integers are hopefully small enough to fit in all targets. */
570 return chksum & 0x7fffffff;
573 /* Compute cfg checksum for the current function.
574 The checksum is calculated carefully so that
575 source code changes that doesn't affect the control flow graph
576 won't change the checksum.
577 This is to make the profile data useable across source code change.
578 The downside of this is that the compiler may use potentially
579 wrong profile data - that the source code change has non-trivial impact
580 on the validity of profile data (e.g. the reversed condition)
581 but the compiler won't detect the change and use the wrong profile data. */
583 unsigned
584 coverage_compute_cfg_checksum (void)
586 basic_block bb;
587 unsigned chksum = n_basic_blocks;
589 FOR_EACH_BB (bb)
591 edge e;
592 edge_iterator ei;
593 chksum = crc32_byte (chksum, bb->index);
594 FOR_EACH_EDGE (e, ei, bb->succs)
596 chksum = crc32_byte (chksum, e->dest->index);
600 return chksum;
603 /* Begin output to the notes file for the current function.
604 Writes the function header. Returns nonzero if data should be output. */
607 coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
609 expanded_location xloc;
610 unsigned long offset;
612 /* We don't need to output .gcno file unless we're under -ftest-coverage
613 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
614 if (no_coverage || !bbg_file_name)
615 return 0;
617 xloc = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
619 /* Announce function */
620 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
621 gcov_write_unsigned (current_function_funcdef_no + 1);
622 gcov_write_unsigned (lineno_checksum);
623 gcov_write_unsigned (cfg_checksum);
624 gcov_write_string (IDENTIFIER_POINTER
625 (DECL_ASSEMBLER_NAME (current_function_decl)));
626 gcov_write_string (xloc.file);
627 gcov_write_unsigned (xloc.line);
628 gcov_write_length (offset);
630 return !gcov_is_error ();
633 /* Finish coverage data for the current function. Verify no output
634 error has occurred. Save function coverage counts. */
636 void
637 coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum)
639 unsigned i;
641 if (bbg_file_name && gcov_is_error ())
643 warning (0, "error writing %qs", bbg_file_name);
644 unlink (bbg_file_name);
645 bbg_file_name = NULL;
648 if (fn_ctr_mask)
650 struct coverage_data *item = 0;
652 /* If the function is extern (i.e. extern inline), then we won't
653 be outputting it, so don't chain it onto the function
654 list. */
655 if (!DECL_EXTERNAL (current_function_decl))
657 item = ggc_alloc_coverage_data ();
659 item->ident = current_function_funcdef_no + 1;
660 item->lineno_checksum = lineno_checksum;
661 item->cfg_checksum = cfg_checksum;
663 item->fn_decl = current_function_decl;
664 item->next = 0;
665 *functions_tail = item;
666 functions_tail = &item->next;
669 for (i = 0; i != GCOV_COUNTERS; i++)
671 tree var = fn_v_ctrs[i];
673 if (item)
674 item->ctr_vars[i] = var;
675 if (var)
677 tree array_type = build_index_type (size_int (fn_n_ctrs[i] - 1));
678 array_type = build_array_type (get_gcov_type (), array_type);
679 TREE_TYPE (var) = array_type;
680 DECL_SIZE (var) = TYPE_SIZE (array_type);
681 DECL_SIZE_UNIT (var) = TYPE_SIZE_UNIT (array_type);
682 varpool_finalize_decl (var);
685 fn_b_ctrs[i] = fn_n_ctrs[i] = 0;
686 fn_v_ctrs[i] = NULL_TREE;
688 prg_ctr_mask |= fn_ctr_mask;
689 fn_ctr_mask = 0;
693 /* Build a coverage variable of TYPE for function FN_DECL. If COUNTER
694 >= 0 it is a counter array, otherwise it is the function structure. */
696 static tree
697 build_var (tree fn_decl, tree type, int counter)
699 tree var = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, type);
700 const char *fn_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn_decl));
701 char *buf;
702 size_t fn_name_len, len;
704 fn_name = targetm.strip_name_encoding (fn_name);
705 fn_name_len = strlen (fn_name);
706 buf = XALLOCAVEC (char, fn_name_len + 8 + sizeof (int) * 3);
708 if (counter < 0)
709 strcpy (buf, "__gcov__");
710 else
711 sprintf (buf, "__gcov%u_", counter);
712 len = strlen (buf);
713 #ifndef NO_DOT_IN_LABEL
714 buf[len - 1] = '.';
715 #elif !defined NO_DOLLAR_IN_LABEL
716 buf[len - 1] = '$';
717 #endif
718 memcpy (buf + len, fn_name, fn_name_len + 1);
719 DECL_NAME (var) = get_identifier (buf);
720 TREE_STATIC (var) = 1;
721 TREE_ADDRESSABLE (var) = 1;
722 DECL_ALIGN (var) = TYPE_ALIGN (type);
724 return var;
727 /* Creates the gcov_fn_info RECORD_TYPE. */
729 static void
730 build_fn_info_type (tree type, unsigned counters, tree gcov_info_type)
732 tree ctr_info = lang_hooks.types.make_type (RECORD_TYPE);
733 tree field, fields;
734 tree array_type;
736 gcc_assert (counters);
738 /* ctr_info::num */
739 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
740 get_gcov_unsigned_t ());
741 fields = field;
743 /* ctr_info::values */
744 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
745 build_pointer_type (get_gcov_type ()));
746 DECL_CHAIN (field) = fields;
747 fields = field;
749 finish_builtin_struct (ctr_info, "__gcov_ctr_info", fields, NULL_TREE);
751 /* key */
752 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
753 build_pointer_type (build_qualified_type
754 (gcov_info_type, TYPE_QUAL_CONST)));
755 fields = field;
757 /* ident */
758 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
759 get_gcov_unsigned_t ());
760 DECL_CHAIN (field) = fields;
761 fields = field;
763 /* lineno_checksum */
764 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
765 get_gcov_unsigned_t ());
766 DECL_CHAIN (field) = fields;
767 fields = field;
769 /* cfg checksum */
770 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
771 get_gcov_unsigned_t ());
772 DECL_CHAIN (field) = fields;
773 fields = field;
775 array_type = build_index_type (size_int (counters - 1));
776 array_type = build_array_type (ctr_info, array_type);
778 /* counters */
779 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, array_type);
780 DECL_CHAIN (field) = fields;
781 fields = field;
783 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
786 /* Returns a CONSTRUCTOR for a gcov_fn_info. DATA is
787 the coverage data for the function and TYPE is the gcov_fn_info
788 RECORD_TYPE. KEY is the object file key. */
790 static tree
791 build_fn_info (const struct coverage_data *data, tree type, tree key)
793 tree fields = TYPE_FIELDS (type);
794 tree ctr_type;
795 unsigned ix;
796 vec<constructor_elt, va_gc> *v1 = NULL;
797 vec<constructor_elt, va_gc> *v2 = NULL;
799 /* key */
800 CONSTRUCTOR_APPEND_ELT (v1, fields,
801 build1 (ADDR_EXPR, TREE_TYPE (fields), key));
802 fields = DECL_CHAIN (fields);
804 /* ident */
805 CONSTRUCTOR_APPEND_ELT (v1, fields,
806 build_int_cstu (get_gcov_unsigned_t (),
807 data->ident));
808 fields = DECL_CHAIN (fields);
810 /* lineno_checksum */
811 CONSTRUCTOR_APPEND_ELT (v1, fields,
812 build_int_cstu (get_gcov_unsigned_t (),
813 data->lineno_checksum));
814 fields = DECL_CHAIN (fields);
816 /* cfg_checksum */
817 CONSTRUCTOR_APPEND_ELT (v1, fields,
818 build_int_cstu (get_gcov_unsigned_t (),
819 data->cfg_checksum));
820 fields = DECL_CHAIN (fields);
822 /* counters */
823 ctr_type = TREE_TYPE (TREE_TYPE (fields));
824 for (ix = 0; ix != GCOV_COUNTERS; ix++)
825 if (prg_ctr_mask & (1 << ix))
827 vec<constructor_elt, va_gc> *ctr = NULL;
828 tree var = data->ctr_vars[ix];
829 unsigned count = 0;
831 if (var)
832 count
833 = tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var))), 0)
834 + 1;
836 CONSTRUCTOR_APPEND_ELT (ctr, TYPE_FIELDS (ctr_type),
837 build_int_cstu (get_gcov_unsigned_t (),
838 count));
840 if (var)
841 CONSTRUCTOR_APPEND_ELT (ctr, DECL_CHAIN (TYPE_FIELDS (ctr_type)),
842 build_fold_addr_expr (var));
844 CONSTRUCTOR_APPEND_ELT (v2, NULL, build_constructor (ctr_type, ctr));
847 CONSTRUCTOR_APPEND_ELT (v1, fields,
848 build_constructor (TREE_TYPE (fields), v2));
850 return build_constructor (type, v1);
853 /* Create gcov_info struct. TYPE is the incomplete RECORD_TYPE to be
854 completed, and FN_INFO_PTR_TYPE is a pointer to the function info type. */
856 static void
857 build_info_type (tree type, tree fn_info_ptr_type)
859 tree field, fields = NULL_TREE;
860 tree merge_fn_type;
862 /* Version ident */
863 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
864 get_gcov_unsigned_t ());
865 DECL_CHAIN (field) = fields;
866 fields = field;
868 /* next pointer */
869 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
870 build_pointer_type (build_qualified_type
871 (type, TYPE_QUAL_CONST)));
872 DECL_CHAIN (field) = fields;
873 fields = field;
875 /* stamp */
876 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
877 get_gcov_unsigned_t ());
878 DECL_CHAIN (field) = fields;
879 fields = field;
881 /* Filename */
882 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
883 build_pointer_type (build_qualified_type
884 (char_type_node, TYPE_QUAL_CONST)));
885 DECL_CHAIN (field) = fields;
886 fields = field;
888 /* merge fn array */
889 merge_fn_type
890 = build_function_type_list (void_type_node,
891 build_pointer_type (get_gcov_type ()),
892 get_gcov_unsigned_t (), NULL_TREE);
893 merge_fn_type
894 = build_array_type (build_pointer_type (merge_fn_type),
895 build_index_type (size_int (GCOV_COUNTERS - 1)));
896 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
897 merge_fn_type);
898 DECL_CHAIN (field) = fields;
899 fields = field;
901 /* n_functions */
902 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
903 get_gcov_unsigned_t ());
904 DECL_CHAIN (field) = fields;
905 fields = field;
907 /* function_info pointer pointer */
908 fn_info_ptr_type = build_pointer_type
909 (build_qualified_type (fn_info_ptr_type, TYPE_QUAL_CONST));
910 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
911 fn_info_ptr_type);
912 DECL_CHAIN (field) = fields;
913 fields = field;
915 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
918 /* Returns a CONSTRUCTOR for the gcov_info object. INFO_TYPE is the
919 gcov_info structure type, FN_ARY is the array of pointers to
920 function info objects. */
922 static tree
923 build_info (tree info_type, tree fn_ary)
925 tree info_fields = TYPE_FIELDS (info_type);
926 tree merge_fn_type, n_funcs;
927 unsigned ix;
928 tree filename_string;
929 int da_file_name_len;
930 vec<constructor_elt, va_gc> *v1 = NULL;
931 vec<constructor_elt, va_gc> *v2 = NULL;
933 /* Version ident */
934 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
935 build_int_cstu (TREE_TYPE (info_fields),
936 GCOV_VERSION));
937 info_fields = DECL_CHAIN (info_fields);
939 /* next -- NULL */
940 CONSTRUCTOR_APPEND_ELT (v1, info_fields, null_pointer_node);
941 info_fields = DECL_CHAIN (info_fields);
943 /* stamp */
944 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
945 build_int_cstu (TREE_TYPE (info_fields),
946 bbg_file_stamp));
947 info_fields = DECL_CHAIN (info_fields);
949 /* Filename */
950 da_file_name_len = strlen (da_file_name);
951 filename_string = build_string (da_file_name_len + 1, da_file_name);
952 TREE_TYPE (filename_string) = build_array_type
953 (char_type_node, build_index_type (size_int (da_file_name_len)));
954 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
955 build1 (ADDR_EXPR, TREE_TYPE (info_fields),
956 filename_string));
957 info_fields = DECL_CHAIN (info_fields);
959 /* merge fn array -- NULL slots indicate unmeasured counters */
960 merge_fn_type = TREE_TYPE (TREE_TYPE (info_fields));
961 for (ix = 0; ix != GCOV_COUNTERS; ix++)
963 tree ptr = null_pointer_node;
965 if ((1u << ix) & prg_ctr_mask)
967 tree merge_fn = build_decl (BUILTINS_LOCATION,
968 FUNCTION_DECL,
969 get_identifier (ctr_merge_functions[ix]),
970 TREE_TYPE (merge_fn_type));
971 DECL_EXTERNAL (merge_fn) = 1;
972 TREE_PUBLIC (merge_fn) = 1;
973 DECL_ARTIFICIAL (merge_fn) = 1;
974 TREE_NOTHROW (merge_fn) = 1;
975 /* Initialize assembler name so we can stream out. */
976 DECL_ASSEMBLER_NAME (merge_fn);
977 ptr = build1 (ADDR_EXPR, merge_fn_type, merge_fn);
979 CONSTRUCTOR_APPEND_ELT (v2, NULL, ptr);
981 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
982 build_constructor (TREE_TYPE (info_fields), v2));
983 info_fields = DECL_CHAIN (info_fields);
985 /* n_functions */
986 n_funcs = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (fn_ary)));
987 n_funcs = fold_build2 (PLUS_EXPR, TREE_TYPE (info_fields),
988 n_funcs, size_one_node);
989 CONSTRUCTOR_APPEND_ELT (v1, info_fields, n_funcs);
990 info_fields = DECL_CHAIN (info_fields);
992 /* functions */
993 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
994 build1 (ADDR_EXPR, TREE_TYPE (info_fields), fn_ary));
995 info_fields = DECL_CHAIN (info_fields);
997 gcc_assert (!info_fields);
998 return build_constructor (info_type, v1);
1001 /* Generate the constructor function to call __gcov_init. */
1003 static void
1004 build_init_ctor (tree gcov_info_type)
1006 tree ctor, stmt, init_fn;
1008 /* Build a decl for __gcov_init. */
1009 init_fn = build_pointer_type (gcov_info_type);
1010 init_fn = build_function_type_list (void_type_node, init_fn, NULL);
1011 init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
1012 get_identifier ("__gcov_init"), init_fn);
1013 TREE_PUBLIC (init_fn) = 1;
1014 DECL_EXTERNAL (init_fn) = 1;
1015 DECL_ASSEMBLER_NAME (init_fn);
1017 /* Generate a call to __gcov_init(&gcov_info). */
1018 ctor = NULL;
1019 stmt = build_fold_addr_expr (gcov_info_var);
1020 stmt = build_call_expr (init_fn, 1, stmt);
1021 append_to_statement_list (stmt, &ctor);
1023 /* Generate a constructor to run it. */
1024 cgraph_build_static_cdtor ('I', ctor, DEFAULT_INIT_PRIORITY);
1027 /* Create the gcov_info types and object. Generate the constructor
1028 function to call __gcov_init. Does not generate the initializer
1029 for the object. Returns TRUE if coverage data is being emitted. */
1031 static bool
1032 coverage_obj_init (void)
1034 tree gcov_info_type;
1035 unsigned n_counters = 0;
1036 unsigned ix;
1037 struct coverage_data *fn;
1038 struct coverage_data **fn_prev;
1039 char name_buf[32];
1041 no_coverage = 1; /* Disable any further coverage. */
1043 if (!prg_ctr_mask)
1044 return false;
1046 if (cgraph_dump_file)
1047 fprintf (cgraph_dump_file, "Using data file %s\n", da_file_name);
1049 /* Prune functions. */
1050 for (fn_prev = &functions_head; (fn = *fn_prev);)
1051 if (DECL_STRUCT_FUNCTION (fn->fn_decl))
1052 fn_prev = &fn->next;
1053 else
1054 /* The function is not being emitted, remove from list. */
1055 *fn_prev = fn->next;
1057 if (functions_head == NULL)
1058 return false;
1060 for (ix = 0; ix != GCOV_COUNTERS; ix++)
1061 if ((1u << ix) & prg_ctr_mask)
1062 n_counters++;
1064 /* Build the info and fn_info types. These are mutually recursive. */
1065 gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1066 gcov_fn_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1067 gcov_fn_info_ptr_type = build_pointer_type
1068 (build_qualified_type (gcov_fn_info_type, TYPE_QUAL_CONST));
1069 build_fn_info_type (gcov_fn_info_type, n_counters, gcov_info_type);
1070 build_info_type (gcov_info_type, gcov_fn_info_ptr_type);
1072 /* Build the gcov info var, this is referred to in its own
1073 initializer. */
1074 gcov_info_var = build_decl (BUILTINS_LOCATION,
1075 VAR_DECL, NULL_TREE, gcov_info_type);
1076 TREE_STATIC (gcov_info_var) = 1;
1077 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
1078 DECL_NAME (gcov_info_var) = get_identifier (name_buf);
1080 build_init_ctor (gcov_info_type);
1082 return true;
1085 /* Generate the coverage function info for FN and DATA. Append a
1086 pointer to that object to CTOR and return the appended CTOR. */
1088 static vec<constructor_elt, va_gc> *
1089 coverage_obj_fn (vec<constructor_elt, va_gc> *ctor, tree fn,
1090 struct coverage_data const *data)
1092 tree init = build_fn_info (data, gcov_fn_info_type, gcov_info_var);
1093 tree var = build_var (fn, gcov_fn_info_type, -1);
1095 DECL_INITIAL (var) = init;
1096 varpool_finalize_decl (var);
1098 CONSTRUCTOR_APPEND_ELT (ctor, NULL,
1099 build1 (ADDR_EXPR, gcov_fn_info_ptr_type, var));
1100 return ctor;
1103 /* Finalize the coverage data. Generates the array of pointers to
1104 function objects from CTOR. Generate the gcov_info initializer. */
1106 static void
1107 coverage_obj_finish (vec<constructor_elt, va_gc> *ctor)
1109 unsigned n_functions = vec_safe_length (ctor);
1110 tree fn_info_ary_type = build_array_type
1111 (build_qualified_type (gcov_fn_info_ptr_type, TYPE_QUAL_CONST),
1112 build_index_type (size_int (n_functions - 1)));
1113 tree fn_info_ary = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE,
1114 fn_info_ary_type);
1115 char name_buf[32];
1117 TREE_STATIC (fn_info_ary) = 1;
1118 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 1);
1119 DECL_NAME (fn_info_ary) = get_identifier (name_buf);
1120 DECL_INITIAL (fn_info_ary) = build_constructor (fn_info_ary_type, ctor);
1121 varpool_finalize_decl (fn_info_ary);
1123 DECL_INITIAL (gcov_info_var)
1124 = build_info (TREE_TYPE (gcov_info_var), fn_info_ary);
1125 varpool_finalize_decl (gcov_info_var);
1128 /* Perform file-level initialization. Read in data file, generate name
1129 of notes file. */
1131 void
1132 coverage_init (const char *filename)
1134 int len = strlen (filename);
1135 int prefix_len = 0;
1137 /* Since coverage_init is invoked very early, before the pass
1138 manager, we need to set up the dumping explicitly. This is
1139 similar to the handling in finish_optimization_passes. */
1140 int profile_pass_num =
1141 g->get_passes ()->get_pass_profile ()->static_pass_number;
1142 g->get_dumps ()->dump_start (profile_pass_num, NULL);
1144 if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
1145 profile_data_prefix = getpwd ();
1147 if (profile_data_prefix)
1148 prefix_len = strlen (profile_data_prefix);
1150 /* Name of da file. */
1151 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
1152 + prefix_len + 2);
1154 if (profile_data_prefix)
1156 memcpy (da_file_name, profile_data_prefix, prefix_len);
1157 da_file_name[prefix_len++] = '/';
1159 memcpy (da_file_name + prefix_len, filename, len);
1160 strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX);
1162 bbg_file_stamp = local_tick;
1164 if (flag_branch_probabilities)
1165 read_counts_file ();
1167 /* Name of bbg file. */
1168 if (flag_test_coverage && !flag_compare_debug)
1170 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1);
1171 memcpy (bbg_file_name, filename, len);
1172 strcpy (bbg_file_name + len, GCOV_NOTE_SUFFIX);
1174 if (!gcov_open (bbg_file_name, -1))
1176 error ("cannot open %s", bbg_file_name);
1177 bbg_file_name = NULL;
1179 else
1181 gcov_write_unsigned (GCOV_NOTE_MAGIC);
1182 gcov_write_unsigned (GCOV_VERSION);
1183 gcov_write_unsigned (bbg_file_stamp);
1187 g->get_dumps ()->dump_finish (profile_pass_num);
1190 /* Performs file-level cleanup. Close notes file, generate coverage
1191 variables and constructor. */
1193 void
1194 coverage_finish (void)
1196 if (bbg_file_name && gcov_close ())
1197 unlink (bbg_file_name);
1199 if (!flag_branch_probabilities && flag_test_coverage
1200 && (!local_tick || local_tick == (unsigned)-1))
1201 /* Only remove the da file, if we're emitting coverage code and
1202 cannot uniquely stamp it. If we can stamp it, libgcov will DTRT. */
1203 unlink (da_file_name);
1205 if (coverage_obj_init ())
1207 vec<constructor_elt, va_gc> *fn_ctor = NULL;
1208 struct coverage_data *fn;
1210 for (fn = functions_head; fn; fn = fn->next)
1211 fn_ctor = coverage_obj_fn (fn_ctor, fn->fn_decl, fn);
1212 coverage_obj_finish (fn_ctor);
1215 XDELETEVEC (da_file_name);
1216 da_file_name = NULL;
1219 #include "gt-coverage.h"