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