AVX-512. Branch to hold overall changes introduced by 20140717 EAS.
[official-gcc.git] / gcc / coverage.c
blob1e47dd88cd98c89c4c0841ea2e910c4cea683d56
1 /* Read and write coverage files, and associated functionality.
2 Copyright (C) 1990-2014 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 "stringpool.h"
34 #include "stor-layout.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 "hash-table.h"
47 #include "tree-iterator.h"
48 #include "context.h"
49 #include "pass_manager.h"
50 #include "tree-pass.h"
51 #include "cgraph.h"
52 #include "dumpfile.h"
53 #include "diagnostic-core.h"
54 #include "intl.h"
55 #include "filenames.h"
56 #include "target.h"
58 #include "gcov-io.h"
59 #include "gcov-io.c"
61 struct GTY((chain_next ("%h.next"))) coverage_data
63 struct coverage_data *next; /* next function */
64 unsigned ident; /* function ident */
65 unsigned lineno_checksum; /* function lineno checksum */
66 unsigned cfg_checksum; /* function cfg checksum */
67 tree fn_decl; /* the function decl */
68 tree ctr_vars[GCOV_COUNTERS]; /* counter variables. */
71 /* Counts information for a function. */
72 typedef struct counts_entry
74 /* We hash by */
75 unsigned ident;
76 unsigned ctr;
78 /* Store */
79 unsigned lineno_checksum;
80 unsigned cfg_checksum;
81 gcov_type *counts;
82 struct gcov_ctr_summary summary;
84 /* hash_table support. */
85 typedef counts_entry value_type;
86 typedef counts_entry compare_type;
87 static inline hashval_t hash (const value_type *);
88 static int equal (const value_type *, const compare_type *);
89 static void remove (value_type *);
90 } counts_entry_t;
92 static GTY(()) struct coverage_data *functions_head = 0;
93 static struct coverage_data **functions_tail = &functions_head;
94 static unsigned no_coverage = 0;
96 /* Cumulative counter information for whole program. */
97 static unsigned prg_ctr_mask; /* Mask of counter types generated. */
99 /* Counter information for current function. */
100 static unsigned fn_ctr_mask; /* Mask of counters used. */
101 static GTY(()) tree fn_v_ctrs[GCOV_COUNTERS]; /* counter variables. */
102 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated. */
103 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base. */
105 /* Coverage info VAR_DECL and function info type nodes. */
106 static GTY(()) tree gcov_info_var;
107 static GTY(()) tree gcov_fn_info_type;
108 static GTY(()) tree gcov_fn_info_ptr_type;
110 /* Name of the notes (gcno) output file. The "bbg" prefix is for
111 historical reasons, when the notes file contained only the
112 basic block graph notes.
113 If this is NULL we're not writing to the notes file. */
114 static char *bbg_file_name;
116 /* File stamp for notes file. */
117 static unsigned bbg_file_stamp;
119 /* Name of the count data (gcda) file. */
120 static char *da_file_name;
122 /* The names of merge functions for counters. */
123 #define STR(str) #str
124 #define DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) STR(__gcov_merge ## FN_TYPE),
125 static const char *const ctr_merge_functions[GCOV_COUNTERS] = {
126 #include "gcov-counter.def"
128 #undef DEF_GCOV_COUNTER
129 #undef STR
131 #define DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) NAME,
132 static const char *const ctr_names[GCOV_COUNTERS] = {
133 #include "gcov-counter.def"
135 #undef DEF_GCOV_COUNTER
137 /* Forward declarations. */
138 static void read_counts_file (void);
139 static tree build_var (tree, tree, int);
140 static void build_fn_info_type (tree, unsigned, tree);
141 static void build_info_type (tree, tree);
142 static tree build_fn_info (const struct coverage_data *, tree, tree);
143 static tree build_info (tree, tree);
144 static bool coverage_obj_init (void);
145 static vec<constructor_elt, va_gc> *coverage_obj_fn
146 (vec<constructor_elt, va_gc> *, tree, struct coverage_data const *);
147 static void coverage_obj_finish (vec<constructor_elt, va_gc> *);
149 /* Return the type node for gcov_type. */
151 tree
152 get_gcov_type (void)
154 enum machine_mode mode = smallest_mode_for_size (GCOV_TYPE_SIZE, MODE_INT);
155 return lang_hooks.types.type_for_mode (mode, false);
158 /* Return the type node for gcov_unsigned_t. */
160 static tree
161 get_gcov_unsigned_t (void)
163 enum machine_mode mode = smallest_mode_for_size (32, MODE_INT);
164 return lang_hooks.types.type_for_mode (mode, true);
167 inline hashval_t
168 counts_entry::hash (const value_type *entry)
170 return entry->ident * GCOV_COUNTERS + entry->ctr;
173 inline int
174 counts_entry::equal (const value_type *entry1,
175 const compare_type *entry2)
177 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
180 inline void
181 counts_entry::remove (value_type *entry)
183 free (entry->counts);
184 free (entry);
187 /* Hash table of count data. */
188 static hash_table<counts_entry> *counts_hash;
190 /* Read in the counts file, if available. */
192 static void
193 read_counts_file (void)
195 gcov_unsigned_t fn_ident = 0;
196 struct gcov_summary summary;
197 unsigned new_summary = 1;
198 gcov_unsigned_t tag;
199 int is_error = 0;
200 unsigned lineno_checksum = 0;
201 unsigned cfg_checksum = 0;
203 if (!gcov_open (da_file_name, 1))
204 return;
206 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
208 warning (0, "%qs is not a gcov data file", da_file_name);
209 gcov_close ();
210 return;
212 else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
214 char v[4], e[4];
216 GCOV_UNSIGNED2STRING (v, tag);
217 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
219 warning (0, "%qs is version %q.*s, expected version %q.*s",
220 da_file_name, 4, v, 4, e);
221 gcov_close ();
222 return;
225 /* Read the stamp, used for creating a generation count. */
226 tag = gcov_read_unsigned ();
227 bbg_file_stamp = crc32_unsigned (bbg_file_stamp, tag);
229 counts_hash = new hash_table<counts_entry> (10);
230 while ((tag = gcov_read_unsigned ()))
232 gcov_unsigned_t length;
233 gcov_position_t offset;
235 length = gcov_read_unsigned ();
236 offset = gcov_position ();
237 if (tag == GCOV_TAG_FUNCTION)
239 if (length)
241 fn_ident = gcov_read_unsigned ();
242 lineno_checksum = gcov_read_unsigned ();
243 cfg_checksum = gcov_read_unsigned ();
245 else
246 fn_ident = lineno_checksum = cfg_checksum = 0;
247 new_summary = 1;
249 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
251 struct gcov_summary sum;
252 unsigned ix;
254 if (new_summary)
255 memset (&summary, 0, sizeof (summary));
257 gcov_read_summary (&sum);
258 for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++)
260 summary.ctrs[ix].runs += sum.ctrs[ix].runs;
261 summary.ctrs[ix].sum_all += sum.ctrs[ix].sum_all;
262 if (summary.ctrs[ix].run_max < sum.ctrs[ix].run_max)
263 summary.ctrs[ix].run_max = sum.ctrs[ix].run_max;
264 summary.ctrs[ix].sum_max += sum.ctrs[ix].sum_max;
266 if (new_summary)
267 memcpy (summary.ctrs[GCOV_COUNTER_ARCS].histogram,
268 sum.ctrs[GCOV_COUNTER_ARCS].histogram,
269 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
270 else
271 gcov_histogram_merge (summary.ctrs[GCOV_COUNTER_ARCS].histogram,
272 sum.ctrs[GCOV_COUNTER_ARCS].histogram);
273 new_summary = 0;
275 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
277 counts_entry_t **slot, *entry, elt;
278 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
279 unsigned ix;
281 elt.ident = fn_ident;
282 elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
284 slot = counts_hash->find_slot (&elt, INSERT);
285 entry = *slot;
286 if (!entry)
288 *slot = entry = XCNEW (counts_entry_t);
289 entry->ident = fn_ident;
290 entry->ctr = elt.ctr;
291 entry->lineno_checksum = lineno_checksum;
292 entry->cfg_checksum = cfg_checksum;
293 if (elt.ctr < GCOV_COUNTERS_SUMMABLE)
294 entry->summary = summary.ctrs[elt.ctr];
295 entry->summary.num = n_counts;
296 entry->counts = XCNEWVEC (gcov_type, n_counts);
298 else if (entry->lineno_checksum != lineno_checksum
299 || entry->cfg_checksum != cfg_checksum)
301 error ("Profile data for function %u is corrupted", fn_ident);
302 error ("checksum is (%x,%x) instead of (%x,%x)",
303 entry->lineno_checksum, entry->cfg_checksum,
304 lineno_checksum, cfg_checksum);
305 delete counts_hash;
306 counts_hash = NULL;
307 break;
309 else if (entry->summary.num != n_counts)
311 error ("Profile data for function %u is corrupted", fn_ident);
312 error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
313 delete counts_hash;
314 counts_hash = NULL;
315 break;
317 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
319 error ("cannot merge separate %s counters for function %u",
320 ctr_names[elt.ctr], fn_ident);
321 goto skip_merge;
323 else
325 entry->summary.runs += summary.ctrs[elt.ctr].runs;
326 entry->summary.sum_all += summary.ctrs[elt.ctr].sum_all;
327 if (entry->summary.run_max < summary.ctrs[elt.ctr].run_max)
328 entry->summary.run_max = summary.ctrs[elt.ctr].run_max;
329 entry->summary.sum_max += summary.ctrs[elt.ctr].sum_max;
331 for (ix = 0; ix != n_counts; ix++)
332 entry->counts[ix] += gcov_read_counter ();
333 skip_merge:;
335 gcov_sync (offset, length);
336 if ((is_error = gcov_is_error ()))
338 error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted",
339 da_file_name);
340 delete counts_hash;
341 counts_hash = NULL;
342 break;
346 gcov_close ();
349 /* Returns the counters for a particular tag. */
351 gcov_type *
352 get_coverage_counts (unsigned counter, unsigned expected,
353 unsigned cfg_checksum, unsigned lineno_checksum,
354 const struct gcov_ctr_summary **summary)
356 counts_entry_t *entry, elt;
358 /* No hash table, no counts. */
359 if (!counts_hash)
361 static int warned = 0;
363 if (!warned++ && dump_enabled_p ())
364 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
365 (flag_guess_branch_prob
366 ? "file %s not found, execution counts estimated\n"
367 : "file %s not found, execution counts assumed to "
368 "be zero\n"),
369 da_file_name);
370 return NULL;
373 elt.ident = current_function_funcdef_no + 1;
374 elt.ctr = counter;
375 entry = counts_hash->find (&elt);
376 if (!entry || !entry->summary.num)
377 /* The function was not emitted, or is weak and not chosen in the
378 final executable. Silently fail, because there's nothing we
379 can do about it. */
380 return NULL;
382 if (entry->cfg_checksum != cfg_checksum
383 || entry->summary.num != expected)
385 static int warned = 0;
386 bool warning_printed = false;
387 tree id = DECL_ASSEMBLER_NAME (current_function_decl);
389 warning_printed =
390 warning_at (input_location, OPT_Wcoverage_mismatch,
391 "the control flow of function %qE does not match "
392 "its profile data (counter %qs)", id, ctr_names[counter]);
393 if (warning_printed && dump_enabled_p ())
395 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
396 "use -Wno-error=coverage-mismatch to tolerate "
397 "the mismatch but performance may drop if the "
398 "function is hot\n");
400 if (!seen_error ()
401 && !warned++)
403 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
404 "coverage mismatch ignored\n");
405 dump_printf (MSG_OPTIMIZED_LOCATIONS,
406 flag_guess_branch_prob
407 ? G_("execution counts estimated\n")
408 : G_("execution counts assumed to be zero\n"));
409 if (!flag_guess_branch_prob)
410 dump_printf (MSG_OPTIMIZED_LOCATIONS,
411 "this can result in poorly optimized code\n");
415 return NULL;
417 else if (entry->lineno_checksum != lineno_checksum)
419 warning (0, "source locations for function %qE have changed,"
420 " the profile data may be out of date",
421 DECL_ASSEMBLER_NAME (current_function_decl));
424 if (summary)
425 *summary = &entry->summary;
427 return entry->counts;
430 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
431 allocation succeeded. */
434 coverage_counter_alloc (unsigned counter, unsigned num)
436 if (no_coverage)
437 return 0;
439 if (!num)
440 return 1;
442 if (!fn_v_ctrs[counter])
444 tree array_type = build_array_type (get_gcov_type (), NULL_TREE);
446 fn_v_ctrs[counter]
447 = build_var (current_function_decl, array_type, counter);
450 fn_b_ctrs[counter] = fn_n_ctrs[counter];
451 fn_n_ctrs[counter] += num;
453 fn_ctr_mask |= 1 << counter;
454 return 1;
457 /* Generate a tree to access COUNTER NO. */
459 tree
460 tree_coverage_counter_ref (unsigned counter, unsigned no)
462 tree gcov_type_node = get_gcov_type ();
464 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
466 no += fn_b_ctrs[counter];
468 /* "no" here is an array index, scaled to bytes later. */
469 return build4 (ARRAY_REF, gcov_type_node, fn_v_ctrs[counter],
470 build_int_cst (integer_type_node, no), NULL, NULL);
473 /* Generate a tree to access the address of COUNTER NO. */
475 tree
476 tree_coverage_counter_addr (unsigned counter, unsigned no)
478 tree gcov_type_node = get_gcov_type ();
480 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
481 no += fn_b_ctrs[counter];
483 /* "no" here is an array index, scaled to bytes later. */
484 return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node,
485 fn_v_ctrs[counter],
486 build_int_cst (integer_type_node, no),
487 NULL, NULL));
491 /* Generate a checksum for a string. CHKSUM is the current
492 checksum. */
494 static unsigned
495 coverage_checksum_string (unsigned chksum, const char *string)
497 int i;
498 char *dup = NULL;
500 /* Look for everything that looks if it were produced by
501 get_file_function_name and zero out the second part
502 that may result from flag_random_seed. This is not critical
503 as the checksums are used only for sanity checking. */
504 for (i = 0; string[i]; i++)
506 int offset = 0;
507 if (!strncmp (string + i, "_GLOBAL__N_", 11))
508 offset = 11;
509 if (!strncmp (string + i, "_GLOBAL__", 9))
510 offset = 9;
512 /* C++ namespaces do have scheme:
513 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
514 since filename might contain extra underscores there seems
515 to be no better chance then walk all possible offsets looking
516 for magicnumber. */
517 if (offset)
519 for (i = i + offset; string[i]; i++)
520 if (string[i]=='_')
522 int y;
524 for (y = 1; y < 9; y++)
525 if (!(string[i + y] >= '0' && string[i + y] <= '9')
526 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
527 break;
528 if (y != 9 || string[i + 9] != '_')
529 continue;
530 for (y = 10; y < 18; y++)
531 if (!(string[i + y] >= '0' && string[i + y] <= '9')
532 && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
533 break;
534 if (y != 18)
535 continue;
536 if (!dup)
537 string = dup = xstrdup (string);
538 for (y = 10; y < 18; y++)
539 dup[i + y] = '0';
541 break;
545 chksum = crc32_string (chksum, string);
546 free (dup);
548 return chksum;
551 /* Compute checksum for the current function. We generate a CRC32. */
553 unsigned
554 coverage_compute_lineno_checksum (void)
556 expanded_location xloc
557 = expand_location (DECL_SOURCE_LOCATION (current_function_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 (current_function_decl)));
564 return chksum;
567 /* Compute profile ID. This is better to be unique in whole program. */
569 unsigned
570 coverage_compute_profile_id (struct cgraph_node *n)
572 unsigned chksum;
574 /* Externally visible symbols have unique name. */
575 if (TREE_PUBLIC (n->decl) || DECL_EXTERNAL (n->decl))
577 chksum = coverage_checksum_string
578 (0, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl)));
580 else
582 expanded_location xloc
583 = expand_location (DECL_SOURCE_LOCATION (n->decl));
585 chksum = xloc.line;
586 chksum = coverage_checksum_string (chksum, xloc.file);
587 chksum = coverage_checksum_string
588 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl)));
589 if (first_global_object_name)
590 chksum = coverage_checksum_string
591 (chksum, first_global_object_name);
592 chksum = coverage_checksum_string
593 (chksum, aux_base_name);
596 /* Non-negative integers are hopefully small enough to fit in all targets. */
597 return chksum & 0x7fffffff;
600 /* Compute cfg checksum for the function FN given as argument.
601 The checksum is calculated carefully so that
602 source code changes that doesn't affect the control flow graph
603 won't change the checksum.
604 This is to make the profile data useable across source code change.
605 The downside of this is that the compiler may use potentially
606 wrong profile data - that the source code change has non-trivial impact
607 on the validity of profile data (e.g. the reversed condition)
608 but the compiler won't detect the change and use the wrong profile data. */
610 unsigned
611 coverage_compute_cfg_checksum (struct function *fn)
613 basic_block bb;
614 unsigned chksum = n_basic_blocks_for_fn (fn);
616 FOR_EACH_BB_FN (bb, fn)
618 edge e;
619 edge_iterator ei;
620 chksum = crc32_byte (chksum, bb->index);
621 FOR_EACH_EDGE (e, ei, bb->succs)
623 chksum = crc32_byte (chksum, e->dest->index);
627 return chksum;
630 /* Begin output to the notes file for the current function.
631 Writes the function header. Returns nonzero if data should be output. */
634 coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
636 expanded_location xloc;
637 unsigned long offset;
639 /* We don't need to output .gcno file unless we're under -ftest-coverage
640 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
641 if (no_coverage || !bbg_file_name)
642 return 0;
644 xloc = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
646 /* Announce function */
647 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
648 gcov_write_unsigned (current_function_funcdef_no + 1);
649 gcov_write_unsigned (lineno_checksum);
650 gcov_write_unsigned (cfg_checksum);
651 gcov_write_string (IDENTIFIER_POINTER
652 (DECL_ASSEMBLER_NAME (current_function_decl)));
653 gcov_write_string (xloc.file);
654 gcov_write_unsigned (xloc.line);
655 gcov_write_length (offset);
657 return !gcov_is_error ();
660 /* Finish coverage data for the current function. Verify no output
661 error has occurred. Save function coverage counts. */
663 void
664 coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum)
666 unsigned i;
668 if (bbg_file_name && gcov_is_error ())
670 warning (0, "error writing %qs", bbg_file_name);
671 unlink (bbg_file_name);
672 bbg_file_name = NULL;
675 if (fn_ctr_mask)
677 struct coverage_data *item = 0;
679 /* If the function is extern (i.e. extern inline), then we won't
680 be outputting it, so don't chain it onto the function
681 list. */
682 if (!DECL_EXTERNAL (current_function_decl))
684 item = ggc_alloc<coverage_data> ();
686 item->ident = current_function_funcdef_no + 1;
687 item->lineno_checksum = lineno_checksum;
688 item->cfg_checksum = cfg_checksum;
690 item->fn_decl = current_function_decl;
691 item->next = 0;
692 *functions_tail = item;
693 functions_tail = &item->next;
696 for (i = 0; i != GCOV_COUNTERS; i++)
698 tree var = fn_v_ctrs[i];
700 if (item)
701 item->ctr_vars[i] = var;
702 if (var)
704 tree array_type = build_index_type (size_int (fn_n_ctrs[i] - 1));
705 array_type = build_array_type (get_gcov_type (), array_type);
706 TREE_TYPE (var) = array_type;
707 DECL_SIZE (var) = TYPE_SIZE (array_type);
708 DECL_SIZE_UNIT (var) = TYPE_SIZE_UNIT (array_type);
709 varpool_finalize_decl (var);
712 fn_b_ctrs[i] = fn_n_ctrs[i] = 0;
713 fn_v_ctrs[i] = NULL_TREE;
715 prg_ctr_mask |= fn_ctr_mask;
716 fn_ctr_mask = 0;
720 /* Build a coverage variable of TYPE for function FN_DECL. If COUNTER
721 >= 0 it is a counter array, otherwise it is the function structure. */
723 static tree
724 build_var (tree fn_decl, tree type, int counter)
726 tree var = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, type);
727 const char *fn_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn_decl));
728 char *buf;
729 size_t fn_name_len, len;
731 fn_name = targetm.strip_name_encoding (fn_name);
732 fn_name_len = strlen (fn_name);
733 buf = XALLOCAVEC (char, fn_name_len + 8 + sizeof (int) * 3);
735 if (counter < 0)
736 strcpy (buf, "__gcov__");
737 else
738 sprintf (buf, "__gcov%u_", counter);
739 len = strlen (buf);
740 #ifndef NO_DOT_IN_LABEL
741 buf[len - 1] = '.';
742 #elif !defined NO_DOLLAR_IN_LABEL
743 buf[len - 1] = '$';
744 #endif
745 memcpy (buf + len, fn_name, fn_name_len + 1);
746 DECL_NAME (var) = get_identifier (buf);
747 TREE_STATIC (var) = 1;
748 TREE_ADDRESSABLE (var) = 1;
749 DECL_NONALIASED (var) = 1;
750 DECL_ALIGN (var) = TYPE_ALIGN (type);
752 return var;
755 /* Creates the gcov_fn_info RECORD_TYPE. */
757 static void
758 build_fn_info_type (tree type, unsigned counters, tree gcov_info_type)
760 tree ctr_info = lang_hooks.types.make_type (RECORD_TYPE);
761 tree field, fields;
762 tree array_type;
764 gcc_assert (counters);
766 /* ctr_info::num */
767 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
768 get_gcov_unsigned_t ());
769 fields = field;
771 /* ctr_info::values */
772 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
773 build_pointer_type (get_gcov_type ()));
774 DECL_CHAIN (field) = fields;
775 fields = field;
777 finish_builtin_struct (ctr_info, "__gcov_ctr_info", fields, NULL_TREE);
779 /* key */
780 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
781 build_pointer_type (build_qualified_type
782 (gcov_info_type, TYPE_QUAL_CONST)));
783 fields = field;
785 /* ident */
786 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
787 get_gcov_unsigned_t ());
788 DECL_CHAIN (field) = fields;
789 fields = field;
791 /* lineno_checksum */
792 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
793 get_gcov_unsigned_t ());
794 DECL_CHAIN (field) = fields;
795 fields = field;
797 /* cfg 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 array_type = build_index_type (size_int (counters - 1));
804 array_type = build_array_type (ctr_info, array_type);
806 /* counters */
807 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, array_type);
808 DECL_CHAIN (field) = fields;
809 fields = field;
811 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
814 /* Returns a CONSTRUCTOR for a gcov_fn_info. DATA is
815 the coverage data for the function and TYPE is the gcov_fn_info
816 RECORD_TYPE. KEY is the object file key. */
818 static tree
819 build_fn_info (const struct coverage_data *data, tree type, tree key)
821 tree fields = TYPE_FIELDS (type);
822 tree ctr_type;
823 unsigned ix;
824 vec<constructor_elt, va_gc> *v1 = NULL;
825 vec<constructor_elt, va_gc> *v2 = NULL;
827 /* key */
828 CONSTRUCTOR_APPEND_ELT (v1, fields,
829 build1 (ADDR_EXPR, TREE_TYPE (fields), key));
830 fields = DECL_CHAIN (fields);
832 /* ident */
833 CONSTRUCTOR_APPEND_ELT (v1, fields,
834 build_int_cstu (get_gcov_unsigned_t (),
835 data->ident));
836 fields = DECL_CHAIN (fields);
838 /* lineno_checksum */
839 CONSTRUCTOR_APPEND_ELT (v1, fields,
840 build_int_cstu (get_gcov_unsigned_t (),
841 data->lineno_checksum));
842 fields = DECL_CHAIN (fields);
844 /* cfg_checksum */
845 CONSTRUCTOR_APPEND_ELT (v1, fields,
846 build_int_cstu (get_gcov_unsigned_t (),
847 data->cfg_checksum));
848 fields = DECL_CHAIN (fields);
850 /* counters */
851 ctr_type = TREE_TYPE (TREE_TYPE (fields));
852 for (ix = 0; ix != GCOV_COUNTERS; ix++)
853 if (prg_ctr_mask & (1 << ix))
855 vec<constructor_elt, va_gc> *ctr = NULL;
856 tree var = data->ctr_vars[ix];
857 unsigned count = 0;
859 if (var)
860 count
861 = tree_to_shwi (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var))))
862 + 1;
864 CONSTRUCTOR_APPEND_ELT (ctr, TYPE_FIELDS (ctr_type),
865 build_int_cstu (get_gcov_unsigned_t (),
866 count));
868 if (var)
869 CONSTRUCTOR_APPEND_ELT (ctr, DECL_CHAIN (TYPE_FIELDS (ctr_type)),
870 build_fold_addr_expr (var));
872 CONSTRUCTOR_APPEND_ELT (v2, NULL, build_constructor (ctr_type, ctr));
875 CONSTRUCTOR_APPEND_ELT (v1, fields,
876 build_constructor (TREE_TYPE (fields), v2));
878 return build_constructor (type, v1);
881 /* Create gcov_info struct. TYPE is the incomplete RECORD_TYPE to be
882 completed, and FN_INFO_PTR_TYPE is a pointer to the function info type. */
884 static void
885 build_info_type (tree type, tree fn_info_ptr_type)
887 tree field, fields = NULL_TREE;
888 tree merge_fn_type;
890 /* Version ident */
891 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
892 get_gcov_unsigned_t ());
893 DECL_CHAIN (field) = fields;
894 fields = field;
896 /* next pointer */
897 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
898 build_pointer_type (build_qualified_type
899 (type, TYPE_QUAL_CONST)));
900 DECL_CHAIN (field) = fields;
901 fields = field;
903 /* stamp */
904 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
905 get_gcov_unsigned_t ());
906 DECL_CHAIN (field) = fields;
907 fields = field;
909 /* Filename */
910 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
911 build_pointer_type (build_qualified_type
912 (char_type_node, TYPE_QUAL_CONST)));
913 DECL_CHAIN (field) = fields;
914 fields = field;
916 /* merge fn array */
917 merge_fn_type
918 = build_function_type_list (void_type_node,
919 build_pointer_type (get_gcov_type ()),
920 get_gcov_unsigned_t (), NULL_TREE);
921 merge_fn_type
922 = build_array_type (build_pointer_type (merge_fn_type),
923 build_index_type (size_int (GCOV_COUNTERS - 1)));
924 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
925 merge_fn_type);
926 DECL_CHAIN (field) = fields;
927 fields = field;
929 /* n_functions */
930 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
931 get_gcov_unsigned_t ());
932 DECL_CHAIN (field) = fields;
933 fields = field;
935 /* function_info pointer pointer */
936 fn_info_ptr_type = build_pointer_type
937 (build_qualified_type (fn_info_ptr_type, TYPE_QUAL_CONST));
938 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
939 fn_info_ptr_type);
940 DECL_CHAIN (field) = fields;
941 fields = field;
943 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
946 /* Returns a CONSTRUCTOR for the gcov_info object. INFO_TYPE is the
947 gcov_info structure type, FN_ARY is the array of pointers to
948 function info objects. */
950 static tree
951 build_info (tree info_type, tree fn_ary)
953 tree info_fields = TYPE_FIELDS (info_type);
954 tree merge_fn_type, n_funcs;
955 unsigned ix;
956 tree filename_string;
957 int da_file_name_len;
958 vec<constructor_elt, va_gc> *v1 = NULL;
959 vec<constructor_elt, va_gc> *v2 = NULL;
961 /* Version ident */
962 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
963 build_int_cstu (TREE_TYPE (info_fields),
964 GCOV_VERSION));
965 info_fields = DECL_CHAIN (info_fields);
967 /* next -- NULL */
968 CONSTRUCTOR_APPEND_ELT (v1, info_fields, null_pointer_node);
969 info_fields = DECL_CHAIN (info_fields);
971 /* stamp */
972 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
973 build_int_cstu (TREE_TYPE (info_fields),
974 bbg_file_stamp));
975 info_fields = DECL_CHAIN (info_fields);
977 /* Filename */
978 da_file_name_len = strlen (da_file_name);
979 filename_string = build_string (da_file_name_len + 1, da_file_name);
980 TREE_TYPE (filename_string) = build_array_type
981 (char_type_node, build_index_type (size_int (da_file_name_len)));
982 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
983 build1 (ADDR_EXPR, TREE_TYPE (info_fields),
984 filename_string));
985 info_fields = DECL_CHAIN (info_fields);
987 /* merge fn array -- NULL slots indicate unmeasured counters */
988 merge_fn_type = TREE_TYPE (TREE_TYPE (info_fields));
989 for (ix = 0; ix != GCOV_COUNTERS; ix++)
991 tree ptr = null_pointer_node;
993 if ((1u << ix) & prg_ctr_mask)
995 tree merge_fn = build_decl (BUILTINS_LOCATION,
996 FUNCTION_DECL,
997 get_identifier (ctr_merge_functions[ix]),
998 TREE_TYPE (merge_fn_type));
999 DECL_EXTERNAL (merge_fn) = 1;
1000 TREE_PUBLIC (merge_fn) = 1;
1001 DECL_ARTIFICIAL (merge_fn) = 1;
1002 TREE_NOTHROW (merge_fn) = 1;
1003 /* Initialize assembler name so we can stream out. */
1004 DECL_ASSEMBLER_NAME (merge_fn);
1005 ptr = build1 (ADDR_EXPR, merge_fn_type, merge_fn);
1007 CONSTRUCTOR_APPEND_ELT (v2, NULL, ptr);
1009 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
1010 build_constructor (TREE_TYPE (info_fields), v2));
1011 info_fields = DECL_CHAIN (info_fields);
1013 /* n_functions */
1014 n_funcs = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (fn_ary)));
1015 n_funcs = fold_build2 (PLUS_EXPR, TREE_TYPE (info_fields),
1016 n_funcs, size_one_node);
1017 CONSTRUCTOR_APPEND_ELT (v1, info_fields, n_funcs);
1018 info_fields = DECL_CHAIN (info_fields);
1020 /* functions */
1021 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
1022 build1 (ADDR_EXPR, TREE_TYPE (info_fields), fn_ary));
1023 info_fields = DECL_CHAIN (info_fields);
1025 gcc_assert (!info_fields);
1026 return build_constructor (info_type, v1);
1029 /* Generate the constructor function to call __gcov_init. */
1031 static void
1032 build_init_ctor (tree gcov_info_type)
1034 tree ctor, stmt, init_fn;
1036 /* Build a decl for __gcov_init. */
1037 init_fn = build_pointer_type (gcov_info_type);
1038 init_fn = build_function_type_list (void_type_node, init_fn, NULL);
1039 init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
1040 get_identifier ("__gcov_init"), init_fn);
1041 TREE_PUBLIC (init_fn) = 1;
1042 DECL_EXTERNAL (init_fn) = 1;
1043 DECL_ASSEMBLER_NAME (init_fn);
1045 /* Generate a call to __gcov_init(&gcov_info). */
1046 ctor = NULL;
1047 stmt = build_fold_addr_expr (gcov_info_var);
1048 stmt = build_call_expr (init_fn, 1, stmt);
1049 append_to_statement_list (stmt, &ctor);
1051 /* Generate a constructor to run it. */
1052 cgraph_build_static_cdtor ('I', ctor, DEFAULT_INIT_PRIORITY);
1055 /* Create the gcov_info types and object. Generate the constructor
1056 function to call __gcov_init. Does not generate the initializer
1057 for the object. Returns TRUE if coverage data is being emitted. */
1059 static bool
1060 coverage_obj_init (void)
1062 tree gcov_info_type;
1063 unsigned n_counters = 0;
1064 unsigned ix;
1065 struct coverage_data *fn;
1066 struct coverage_data **fn_prev;
1067 char name_buf[32];
1069 no_coverage = 1; /* Disable any further coverage. */
1071 if (!prg_ctr_mask)
1072 return false;
1074 if (cgraph_dump_file)
1075 fprintf (cgraph_dump_file, "Using data file %s\n", da_file_name);
1077 /* Prune functions. */
1078 for (fn_prev = &functions_head; (fn = *fn_prev);)
1079 if (DECL_STRUCT_FUNCTION (fn->fn_decl))
1080 fn_prev = &fn->next;
1081 else
1082 /* The function is not being emitted, remove from list. */
1083 *fn_prev = fn->next;
1085 if (functions_head == NULL)
1086 return false;
1088 for (ix = 0; ix != GCOV_COUNTERS; ix++)
1089 if ((1u << ix) & prg_ctr_mask)
1090 n_counters++;
1092 /* Build the info and fn_info types. These are mutually recursive. */
1093 gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1094 gcov_fn_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1095 gcov_fn_info_ptr_type = build_pointer_type
1096 (build_qualified_type (gcov_fn_info_type, TYPE_QUAL_CONST));
1097 build_fn_info_type (gcov_fn_info_type, n_counters, gcov_info_type);
1098 build_info_type (gcov_info_type, gcov_fn_info_ptr_type);
1100 /* Build the gcov info var, this is referred to in its own
1101 initializer. */
1102 gcov_info_var = build_decl (BUILTINS_LOCATION,
1103 VAR_DECL, NULL_TREE, gcov_info_type);
1104 TREE_STATIC (gcov_info_var) = 1;
1105 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
1106 DECL_NAME (gcov_info_var) = get_identifier (name_buf);
1108 build_init_ctor (gcov_info_type);
1110 return true;
1113 /* Generate the coverage function info for FN and DATA. Append a
1114 pointer to that object to CTOR and return the appended CTOR. */
1116 static vec<constructor_elt, va_gc> *
1117 coverage_obj_fn (vec<constructor_elt, va_gc> *ctor, tree fn,
1118 struct coverage_data const *data)
1120 tree init = build_fn_info (data, gcov_fn_info_type, gcov_info_var);
1121 tree var = build_var (fn, gcov_fn_info_type, -1);
1123 DECL_INITIAL (var) = init;
1124 varpool_finalize_decl (var);
1126 CONSTRUCTOR_APPEND_ELT (ctor, NULL,
1127 build1 (ADDR_EXPR, gcov_fn_info_ptr_type, var));
1128 return ctor;
1131 /* Finalize the coverage data. Generates the array of pointers to
1132 function objects from CTOR. Generate the gcov_info initializer. */
1134 static void
1135 coverage_obj_finish (vec<constructor_elt, va_gc> *ctor)
1137 unsigned n_functions = vec_safe_length (ctor);
1138 tree fn_info_ary_type = build_array_type
1139 (build_qualified_type (gcov_fn_info_ptr_type, TYPE_QUAL_CONST),
1140 build_index_type (size_int (n_functions - 1)));
1141 tree fn_info_ary = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE,
1142 fn_info_ary_type);
1143 char name_buf[32];
1145 TREE_STATIC (fn_info_ary) = 1;
1146 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 1);
1147 DECL_NAME (fn_info_ary) = get_identifier (name_buf);
1148 DECL_INITIAL (fn_info_ary) = build_constructor (fn_info_ary_type, ctor);
1149 varpool_finalize_decl (fn_info_ary);
1151 DECL_INITIAL (gcov_info_var)
1152 = build_info (TREE_TYPE (gcov_info_var), fn_info_ary);
1153 varpool_finalize_decl (gcov_info_var);
1156 /* Perform file-level initialization. Read in data file, generate name
1157 of notes file. */
1159 void
1160 coverage_init (const char *filename)
1162 int len = strlen (filename);
1163 int prefix_len = 0;
1165 /* Since coverage_init is invoked very early, before the pass
1166 manager, we need to set up the dumping explicitly. This is
1167 similar to the handling in finish_optimization_passes. */
1168 int profile_pass_num =
1169 g->get_passes ()->get_pass_profile ()->static_pass_number;
1170 g->get_dumps ()->dump_start (profile_pass_num, NULL);
1172 if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
1173 profile_data_prefix = getpwd ();
1175 if (profile_data_prefix)
1176 prefix_len = strlen (profile_data_prefix);
1178 /* Name of da file. */
1179 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
1180 + prefix_len + 2);
1182 if (profile_data_prefix)
1184 memcpy (da_file_name, profile_data_prefix, prefix_len);
1185 da_file_name[prefix_len++] = '/';
1187 memcpy (da_file_name + prefix_len, filename, len);
1188 strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX);
1190 bbg_file_stamp = local_tick;
1192 if (flag_branch_probabilities)
1193 read_counts_file ();
1195 /* Name of bbg file. */
1196 if (flag_test_coverage && !flag_compare_debug)
1198 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1);
1199 memcpy (bbg_file_name, filename, len);
1200 strcpy (bbg_file_name + len, GCOV_NOTE_SUFFIX);
1202 if (!gcov_open (bbg_file_name, -1))
1204 error ("cannot open %s", bbg_file_name);
1205 bbg_file_name = NULL;
1207 else
1209 gcov_write_unsigned (GCOV_NOTE_MAGIC);
1210 gcov_write_unsigned (GCOV_VERSION);
1211 gcov_write_unsigned (bbg_file_stamp);
1215 g->get_dumps ()->dump_finish (profile_pass_num);
1218 /* Performs file-level cleanup. Close notes file, generate coverage
1219 variables and constructor. */
1221 void
1222 coverage_finish (void)
1224 if (bbg_file_name && gcov_close ())
1225 unlink (bbg_file_name);
1227 if (!flag_branch_probabilities && flag_test_coverage
1228 && (!local_tick || local_tick == (unsigned)-1))
1229 /* Only remove the da file, if we're emitting coverage code and
1230 cannot uniquely stamp it. If we can stamp it, libgcov will DTRT. */
1231 unlink (da_file_name);
1233 if (coverage_obj_init ())
1235 vec<constructor_elt, va_gc> *fn_ctor = NULL;
1236 struct coverage_data *fn;
1238 for (fn = functions_head; fn; fn = fn->next)
1239 fn_ctor = coverage_obj_fn (fn_ctor, fn->fn_decl, fn);
1240 coverage_obj_finish (fn_ctor);
1243 XDELETEVEC (da_file_name);
1244 da_file_name = NULL;
1247 #include "gt-coverage.h"