2016-07-28 Steven G. Kargl <kargl@gcc.gnu.org>
[official-gcc.git] / gcc / coverage.c
blobd4d371ecd6d403b4407946619e61628a18024ad9
1 /* Read and write coverage files, and associated functionality.
2 Copyright (C) 1990-2016 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 "backend.h"
31 #include "target.h"
32 #include "rtl.h"
33 #include "tree.h"
34 #include "tree-pass.h"
35 #include "tm_p.h"
36 #include "stringpool.h"
37 #include "cgraph.h"
38 #include "coverage.h"
39 #include "diagnostic-core.h"
40 #include "fold-const.h"
41 #include "stor-layout.h"
42 #include "output.h"
43 #include "toplev.h"
44 #include "langhooks.h"
45 #include "tree-iterator.h"
46 #include "context.h"
47 #include "pass_manager.h"
48 #include "intl.h"
49 #include "params.h"
50 #include "auto-profile.h"
52 #include "gcov-io.c"
54 struct GTY((chain_next ("%h.next"))) coverage_data
56 struct coverage_data *next; /* next function */
57 unsigned ident; /* function ident */
58 unsigned lineno_checksum; /* function lineno checksum */
59 unsigned cfg_checksum; /* function cfg checksum */
60 tree fn_decl; /* the function decl */
61 tree ctr_vars[GCOV_COUNTERS]; /* counter variables. */
64 /* Counts information for a function. */
65 struct counts_entry : pointer_hash <counts_entry>
67 /* We hash by */
68 unsigned ident;
69 unsigned ctr;
71 /* Store */
72 unsigned lineno_checksum;
73 unsigned cfg_checksum;
74 gcov_type *counts;
75 struct gcov_ctr_summary summary;
77 /* hash_table support. */
78 static inline hashval_t hash (const counts_entry *);
79 static int equal (const counts_entry *, const counts_entry *);
80 static void remove (counts_entry *);
83 static GTY(()) struct coverage_data *functions_head = 0;
84 static struct coverage_data **functions_tail = &functions_head;
85 static unsigned no_coverage = 0;
87 /* Cumulative counter information for whole program. */
88 static unsigned prg_ctr_mask; /* Mask of counter types generated. */
90 /* Counter information for current function. */
91 static unsigned fn_ctr_mask; /* Mask of counters used. */
92 static GTY(()) tree fn_v_ctrs[GCOV_COUNTERS]; /* counter variables. */
93 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated. */
94 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base. */
96 /* Coverage info VAR_DECL and function info type nodes. */
97 static GTY(()) tree gcov_info_var;
98 static GTY(()) tree gcov_fn_info_type;
99 static GTY(()) tree gcov_fn_info_ptr_type;
101 /* Name of the notes (gcno) output file. The "bbg" prefix is for
102 historical reasons, when the notes file contained only the
103 basic block graph notes.
104 If this is NULL we're not writing to the notes file. */
105 static char *bbg_file_name;
107 /* File stamp for notes file. */
108 static unsigned bbg_file_stamp;
110 /* Name of the count data (gcda) file. */
111 static char *da_file_name;
113 /* The names of merge functions for counters. */
114 #define STR(str) #str
115 #define DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) STR(__gcov_merge ## FN_TYPE),
116 static const char *const ctr_merge_functions[GCOV_COUNTERS] = {
117 #include "gcov-counter.def"
119 #undef DEF_GCOV_COUNTER
120 #undef STR
122 #define DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) NAME,
123 static const char *const ctr_names[GCOV_COUNTERS] = {
124 #include "gcov-counter.def"
126 #undef DEF_GCOV_COUNTER
128 /* Forward declarations. */
129 static void read_counts_file (void);
130 static tree build_var (tree, tree, int);
131 static void build_fn_info_type (tree, unsigned, tree);
132 static void build_info_type (tree, tree);
133 static tree build_fn_info (const struct coverage_data *, tree, tree);
134 static tree build_info (tree, tree);
135 static bool coverage_obj_init (void);
136 static vec<constructor_elt, va_gc> *coverage_obj_fn
137 (vec<constructor_elt, va_gc> *, tree, struct coverage_data const *);
138 static void coverage_obj_finish (vec<constructor_elt, va_gc> *);
140 /* Return the type node for gcov_type. */
142 tree
143 get_gcov_type (void)
145 machine_mode mode = smallest_mode_for_size (GCOV_TYPE_SIZE, MODE_INT);
146 return lang_hooks.types.type_for_mode (mode, false);
149 /* Return the type node for gcov_unsigned_t. */
151 static tree
152 get_gcov_unsigned_t (void)
154 machine_mode mode = smallest_mode_for_size (32, MODE_INT);
155 return lang_hooks.types.type_for_mode (mode, true);
158 inline hashval_t
159 counts_entry::hash (const counts_entry *entry)
161 return entry->ident * GCOV_COUNTERS + entry->ctr;
164 inline int
165 counts_entry::equal (const counts_entry *entry1, const counts_entry *entry2)
167 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
170 inline void
171 counts_entry::remove (counts_entry *entry)
173 free (entry->counts);
174 free (entry);
177 /* Hash table of count data. */
178 static hash_table<counts_entry> *counts_hash;
180 /* Read in the counts file, if available. */
182 static void
183 read_counts_file (void)
185 gcov_unsigned_t fn_ident = 0;
186 struct gcov_summary summary;
187 unsigned new_summary = 1;
188 gcov_unsigned_t tag;
189 int is_error = 0;
190 unsigned lineno_checksum = 0;
191 unsigned cfg_checksum = 0;
193 if (!gcov_open (da_file_name, 1))
194 return;
196 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
198 warning (0, "%qs is not a gcov data file", da_file_name);
199 gcov_close ();
200 return;
202 else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
204 char v[4], e[4];
206 GCOV_UNSIGNED2STRING (v, tag);
207 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
209 warning (0, "%qs is version %q.*s, expected version %q.*s",
210 da_file_name, 4, v, 4, e);
211 gcov_close ();
212 return;
215 /* Read the stamp, used for creating a generation count. */
216 tag = gcov_read_unsigned ();
217 bbg_file_stamp = crc32_unsigned (bbg_file_stamp, tag);
219 counts_hash = new hash_table<counts_entry> (10);
220 while ((tag = gcov_read_unsigned ()))
222 gcov_unsigned_t length;
223 gcov_position_t offset;
225 length = gcov_read_unsigned ();
226 offset = gcov_position ();
227 if (tag == GCOV_TAG_FUNCTION)
229 if (length)
231 fn_ident = gcov_read_unsigned ();
232 lineno_checksum = gcov_read_unsigned ();
233 cfg_checksum = gcov_read_unsigned ();
235 else
236 fn_ident = lineno_checksum = cfg_checksum = 0;
237 new_summary = 1;
239 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
241 struct gcov_summary sum;
242 unsigned ix;
244 if (new_summary)
245 memset (&summary, 0, sizeof (summary));
247 gcov_read_summary (&sum);
248 for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++)
250 summary.ctrs[ix].runs += sum.ctrs[ix].runs;
251 summary.ctrs[ix].sum_all += sum.ctrs[ix].sum_all;
252 if (summary.ctrs[ix].run_max < sum.ctrs[ix].run_max)
253 summary.ctrs[ix].run_max = sum.ctrs[ix].run_max;
254 summary.ctrs[ix].sum_max += sum.ctrs[ix].sum_max;
256 if (new_summary)
257 memcpy (summary.ctrs[GCOV_COUNTER_ARCS].histogram,
258 sum.ctrs[GCOV_COUNTER_ARCS].histogram,
259 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
260 else
261 gcov_histogram_merge (summary.ctrs[GCOV_COUNTER_ARCS].histogram,
262 sum.ctrs[GCOV_COUNTER_ARCS].histogram);
263 new_summary = 0;
265 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
267 counts_entry **slot, *entry, elt;
268 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
269 unsigned ix;
271 elt.ident = fn_ident;
272 elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
274 slot = counts_hash->find_slot (&elt, INSERT);
275 entry = *slot;
276 if (!entry)
278 *slot = entry = XCNEW (counts_entry);
279 entry->ident = fn_ident;
280 entry->ctr = elt.ctr;
281 entry->lineno_checksum = lineno_checksum;
282 entry->cfg_checksum = cfg_checksum;
283 if (elt.ctr < GCOV_COUNTERS_SUMMABLE)
284 entry->summary = summary.ctrs[elt.ctr];
285 entry->summary.num = n_counts;
286 entry->counts = XCNEWVEC (gcov_type, n_counts);
288 else if (entry->lineno_checksum != lineno_checksum
289 || entry->cfg_checksum != cfg_checksum)
291 error ("Profile data for function %u is corrupted", fn_ident);
292 error ("checksum is (%x,%x) instead of (%x,%x)",
293 entry->lineno_checksum, entry->cfg_checksum,
294 lineno_checksum, cfg_checksum);
295 delete counts_hash;
296 counts_hash = NULL;
297 break;
299 else if (entry->summary.num != n_counts)
301 error ("Profile data for function %u is corrupted", fn_ident);
302 error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
303 delete counts_hash;
304 counts_hash = NULL;
305 break;
307 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
309 error ("cannot merge separate %s counters for function %u",
310 ctr_names[elt.ctr], fn_ident);
311 goto skip_merge;
313 else
315 entry->summary.runs += summary.ctrs[elt.ctr].runs;
316 entry->summary.sum_all += summary.ctrs[elt.ctr].sum_all;
317 if (entry->summary.run_max < summary.ctrs[elt.ctr].run_max)
318 entry->summary.run_max = summary.ctrs[elt.ctr].run_max;
319 entry->summary.sum_max += summary.ctrs[elt.ctr].sum_max;
321 for (ix = 0; ix != n_counts; ix++)
322 entry->counts[ix] += gcov_read_counter ();
323 skip_merge:;
325 gcov_sync (offset, length);
326 if ((is_error = gcov_is_error ()))
328 error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted",
329 da_file_name);
330 delete counts_hash;
331 counts_hash = NULL;
332 break;
336 gcov_close ();
339 /* Returns the counters for a particular tag. */
341 gcov_type *
342 get_coverage_counts (unsigned counter, unsigned expected,
343 unsigned cfg_checksum, unsigned lineno_checksum,
344 const struct gcov_ctr_summary **summary)
346 counts_entry *entry, elt;
348 /* No hash table, no counts. */
349 if (!counts_hash)
351 static int warned = 0;
353 if (!warned++ && dump_enabled_p ())
354 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
355 (flag_guess_branch_prob
356 ? "file %s not found, execution counts estimated\n"
357 : "file %s not found, execution counts assumed to "
358 "be zero\n"),
359 da_file_name);
360 return NULL;
362 if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))
363 elt.ident = current_function_funcdef_no + 1;
364 else
366 gcc_assert (coverage_node_map_initialized_p ());
367 elt.ident = cgraph_node::get (cfun->decl)->profile_id;
369 elt.ctr = counter;
370 entry = counts_hash->find (&elt);
371 if (!entry || !entry->summary.num)
372 /* The function was not emitted, or is weak and not chosen in the
373 final executable. Silently fail, because there's nothing we
374 can do about it. */
375 return NULL;
377 if (entry->cfg_checksum != cfg_checksum
378 || entry->summary.num != expected)
380 static int warned = 0;
381 bool warning_printed = false;
382 tree id = DECL_ASSEMBLER_NAME (current_function_decl);
384 warning_printed =
385 warning_at (input_location, OPT_Wcoverage_mismatch,
386 "the control flow of function %qE does not match "
387 "its profile data (counter %qs)", id, ctr_names[counter]);
388 if (warning_printed && dump_enabled_p ())
390 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
391 "use -Wno-error=coverage-mismatch to tolerate "
392 "the mismatch but performance may drop if the "
393 "function is hot\n");
395 if (!seen_error ()
396 && !warned++)
398 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
399 "coverage mismatch ignored\n");
400 dump_printf (MSG_OPTIMIZED_LOCATIONS,
401 flag_guess_branch_prob
402 ? G_("execution counts estimated\n")
403 : G_("execution counts assumed to be zero\n"));
404 if (!flag_guess_branch_prob)
405 dump_printf (MSG_OPTIMIZED_LOCATIONS,
406 "this can result in poorly optimized code\n");
410 return NULL;
412 else if (entry->lineno_checksum != lineno_checksum)
414 warning (OPT_Wcoverage_mismatch,
415 "source locations for function %qE have changed,"
416 " the profile data may be out of date",
417 DECL_ASSEMBLER_NAME (current_function_decl));
420 if (summary)
421 *summary = &entry->summary;
423 return entry->counts;
426 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
427 allocation succeeded. */
430 coverage_counter_alloc (unsigned counter, unsigned num)
432 if (no_coverage)
433 return 0;
435 if (!num)
436 return 1;
438 if (!fn_v_ctrs[counter])
440 tree array_type = build_array_type (get_gcov_type (), NULL_TREE);
442 fn_v_ctrs[counter]
443 = build_var (current_function_decl, array_type, counter);
446 fn_b_ctrs[counter] = fn_n_ctrs[counter];
447 fn_n_ctrs[counter] += num;
449 fn_ctr_mask |= 1 << counter;
450 return 1;
453 /* Generate a tree to access COUNTER NO. */
455 tree
456 tree_coverage_counter_ref (unsigned counter, unsigned no)
458 tree gcov_type_node = get_gcov_type ();
460 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
462 no += fn_b_ctrs[counter];
464 /* "no" here is an array index, scaled to bytes later. */
465 return build4 (ARRAY_REF, gcov_type_node, fn_v_ctrs[counter],
466 build_int_cst (integer_type_node, no), NULL, NULL);
469 /* Generate a tree to access the address of COUNTER NO. */
471 tree
472 tree_coverage_counter_addr (unsigned counter, unsigned no)
474 tree gcov_type_node = get_gcov_type ();
476 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
477 no += fn_b_ctrs[counter];
479 /* "no" here is an array index, scaled to bytes later. */
480 return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node,
481 fn_v_ctrs[counter],
482 build_int_cst (integer_type_node, no),
483 NULL, NULL));
487 /* Generate a checksum for a string. CHKSUM is the current
488 checksum. */
490 static unsigned
491 coverage_checksum_string (unsigned chksum, const char *string)
493 int i;
494 char *dup = NULL;
496 /* Look for everything that looks if it were produced by
497 get_file_function_name and zero out the second part
498 that may result from flag_random_seed. This is not critical
499 as the checksums are used only for sanity checking. */
500 for (i = 0; string[i]; i++)
502 int offset = 0;
503 if (!strncmp (string + i, "_GLOBAL__N_", 11))
504 offset = 11;
505 if (!strncmp (string + i, "_GLOBAL__", 9))
506 offset = 9;
508 /* C++ namespaces do have scheme:
509 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
510 since filename might contain extra underscores there seems
511 to be no better chance then walk all possible offsets looking
512 for magicnumber. */
513 if (offset)
515 for (i = i + offset; string[i]; i++)
516 if (string[i]=='_')
518 int y;
520 for (y = 1; y < 9; y++)
521 if (!(string[i + y] >= '0' && string[i + y] <= '9')
522 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
523 break;
524 if (y != 9 || string[i + 9] != '_')
525 continue;
526 for (y = 10; y < 18; y++)
527 if (!(string[i + y] >= '0' && string[i + y] <= '9')
528 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
529 break;
530 if (y != 18)
531 continue;
532 if (!dup)
533 string = dup = xstrdup (string);
534 for (y = 10; y < 18; y++)
535 dup[i + y] = '0';
537 break;
541 chksum = crc32_string (chksum, string);
542 free (dup);
544 return chksum;
547 /* Compute checksum for the current function. We generate a CRC32. */
549 unsigned
550 coverage_compute_lineno_checksum (void)
552 expanded_location xloc
553 = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
554 unsigned chksum = xloc.line;
556 if (xloc.file)
557 chksum = coverage_checksum_string (chksum, xloc.file);
558 chksum = coverage_checksum_string
559 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
561 return chksum;
564 /* Compute profile ID. This is better to be unique in whole program. */
566 unsigned
567 coverage_compute_profile_id (struct cgraph_node *n)
569 unsigned chksum;
571 /* Externally visible symbols have unique name. */
572 if (TREE_PUBLIC (n->decl) || DECL_EXTERNAL (n->decl) || n->unique_name)
574 chksum = coverage_checksum_string
575 (0, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl)));
577 else
579 expanded_location xloc
580 = expand_location (DECL_SOURCE_LOCATION (n->decl));
581 bool use_name_only = (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID) == 0);
583 chksum = (use_name_only ? 0 : xloc.line);
584 if (xloc.file)
585 chksum = coverage_checksum_string (chksum, xloc.file);
586 chksum = coverage_checksum_string
587 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl)));
588 if (!use_name_only && first_global_object_name)
589 chksum = coverage_checksum_string
590 (chksum, first_global_object_name);
591 chksum = coverage_checksum_string
592 (chksum, aux_base_name);
595 /* Non-negative integers are hopefully small enough to fit in all targets.
596 Gcov file formats wants non-zero function IDs. */
597 chksum = chksum & 0x7fffffff;
598 return chksum + (!chksum);
601 /* Compute cfg checksum for the function FN given as argument.
602 The checksum is calculated carefully so that
603 source code changes that doesn't affect the control flow graph
604 won't change the checksum.
605 This is to make the profile data useable across source code change.
606 The downside of this is that the compiler may use potentially
607 wrong profile data - that the source code change has non-trivial impact
608 on the validity of profile data (e.g. the reversed condition)
609 but the compiler won't detect the change and use the wrong profile data. */
611 unsigned
612 coverage_compute_cfg_checksum (struct function *fn)
614 basic_block bb;
615 unsigned chksum = n_basic_blocks_for_fn (fn);
617 FOR_EACH_BB_FN (bb, fn)
619 edge e;
620 edge_iterator ei;
621 chksum = crc32_byte (chksum, bb->index);
622 FOR_EACH_EDGE (e, ei, bb->succs)
624 chksum = crc32_byte (chksum, e->dest->index);
628 return chksum;
631 /* Begin output to the notes file for the current function.
632 Writes the function header. Returns nonzero if data should be output. */
635 coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
637 expanded_location xloc;
638 unsigned long offset;
640 /* We don't need to output .gcno file unless we're under -ftest-coverage
641 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
642 if (no_coverage || !bbg_file_name)
643 return 0;
645 xloc = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
647 /* Announce function */
648 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
649 if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))
650 gcov_write_unsigned (current_function_funcdef_no + 1);
651 else
653 gcc_assert (coverage_node_map_initialized_p ());
654 gcov_write_unsigned (
655 cgraph_node::get (current_function_decl)->profile_id);
658 gcov_write_unsigned (lineno_checksum);
659 gcov_write_unsigned (cfg_checksum);
660 gcov_write_string (IDENTIFIER_POINTER
661 (DECL_ASSEMBLER_NAME (current_function_decl)));
662 gcov_write_string (xloc.file);
663 gcov_write_unsigned (xloc.line);
664 gcov_write_length (offset);
666 return !gcov_is_error ();
669 /* Finish coverage data for the current function. Verify no output
670 error has occurred. Save function coverage counts. */
672 void
673 coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum)
675 unsigned i;
677 if (bbg_file_name && gcov_is_error ())
679 warning (0, "error writing %qs", bbg_file_name);
680 unlink (bbg_file_name);
681 bbg_file_name = NULL;
684 if (fn_ctr_mask)
686 struct coverage_data *item = 0;
688 item = ggc_alloc<coverage_data> ();
690 if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))
691 item->ident = current_function_funcdef_no + 1;
692 else
694 gcc_assert (coverage_node_map_initialized_p ());
695 item->ident = cgraph_node::get (cfun->decl)->profile_id;
698 item->lineno_checksum = lineno_checksum;
699 item->cfg_checksum = cfg_checksum;
701 item->fn_decl = current_function_decl;
702 item->next = 0;
703 *functions_tail = item;
704 functions_tail = &item->next;
706 for (i = 0; i != GCOV_COUNTERS; i++)
708 tree var = fn_v_ctrs[i];
710 if (item)
711 item->ctr_vars[i] = var;
712 if (var)
714 tree array_type = build_index_type (size_int (fn_n_ctrs[i] - 1));
715 array_type = build_array_type (get_gcov_type (), array_type);
716 TREE_TYPE (var) = array_type;
717 DECL_SIZE (var) = TYPE_SIZE (array_type);
718 DECL_SIZE_UNIT (var) = TYPE_SIZE_UNIT (array_type);
719 varpool_node::finalize_decl (var);
722 fn_b_ctrs[i] = fn_n_ctrs[i] = 0;
723 fn_v_ctrs[i] = NULL_TREE;
725 prg_ctr_mask |= fn_ctr_mask;
726 fn_ctr_mask = 0;
730 /* Build a coverage variable of TYPE for function FN_DECL. If COUNTER
731 >= 0 it is a counter array, otherwise it is the function structure. */
733 static tree
734 build_var (tree fn_decl, tree type, int counter)
736 tree var = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, type);
737 const char *fn_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn_decl));
738 char *buf;
739 size_t fn_name_len, len;
741 fn_name = targetm.strip_name_encoding (fn_name);
742 fn_name_len = strlen (fn_name);
743 buf = XALLOCAVEC (char, fn_name_len + 8 + sizeof (int) * 3);
745 if (counter < 0)
746 strcpy (buf, "__gcov__");
747 else
748 sprintf (buf, "__gcov%u_", counter);
749 len = strlen (buf);
750 buf[len - 1] = symbol_table::symbol_suffix_separator ();
751 memcpy (buf + len, fn_name, fn_name_len + 1);
752 DECL_NAME (var) = get_identifier (buf);
753 TREE_STATIC (var) = 1;
754 TREE_ADDRESSABLE (var) = 1;
755 DECL_NONALIASED (var) = 1;
756 SET_DECL_ALIGN (var, TYPE_ALIGN (type));
758 return var;
761 /* Creates the gcov_fn_info RECORD_TYPE. */
763 static void
764 build_fn_info_type (tree type, unsigned counters, tree gcov_info_type)
766 tree ctr_info = lang_hooks.types.make_type (RECORD_TYPE);
767 tree field, fields;
768 tree array_type;
770 gcc_assert (counters);
772 /* ctr_info::num */
773 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
774 get_gcov_unsigned_t ());
775 fields = field;
777 /* ctr_info::values */
778 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
779 build_pointer_type (get_gcov_type ()));
780 DECL_CHAIN (field) = fields;
781 fields = field;
783 finish_builtin_struct (ctr_info, "__gcov_ctr_info", fields, NULL_TREE);
785 /* key */
786 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
787 build_pointer_type (build_qualified_type
788 (gcov_info_type, TYPE_QUAL_CONST)));
789 fields = field;
791 /* ident */
792 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
793 get_gcov_unsigned_t ());
794 DECL_CHAIN (field) = fields;
795 fields = field;
797 /* lineno_checksum */
798 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
799 get_gcov_unsigned_t ());
800 DECL_CHAIN (field) = fields;
801 fields = field;
803 /* cfg checksum */
804 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
805 get_gcov_unsigned_t ());
806 DECL_CHAIN (field) = fields;
807 fields = field;
809 array_type = build_index_type (size_int (counters - 1));
810 array_type = build_array_type (ctr_info, array_type);
812 /* counters */
813 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, array_type);
814 DECL_CHAIN (field) = fields;
815 fields = field;
817 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
820 /* Returns a CONSTRUCTOR for a gcov_fn_info. DATA is
821 the coverage data for the function and TYPE is the gcov_fn_info
822 RECORD_TYPE. KEY is the object file key. */
824 static tree
825 build_fn_info (const struct coverage_data *data, tree type, tree key)
827 tree fields = TYPE_FIELDS (type);
828 tree ctr_type;
829 unsigned ix;
830 vec<constructor_elt, va_gc> *v1 = NULL;
831 vec<constructor_elt, va_gc> *v2 = NULL;
833 /* key */
834 CONSTRUCTOR_APPEND_ELT (v1, fields,
835 build1 (ADDR_EXPR, TREE_TYPE (fields), key));
836 fields = DECL_CHAIN (fields);
838 /* ident */
839 CONSTRUCTOR_APPEND_ELT (v1, fields,
840 build_int_cstu (get_gcov_unsigned_t (),
841 data->ident));
842 fields = DECL_CHAIN (fields);
844 /* lineno_checksum */
845 CONSTRUCTOR_APPEND_ELT (v1, fields,
846 build_int_cstu (get_gcov_unsigned_t (),
847 data->lineno_checksum));
848 fields = DECL_CHAIN (fields);
850 /* cfg_checksum */
851 CONSTRUCTOR_APPEND_ELT (v1, fields,
852 build_int_cstu (get_gcov_unsigned_t (),
853 data->cfg_checksum));
854 fields = DECL_CHAIN (fields);
856 /* counters */
857 ctr_type = TREE_TYPE (TREE_TYPE (fields));
858 for (ix = 0; ix != GCOV_COUNTERS; ix++)
859 if (prg_ctr_mask & (1 << ix))
861 vec<constructor_elt, va_gc> *ctr = NULL;
862 tree var = data->ctr_vars[ix];
863 unsigned count = 0;
865 if (var)
866 count
867 = tree_to_shwi (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var))))
868 + 1;
870 CONSTRUCTOR_APPEND_ELT (ctr, TYPE_FIELDS (ctr_type),
871 build_int_cstu (get_gcov_unsigned_t (),
872 count));
874 if (var)
875 CONSTRUCTOR_APPEND_ELT (ctr, DECL_CHAIN (TYPE_FIELDS (ctr_type)),
876 build_fold_addr_expr (var));
878 CONSTRUCTOR_APPEND_ELT (v2, NULL, build_constructor (ctr_type, ctr));
881 CONSTRUCTOR_APPEND_ELT (v1, fields,
882 build_constructor (TREE_TYPE (fields), v2));
884 return build_constructor (type, v1);
887 /* Create gcov_info struct. TYPE is the incomplete RECORD_TYPE to be
888 completed, and FN_INFO_PTR_TYPE is a pointer to the function info type. */
890 static void
891 build_info_type (tree type, tree fn_info_ptr_type)
893 tree field, fields = NULL_TREE;
894 tree merge_fn_type;
896 /* Version ident */
897 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
898 get_gcov_unsigned_t ());
899 DECL_CHAIN (field) = fields;
900 fields = field;
902 /* next pointer */
903 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
904 build_pointer_type (build_qualified_type
905 (type, TYPE_QUAL_CONST)));
906 DECL_CHAIN (field) = fields;
907 fields = field;
909 /* stamp */
910 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
911 get_gcov_unsigned_t ());
912 DECL_CHAIN (field) = fields;
913 fields = field;
915 /* Filename */
916 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
917 build_pointer_type (build_qualified_type
918 (char_type_node, TYPE_QUAL_CONST)));
919 DECL_CHAIN (field) = fields;
920 fields = field;
922 /* merge fn array */
923 merge_fn_type
924 = build_function_type_list (void_type_node,
925 build_pointer_type (get_gcov_type ()),
926 get_gcov_unsigned_t (), NULL_TREE);
927 merge_fn_type
928 = build_array_type (build_pointer_type (merge_fn_type),
929 build_index_type (size_int (GCOV_COUNTERS - 1)));
930 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
931 merge_fn_type);
932 DECL_CHAIN (field) = fields;
933 fields = field;
935 /* n_functions */
936 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
937 get_gcov_unsigned_t ());
938 DECL_CHAIN (field) = fields;
939 fields = field;
941 /* function_info pointer pointer */
942 fn_info_ptr_type = build_pointer_type
943 (build_qualified_type (fn_info_ptr_type, TYPE_QUAL_CONST));
944 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
945 fn_info_ptr_type);
946 DECL_CHAIN (field) = fields;
947 fields = field;
949 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
952 /* Returns a CONSTRUCTOR for the gcov_info object. INFO_TYPE is the
953 gcov_info structure type, FN_ARY is the array of pointers to
954 function info objects. */
956 static tree
957 build_info (tree info_type, tree fn_ary)
959 tree info_fields = TYPE_FIELDS (info_type);
960 tree merge_fn_type, n_funcs;
961 unsigned ix;
962 tree filename_string;
963 int da_file_name_len;
964 vec<constructor_elt, va_gc> *v1 = NULL;
965 vec<constructor_elt, va_gc> *v2 = NULL;
967 /* Version ident */
968 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
969 build_int_cstu (TREE_TYPE (info_fields),
970 GCOV_VERSION));
971 info_fields = DECL_CHAIN (info_fields);
973 /* next -- NULL */
974 CONSTRUCTOR_APPEND_ELT (v1, info_fields, null_pointer_node);
975 info_fields = DECL_CHAIN (info_fields);
977 /* stamp */
978 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
979 build_int_cstu (TREE_TYPE (info_fields),
980 bbg_file_stamp));
981 info_fields = DECL_CHAIN (info_fields);
983 /* Filename */
984 da_file_name_len = strlen (da_file_name);
985 filename_string = build_string (da_file_name_len + 1, da_file_name);
986 TREE_TYPE (filename_string) = build_array_type
987 (char_type_node, build_index_type (size_int (da_file_name_len)));
988 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
989 build1 (ADDR_EXPR, TREE_TYPE (info_fields),
990 filename_string));
991 info_fields = DECL_CHAIN (info_fields);
993 /* merge fn array -- NULL slots indicate unmeasured counters */
994 merge_fn_type = TREE_TYPE (TREE_TYPE (info_fields));
995 for (ix = 0; ix != GCOV_COUNTERS; ix++)
997 tree ptr = null_pointer_node;
999 if ((1u << ix) & prg_ctr_mask)
1001 tree merge_fn = build_decl (BUILTINS_LOCATION,
1002 FUNCTION_DECL,
1003 get_identifier (ctr_merge_functions[ix]),
1004 TREE_TYPE (merge_fn_type));
1005 DECL_EXTERNAL (merge_fn) = 1;
1006 TREE_PUBLIC (merge_fn) = 1;
1007 DECL_ARTIFICIAL (merge_fn) = 1;
1008 TREE_NOTHROW (merge_fn) = 1;
1009 /* Initialize assembler name so we can stream out. */
1010 DECL_ASSEMBLER_NAME (merge_fn);
1011 ptr = build1 (ADDR_EXPR, merge_fn_type, merge_fn);
1013 CONSTRUCTOR_APPEND_ELT (v2, NULL, ptr);
1015 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
1016 build_constructor (TREE_TYPE (info_fields), v2));
1017 info_fields = DECL_CHAIN (info_fields);
1019 /* n_functions */
1020 n_funcs = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (fn_ary)));
1021 n_funcs = fold_build2 (PLUS_EXPR, TREE_TYPE (info_fields),
1022 n_funcs, size_one_node);
1023 CONSTRUCTOR_APPEND_ELT (v1, info_fields, n_funcs);
1024 info_fields = DECL_CHAIN (info_fields);
1026 /* functions */
1027 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
1028 build1 (ADDR_EXPR, TREE_TYPE (info_fields), fn_ary));
1029 info_fields = DECL_CHAIN (info_fields);
1031 gcc_assert (!info_fields);
1032 return build_constructor (info_type, v1);
1035 /* Generate the constructor function to call __gcov_init. */
1037 static void
1038 build_init_ctor (tree gcov_info_type)
1040 tree ctor, stmt, init_fn;
1042 /* Build a decl for __gcov_init. */
1043 init_fn = build_pointer_type (gcov_info_type);
1044 init_fn = build_function_type_list (void_type_node, init_fn, NULL);
1045 init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
1046 get_identifier ("__gcov_init"), init_fn);
1047 TREE_PUBLIC (init_fn) = 1;
1048 DECL_EXTERNAL (init_fn) = 1;
1049 DECL_ASSEMBLER_NAME (init_fn);
1051 /* Generate a call to __gcov_init(&gcov_info). */
1052 ctor = NULL;
1053 stmt = build_fold_addr_expr (gcov_info_var);
1054 stmt = build_call_expr (init_fn, 1, stmt);
1055 append_to_statement_list (stmt, &ctor);
1057 /* Generate a constructor to run it. */
1058 cgraph_build_static_cdtor ('I', ctor, DEFAULT_INIT_PRIORITY);
1061 /* Create the gcov_info types and object. Generate the constructor
1062 function to call __gcov_init. Does not generate the initializer
1063 for the object. Returns TRUE if coverage data is being emitted. */
1065 static bool
1066 coverage_obj_init (void)
1068 tree gcov_info_type;
1069 unsigned n_counters = 0;
1070 unsigned ix;
1071 struct coverage_data *fn;
1072 struct coverage_data **fn_prev;
1073 char name_buf[32];
1075 no_coverage = 1; /* Disable any further coverage. */
1077 if (!prg_ctr_mask)
1078 return false;
1080 if (symtab->dump_file)
1081 fprintf (symtab->dump_file, "Using data file %s\n", da_file_name);
1083 /* Prune functions. */
1084 for (fn_prev = &functions_head; (fn = *fn_prev);)
1085 if (DECL_STRUCT_FUNCTION (fn->fn_decl))
1086 fn_prev = &fn->next;
1087 else
1088 /* The function is not being emitted, remove from list. */
1089 *fn_prev = fn->next;
1091 if (functions_head == NULL)
1092 return false;
1094 for (ix = 0; ix != GCOV_COUNTERS; ix++)
1095 if ((1u << ix) & prg_ctr_mask)
1096 n_counters++;
1098 /* Build the info and fn_info types. These are mutually recursive. */
1099 gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1100 gcov_fn_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1101 build_fn_info_type (gcov_fn_info_type, n_counters, gcov_info_type);
1102 gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1103 gcov_fn_info_ptr_type = build_pointer_type
1104 (build_qualified_type (gcov_fn_info_type, TYPE_QUAL_CONST));
1105 build_info_type (gcov_info_type, gcov_fn_info_ptr_type);
1107 /* Build the gcov info var, this is referred to in its own
1108 initializer. */
1109 gcov_info_var = build_decl (BUILTINS_LOCATION,
1110 VAR_DECL, NULL_TREE, gcov_info_type);
1111 TREE_STATIC (gcov_info_var) = 1;
1112 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
1113 DECL_NAME (gcov_info_var) = get_identifier (name_buf);
1115 build_init_ctor (gcov_info_type);
1117 return true;
1120 /* Generate the coverage function info for FN and DATA. Append a
1121 pointer to that object to CTOR and return the appended CTOR. */
1123 static vec<constructor_elt, va_gc> *
1124 coverage_obj_fn (vec<constructor_elt, va_gc> *ctor, tree fn,
1125 struct coverage_data const *data)
1127 tree init = build_fn_info (data, gcov_fn_info_type, gcov_info_var);
1128 tree var = build_var (fn, gcov_fn_info_type, -1);
1130 DECL_INITIAL (var) = init;
1131 varpool_node::finalize_decl (var);
1133 CONSTRUCTOR_APPEND_ELT (ctor, NULL,
1134 build1 (ADDR_EXPR, gcov_fn_info_ptr_type, var));
1135 return ctor;
1138 /* Finalize the coverage data. Generates the array of pointers to
1139 function objects from CTOR. Generate the gcov_info initializer. */
1141 static void
1142 coverage_obj_finish (vec<constructor_elt, va_gc> *ctor)
1144 unsigned n_functions = vec_safe_length (ctor);
1145 tree fn_info_ary_type = build_array_type
1146 (build_qualified_type (gcov_fn_info_ptr_type, TYPE_QUAL_CONST),
1147 build_index_type (size_int (n_functions - 1)));
1148 tree fn_info_ary = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE,
1149 fn_info_ary_type);
1150 char name_buf[32];
1152 TREE_STATIC (fn_info_ary) = 1;
1153 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 1);
1154 DECL_NAME (fn_info_ary) = get_identifier (name_buf);
1155 DECL_INITIAL (fn_info_ary) = build_constructor (fn_info_ary_type, ctor);
1156 varpool_node::finalize_decl (fn_info_ary);
1158 DECL_INITIAL (gcov_info_var)
1159 = build_info (TREE_TYPE (gcov_info_var), fn_info_ary);
1160 varpool_node::finalize_decl (gcov_info_var);
1163 /* Perform file-level initialization. Read in data file, generate name
1164 of notes file. */
1166 void
1167 coverage_init (const char *filename)
1169 int len = strlen (filename);
1170 int prefix_len = 0;
1172 /* Since coverage_init is invoked very early, before the pass
1173 manager, we need to set up the dumping explicitly. This is
1174 similar to the handling in finish_optimization_passes. */
1175 int profile_pass_num =
1176 g->get_passes ()->get_pass_profile ()->static_pass_number;
1177 g->get_dumps ()->dump_start (profile_pass_num, NULL);
1179 if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
1180 profile_data_prefix = getpwd ();
1182 if (profile_data_prefix)
1183 prefix_len = strlen (profile_data_prefix);
1185 /* Name of da file. */
1186 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
1187 + prefix_len + 2);
1189 if (profile_data_prefix)
1191 memcpy (da_file_name, profile_data_prefix, prefix_len);
1192 da_file_name[prefix_len++] = '/';
1194 memcpy (da_file_name + prefix_len, filename, len);
1195 strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX);
1197 bbg_file_stamp = local_tick;
1199 if (flag_auto_profile)
1200 read_autofdo_file ();
1201 else if (flag_branch_probabilities)
1202 read_counts_file ();
1204 /* Name of bbg file. */
1205 if (flag_test_coverage && !flag_compare_debug)
1207 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1);
1208 memcpy (bbg_file_name, filename, len);
1209 strcpy (bbg_file_name + len, GCOV_NOTE_SUFFIX);
1211 if (!gcov_open (bbg_file_name, -1))
1213 error ("cannot open %s", bbg_file_name);
1214 bbg_file_name = NULL;
1216 else
1218 gcov_write_unsigned (GCOV_NOTE_MAGIC);
1219 gcov_write_unsigned (GCOV_VERSION);
1220 gcov_write_unsigned (bbg_file_stamp);
1224 g->get_dumps ()->dump_finish (profile_pass_num);
1227 /* Performs file-level cleanup. Close notes file, generate coverage
1228 variables and constructor. */
1230 void
1231 coverage_finish (void)
1233 if (bbg_file_name && gcov_close ())
1234 unlink (bbg_file_name);
1236 if (!flag_branch_probabilities && flag_test_coverage
1237 && (!local_tick || local_tick == (unsigned)-1))
1238 /* Only remove the da file, if we're emitting coverage code and
1239 cannot uniquely stamp it. If we can stamp it, libgcov will DTRT. */
1240 unlink (da_file_name);
1242 if (coverage_obj_init ())
1244 vec<constructor_elt, va_gc> *fn_ctor = NULL;
1245 struct coverage_data *fn;
1247 for (fn = functions_head; fn; fn = fn->next)
1248 fn_ctor = coverage_obj_fn (fn_ctor, fn->fn_decl, fn);
1249 coverage_obj_finish (fn_ctor);
1252 XDELETEVEC (da_file_name);
1253 da_file_name = NULL;
1256 #include "gt-coverage.h"