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
129 /* Return the type node for gcov_type. */
130
131 tree
get_gcov_type(void)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
get_gcov_unsigned_t(void)140 get_gcov_unsigned_t (void)
141 {
142 return lang_hooks.types.type_for_size (32, true);
143 }
144
145 static hashval_t
htab_counts_entry_hash(const void * of)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
htab_counts_entry_eq(const void * of1,const void * of2)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
htab_counts_entry_del(void * of)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
read_counts_file(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 *
get_coverage_counts(unsigned counter,unsigned expected,unsigned cfg_checksum,unsigned lineno_checksum,const struct gcov_ctr_summary ** summary)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
coverage_counter_alloc(unsigned counter,unsigned num)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
tree_coverage_counter_ref(unsigned counter,unsigned no)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
tree_coverage_counter_addr(unsigned counter,unsigned no)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
456
457 /* Generate a checksum for a string. CHKSUM is the current
458 checksum. */
459
460 static unsigned
coverage_checksum_string(unsigned chksum,const char * string)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
coverage_compute_lineno_checksum(void)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
coverage_compute_cfg_checksum(void)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
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
coverage_begin_function(unsigned lineno_checksum,unsigned cfg_checksum)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
coverage_end_function(unsigned lineno_checksum,unsigned cfg_checksum)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
build_var(tree fn_decl,tree type,int counter)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
build_fn_info_type(tree type,unsigned counters,tree gcov_info_type)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
build_fn_info(const struct coverage_data * data,tree type,tree key)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
build_info_type(tree type,tree fn_info_ptr_type)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
build_info(tree info_type,tree fn_ary)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
coverage_obj_init(void)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 if (functions_head == NULL)
992 return false;
993
994 for (ix = 0; ix != GCOV_COUNTERS; ix++)
995 if ((1u << ix) & prg_ctr_mask)
996 n_counters++;
997
998 /* Build the info and fn_info types. These are mutually recursive. */
999 gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1000 gcov_fn_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1001 gcov_fn_info_ptr_type = build_pointer_type
1002 (build_qualified_type (gcov_fn_info_type, TYPE_QUAL_CONST));
1003 build_fn_info_type (gcov_fn_info_type, n_counters, gcov_info_type);
1004 build_info_type (gcov_info_type, gcov_fn_info_ptr_type);
1005
1006 /* Build the gcov info var, this is referred to in its own
1007 initializer. */
1008 gcov_info_var = build_decl (BUILTINS_LOCATION,
1009 VAR_DECL, NULL_TREE, gcov_info_type);
1010 TREE_STATIC (gcov_info_var) = 1;
1011 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
1012 DECL_NAME (gcov_info_var) = get_identifier (name_buf);
1013
1014 /* Build a decl for __gcov_init. */
1015 init_fn = build_pointer_type (gcov_info_type);
1016 init_fn = build_function_type_list (void_type_node, init_fn, NULL);
1017 init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
1018 get_identifier ("__gcov_init"), init_fn);
1019 TREE_PUBLIC (init_fn) = 1;
1020 DECL_EXTERNAL (init_fn) = 1;
1021 DECL_ASSEMBLER_NAME (init_fn);
1022
1023 /* Generate a call to __gcov_init(&gcov_info). */
1024 ctor = NULL;
1025 stmt = build_fold_addr_expr (gcov_info_var);
1026 stmt = build_call_expr (init_fn, 1, stmt);
1027 append_to_statement_list (stmt, &ctor);
1028
1029 /* Generate a constructor to run it. */
1030 cgraph_build_static_cdtor ('I', ctor, DEFAULT_INIT_PRIORITY);
1031
1032 return true;
1033 }
1034
1035 /* Generate the coverage function info for FN and DATA. Append a
1036 pointer to that object to CTOR and return the appended CTOR. */
1037
VEC(constructor_elt,gc)1038 static VEC(constructor_elt,gc) *
1039 coverage_obj_fn (VEC(constructor_elt,gc) *ctor, tree fn,
1040 struct coverage_data const *data)
1041 {
1042 tree init = build_fn_info (data, gcov_fn_info_type, gcov_info_var);
1043 tree var = build_var (fn, gcov_fn_info_type, -1);
1044
1045 DECL_INITIAL (var) = init;
1046 varpool_finalize_decl (var);
1047
1048 CONSTRUCTOR_APPEND_ELT (ctor, NULL,
1049 build1 (ADDR_EXPR, gcov_fn_info_ptr_type, var));
1050 return ctor;
1051 }
1052
1053 /* Finalize the coverage data. Generates the array of pointers to
1054 function objects from CTOR. Generate the gcov_info initializer. */
1055
1056 static void
coverage_obj_finish(VEC (constructor_elt,gc)* ctor)1057 coverage_obj_finish (VEC(constructor_elt,gc) *ctor)
1058 {
1059 unsigned n_functions = VEC_length(constructor_elt, ctor);
1060 tree fn_info_ary_type = build_array_type
1061 (build_qualified_type (gcov_fn_info_ptr_type, TYPE_QUAL_CONST),
1062 build_index_type (size_int (n_functions - 1)));
1063 tree fn_info_ary = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE,
1064 fn_info_ary_type);
1065 char name_buf[32];
1066
1067 TREE_STATIC (fn_info_ary) = 1;
1068 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 1);
1069 DECL_NAME (fn_info_ary) = get_identifier (name_buf);
1070 DECL_INITIAL (fn_info_ary) = build_constructor (fn_info_ary_type, ctor);
1071 varpool_finalize_decl (fn_info_ary);
1072
1073 DECL_INITIAL (gcov_info_var)
1074 = build_info (TREE_TYPE (gcov_info_var), fn_info_ary);
1075 varpool_finalize_decl (gcov_info_var);
1076 }
1077
1078 /* Perform file-level initialization. Read in data file, generate name
1079 of graph file. */
1080
1081 void
coverage_init(const char * filename)1082 coverage_init (const char *filename)
1083 {
1084 int len = strlen (filename);
1085 int prefix_len = 0;
1086
1087 if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
1088 profile_data_prefix = getpwd ();
1089
1090 if (profile_data_prefix)
1091 prefix_len = strlen (profile_data_prefix);
1092
1093 /* Name of da file. */
1094 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
1095 + prefix_len + 2);
1096
1097 if (profile_data_prefix)
1098 {
1099 memcpy (da_file_name, profile_data_prefix, prefix_len);
1100 da_file_name[prefix_len++] = '/';
1101 }
1102 memcpy (da_file_name + prefix_len, filename, len);
1103 strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX);
1104
1105 if (flag_branch_probabilities)
1106 read_counts_file ();
1107
1108 /* Name of bbg file. */
1109 if (flag_test_coverage && !flag_compare_debug)
1110 {
1111 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1);
1112 memcpy (bbg_file_name, filename, len);
1113 strcpy (bbg_file_name + len, GCOV_NOTE_SUFFIX);
1114
1115 if (!gcov_open (bbg_file_name, -1))
1116 {
1117 error ("cannot open %s", bbg_file_name);
1118 bbg_file_name = NULL;
1119 }
1120 else
1121 {
1122 gcov_write_unsigned (GCOV_NOTE_MAGIC);
1123 gcov_write_unsigned (GCOV_VERSION);
1124 gcov_write_unsigned (local_tick);
1125 }
1126 }
1127 }
1128
1129 /* Performs file-level cleanup. Close graph file, generate coverage
1130 variables and constructor. */
1131
1132 void
coverage_finish(void)1133 coverage_finish (void)
1134 {
1135 if (bbg_file_name && gcov_close ())
1136 unlink (bbg_file_name);
1137
1138 if (!local_tick || local_tick == (unsigned)-1)
1139 /* Only remove the da file, if we cannot stamp it. If we can
1140 stamp it, libgcov will DTRT. */
1141 unlink (da_file_name);
1142
1143 if (coverage_obj_init ())
1144 {
1145 VEC(constructor_elt,gc) *fn_ctor = NULL;
1146 struct coverage_data *fn;
1147
1148 for (fn = functions_head; fn; fn = fn->next)
1149 fn_ctor = coverage_obj_fn (fn_ctor, fn->fn_decl, fn);
1150 coverage_obj_finish (fn_ctor);
1151 }
1152 }
1153
1154 #include "gt-coverage.h"
1155