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