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
10 This file is part of GCC.
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
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
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/>. */
31 #include "coretypes.h"
40 #include "basic-block.h"
45 #include "langhooks.h"
46 #include "hash-table.h"
47 #include "tree-iterator.h"
50 #include "diagnostic-core.h"
52 #include "filenames.h"
58 struct GTY((chain_next ("%h.next"))) coverage_data
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. */
68 /* Counts information for a function. */
69 typedef struct counts_entry
76 unsigned lineno_checksum
;
77 unsigned cfg_checksum
;
79 struct gcov_ctr_summary summary
;
81 /* hash_table support. */
82 typedef counts_entry value_type
;
83 typedef counts_entry compare_type
;
84 static inline hashval_t
hash (const value_type
*);
85 static int equal (const value_type
*, const compare_type
*);
86 static void remove (value_type
*);
89 static GTY(()) struct coverage_data
*functions_head
= 0;
90 static struct coverage_data
**functions_tail
= &functions_head
;
91 static unsigned no_coverage
= 0;
93 /* Cumulative counter information for whole program. */
94 static unsigned prg_ctr_mask
; /* Mask of counter types generated. */
96 /* Counter information for current function. */
97 static unsigned fn_ctr_mask
; /* Mask of counters used. */
98 static GTY(()) tree fn_v_ctrs
[GCOV_COUNTERS
]; /* counter variables. */
99 static unsigned fn_n_ctrs
[GCOV_COUNTERS
]; /* Counters allocated. */
100 static unsigned fn_b_ctrs
[GCOV_COUNTERS
]; /* Allocation base. */
102 /* Coverage info VAR_DECL and function info type nodes. */
103 static GTY(()) tree gcov_info_var
;
104 static GTY(()) tree gcov_fn_info_type
;
105 static GTY(()) tree gcov_fn_info_ptr_type
;
107 /* Name of the notes (gcno) output file. The "bbg" prefix is for
108 historical reasons, when the notes file contained only the
109 basic block graph notes.
110 If this is NULL we're not writing to the notes file. */
111 static char *bbg_file_name
;
113 /* File stamp for notes file. */
114 static unsigned bbg_file_stamp
;
116 /* Name of the count data (gcda) file. */
117 static char *da_file_name
;
119 /* The names of merge functions for counters. */
120 static const char *const ctr_merge_functions
[GCOV_COUNTERS
] = GCOV_MERGE_FUNCTIONS
;
121 static const char *const ctr_names
[GCOV_COUNTERS
] = GCOV_COUNTER_NAMES
;
123 /* Forward declarations. */
124 static void read_counts_file (void);
125 static tree
build_var (tree
, tree
, int);
126 static void build_fn_info_type (tree
, unsigned, tree
);
127 static void build_info_type (tree
, tree
);
128 static tree
build_fn_info (const struct coverage_data
*, tree
, tree
);
129 static tree
build_info (tree
, tree
);
130 static bool coverage_obj_init (void);
131 static vec
<constructor_elt
, va_gc
> *coverage_obj_fn
132 (vec
<constructor_elt
, va_gc
> *, tree
, struct coverage_data
const *);
133 static void coverage_obj_finish (vec
<constructor_elt
, va_gc
> *);
135 /* Return the type node for gcov_type. */
140 enum machine_mode mode
= smallest_mode_for_size (GCOV_TYPE_SIZE
, MODE_INT
);
141 return lang_hooks
.types
.type_for_mode (mode
, false);
144 /* Return the type node for gcov_unsigned_t. */
147 get_gcov_unsigned_t (void)
149 enum machine_mode mode
= smallest_mode_for_size (32, MODE_INT
);
150 return lang_hooks
.types
.type_for_mode (mode
, true);
154 counts_entry::hash (const value_type
*entry
)
156 return entry
->ident
* GCOV_COUNTERS
+ entry
->ctr
;
160 counts_entry::equal (const value_type
*entry1
,
161 const compare_type
*entry2
)
163 return entry1
->ident
== entry2
->ident
&& entry1
->ctr
== entry2
->ctr
;
167 counts_entry::remove (value_type
*entry
)
169 free (entry
->counts
);
173 /* Hash table of count data. */
174 static hash_table
<counts_entry
> counts_hash
;
176 /* Read in the counts file, if available. */
179 read_counts_file (void)
181 gcov_unsigned_t fn_ident
= 0;
182 struct gcov_summary summary
;
183 unsigned new_summary
= 1;
186 unsigned lineno_checksum
= 0;
187 unsigned cfg_checksum
= 0;
189 if (!gcov_open (da_file_name
, 1))
192 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC
))
194 warning (0, "%qs is not a gcov data file", da_file_name
);
198 else if ((tag
= gcov_read_unsigned ()) != GCOV_VERSION
)
202 GCOV_UNSIGNED2STRING (v
, tag
);
203 GCOV_UNSIGNED2STRING (e
, GCOV_VERSION
);
205 warning (0, "%qs is version %q.*s, expected version %q.*s",
206 da_file_name
, 4, v
, 4, e
);
211 /* Read the stamp, used for creating a generation count. */
212 tag
= gcov_read_unsigned ();
213 bbg_file_stamp
= crc32_unsigned (bbg_file_stamp
, tag
);
215 counts_hash
.create (10);
216 while ((tag
= gcov_read_unsigned ()))
218 gcov_unsigned_t length
;
219 gcov_position_t offset
;
221 length
= gcov_read_unsigned ();
222 offset
= gcov_position ();
223 if (tag
== GCOV_TAG_FUNCTION
)
227 fn_ident
= gcov_read_unsigned ();
228 lineno_checksum
= gcov_read_unsigned ();
229 cfg_checksum
= gcov_read_unsigned ();
232 fn_ident
= lineno_checksum
= cfg_checksum
= 0;
235 else if (tag
== GCOV_TAG_PROGRAM_SUMMARY
)
237 struct gcov_summary sum
;
241 memset (&summary
, 0, sizeof (summary
));
243 gcov_read_summary (&sum
);
244 for (ix
= 0; ix
!= GCOV_COUNTERS_SUMMABLE
; ix
++)
246 summary
.ctrs
[ix
].runs
+= sum
.ctrs
[ix
].runs
;
247 summary
.ctrs
[ix
].sum_all
+= sum
.ctrs
[ix
].sum_all
;
248 if (summary
.ctrs
[ix
].run_max
< sum
.ctrs
[ix
].run_max
)
249 summary
.ctrs
[ix
].run_max
= sum
.ctrs
[ix
].run_max
;
250 summary
.ctrs
[ix
].sum_max
+= sum
.ctrs
[ix
].sum_max
;
253 memcpy (summary
.ctrs
[GCOV_COUNTER_ARCS
].histogram
,
254 sum
.ctrs
[GCOV_COUNTER_ARCS
].histogram
,
255 sizeof (gcov_bucket_type
) * GCOV_HISTOGRAM_SIZE
);
257 gcov_histogram_merge (summary
.ctrs
[GCOV_COUNTER_ARCS
].histogram
,
258 sum
.ctrs
[GCOV_COUNTER_ARCS
].histogram
);
261 else if (GCOV_TAG_IS_COUNTER (tag
) && fn_ident
)
263 counts_entry_t
**slot
, *entry
, elt
;
264 unsigned n_counts
= GCOV_TAG_COUNTER_NUM (length
);
267 elt
.ident
= fn_ident
;
268 elt
.ctr
= GCOV_COUNTER_FOR_TAG (tag
);
270 slot
= counts_hash
.find_slot (&elt
, INSERT
);
274 *slot
= entry
= XCNEW (counts_entry_t
);
275 entry
->ident
= fn_ident
;
276 entry
->ctr
= elt
.ctr
;
277 entry
->lineno_checksum
= lineno_checksum
;
278 entry
->cfg_checksum
= cfg_checksum
;
279 if (elt
.ctr
< GCOV_COUNTERS_SUMMABLE
)
280 entry
->summary
= summary
.ctrs
[elt
.ctr
];
281 entry
->summary
.num
= n_counts
;
282 entry
->counts
= XCNEWVEC (gcov_type
, n_counts
);
284 else if (entry
->lineno_checksum
!= lineno_checksum
285 || entry
->cfg_checksum
!= cfg_checksum
)
287 error ("Profile data for function %u is corrupted", fn_ident
);
288 error ("checksum is (%x,%x) instead of (%x,%x)",
289 entry
->lineno_checksum
, entry
->cfg_checksum
,
290 lineno_checksum
, cfg_checksum
);
291 counts_hash
.dispose ();
294 else if (entry
->summary
.num
!= n_counts
)
296 error ("Profile data for function %u is corrupted", fn_ident
);
297 error ("number of counters is %d instead of %d", entry
->summary
.num
, n_counts
);
298 counts_hash
.dispose ();
301 else if (elt
.ctr
>= GCOV_COUNTERS_SUMMABLE
)
303 error ("cannot merge separate %s counters for function %u",
304 ctr_names
[elt
.ctr
], fn_ident
);
309 entry
->summary
.runs
+= summary
.ctrs
[elt
.ctr
].runs
;
310 entry
->summary
.sum_all
+= summary
.ctrs
[elt
.ctr
].sum_all
;
311 if (entry
->summary
.run_max
< summary
.ctrs
[elt
.ctr
].run_max
)
312 entry
->summary
.run_max
= summary
.ctrs
[elt
.ctr
].run_max
;
313 entry
->summary
.sum_max
+= summary
.ctrs
[elt
.ctr
].sum_max
;
315 for (ix
= 0; ix
!= n_counts
; ix
++)
316 entry
->counts
[ix
] += gcov_read_counter ();
319 gcov_sync (offset
, length
);
320 if ((is_error
= gcov_is_error ()))
322 error (is_error
< 0 ? "%qs has overflowed" : "%qs is corrupted",
324 counts_hash
.dispose ();
332 /* Returns the counters for a particular tag. */
335 get_coverage_counts (unsigned counter
, unsigned expected
,
336 unsigned cfg_checksum
, unsigned lineno_checksum
,
337 const struct gcov_ctr_summary
**summary
)
339 counts_entry_t
*entry
, elt
;
341 /* No hash table, no counts. */
342 if (!counts_hash
.is_created ())
344 static int warned
= 0;
347 inform (input_location
, (flag_guess_branch_prob
348 ? "file %s not found, execution counts estimated"
349 : "file %s not found, execution counts assumed to be zero"),
354 elt
.ident
= current_function_funcdef_no
+ 1;
356 entry
= counts_hash
.find (&elt
);
357 if (!entry
|| !entry
->summary
.num
)
358 /* The function was not emitted, or is weak and not chosen in the
359 final executable. Silently fail, because there's nothing we
363 if (entry
->cfg_checksum
!= cfg_checksum
364 || entry
->summary
.num
!= expected
)
366 static int warned
= 0;
367 bool warning_printed
= false;
368 tree id
= DECL_ASSEMBLER_NAME (current_function_decl
);
371 warning_at (input_location
, OPT_Wcoverage_mismatch
,
372 "the control flow of function %qE does not match "
373 "its profile data (counter %qs)", id
, ctr_names
[counter
]);
376 inform (input_location
, "use -Wno-error=coverage-mismatch to tolerate "
377 "the mismatch but performance may drop if the function is hot");
382 inform (input_location
, "coverage mismatch ignored");
383 inform (input_location
, flag_guess_branch_prob
384 ? G_("execution counts estimated")
385 : G_("execution counts assumed to be zero"));
386 if (!flag_guess_branch_prob
)
387 inform (input_location
,
388 "this can result in poorly optimized code");
394 else if (entry
->lineno_checksum
!= lineno_checksum
)
396 warning (0, "source locations for function %qE have changed,"
397 " the profile data may be out of date",
398 DECL_ASSEMBLER_NAME (current_function_decl
));
402 *summary
= &entry
->summary
;
404 return entry
->counts
;
407 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
408 allocation succeeded. */
411 coverage_counter_alloc (unsigned counter
, unsigned num
)
419 if (!fn_v_ctrs
[counter
])
421 tree array_type
= build_array_type (get_gcov_type (), NULL_TREE
);
424 = build_var (current_function_decl
, array_type
, counter
);
427 fn_b_ctrs
[counter
] = fn_n_ctrs
[counter
];
428 fn_n_ctrs
[counter
] += num
;
430 fn_ctr_mask
|= 1 << counter
;
434 /* Generate a tree to access COUNTER NO. */
437 tree_coverage_counter_ref (unsigned counter
, unsigned no
)
439 tree gcov_type_node
= get_gcov_type ();
441 gcc_assert (no
< fn_n_ctrs
[counter
] - fn_b_ctrs
[counter
]);
443 no
+= fn_b_ctrs
[counter
];
445 /* "no" here is an array index, scaled to bytes later. */
446 return build4 (ARRAY_REF
, gcov_type_node
, fn_v_ctrs
[counter
],
447 build_int_cst (integer_type_node
, no
), NULL
, NULL
);
450 /* Generate a tree to access the address of COUNTER NO. */
453 tree_coverage_counter_addr (unsigned counter
, unsigned no
)
455 tree gcov_type_node
= get_gcov_type ();
457 gcc_assert (no
< fn_n_ctrs
[counter
] - fn_b_ctrs
[counter
]);
458 no
+= fn_b_ctrs
[counter
];
460 /* "no" here is an array index, scaled to bytes later. */
461 return build_fold_addr_expr (build4 (ARRAY_REF
, gcov_type_node
,
463 build_int_cst (integer_type_node
, no
),
468 /* Generate a checksum for a string. CHKSUM is the current
472 coverage_checksum_string (unsigned chksum
, const char *string
)
477 /* Look for everything that looks if it were produced by
478 get_file_function_name and zero out the second part
479 that may result from flag_random_seed. This is not critical
480 as the checksums are used only for sanity checking. */
481 for (i
= 0; string
[i
]; i
++)
484 if (!strncmp (string
+ i
, "_GLOBAL__N_", 11))
486 if (!strncmp (string
+ i
, "_GLOBAL__", 9))
489 /* C++ namespaces do have scheme:
490 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
491 since filename might contain extra underscores there seems
492 to be no better chance then walk all possible offsets looking
496 for (i
= i
+ offset
; string
[i
]; i
++)
501 for (y
= 1; y
< 9; y
++)
502 if (!(string
[i
+ y
] >= '0' && string
[i
+ y
] <= '9')
503 && !(string
[i
+ y
] >= 'A' && string
[i
+ y
] <= 'F'))
505 if (y
!= 9 || string
[i
+ 9] != '_')
507 for (y
= 10; y
< 18; y
++)
508 if (!(string
[i
+ y
] >= '0' && string
[i
+ y
] <= '9')
509 && !(string
[i
+ y
] >= 'A' && string
[i
+ y
] <= 'F'))
514 string
= dup
= xstrdup (string
);
515 for (y
= 10; y
< 18; y
++)
522 chksum
= crc32_string (chksum
, string
);
528 /* Compute checksum for the current function. We generate a CRC32. */
531 coverage_compute_lineno_checksum (void)
533 expanded_location xloc
534 = expand_location (DECL_SOURCE_LOCATION (current_function_decl
));
535 unsigned chksum
= xloc
.line
;
537 chksum
= coverage_checksum_string (chksum
, xloc
.file
);
538 chksum
= coverage_checksum_string
539 (chksum
, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl
)));
544 /* Compute cfg checksum for the current function.
545 The checksum is calculated carefully so that
546 source code changes that doesn't affect the control flow graph
547 won't change the checksum.
548 This is to make the profile data useable across source code change.
549 The downside of this is that the compiler may use potentially
550 wrong profile data - that the source code change has non-trivial impact
551 on the validity of profile data (e.g. the reversed condition)
552 but the compiler won't detect the change and use the wrong profile data. */
555 coverage_compute_cfg_checksum (void)
558 unsigned chksum
= n_basic_blocks
;
564 chksum
= crc32_byte (chksum
, bb
->index
);
565 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
567 chksum
= crc32_byte (chksum
, e
->dest
->index
);
574 /* Begin output to the notes file for the current function.
575 Writes the function header. Returns nonzero if data should be output. */
578 coverage_begin_function (unsigned lineno_checksum
, unsigned cfg_checksum
)
580 expanded_location xloc
;
581 unsigned long offset
;
583 /* We don't need to output .gcno file unless we're under -ftest-coverage
584 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
585 if (no_coverage
|| !bbg_file_name
)
588 xloc
= expand_location (DECL_SOURCE_LOCATION (current_function_decl
));
590 /* Announce function */
591 offset
= gcov_write_tag (GCOV_TAG_FUNCTION
);
592 gcov_write_unsigned (current_function_funcdef_no
+ 1);
593 gcov_write_unsigned (lineno_checksum
);
594 gcov_write_unsigned (cfg_checksum
);
595 gcov_write_string (IDENTIFIER_POINTER
596 (DECL_ASSEMBLER_NAME (current_function_decl
)));
597 gcov_write_string (xloc
.file
);
598 gcov_write_unsigned (xloc
.line
);
599 gcov_write_length (offset
);
601 return !gcov_is_error ();
604 /* Finish coverage data for the current function. Verify no output
605 error has occurred. Save function coverage counts. */
608 coverage_end_function (unsigned lineno_checksum
, unsigned cfg_checksum
)
612 if (bbg_file_name
&& gcov_is_error ())
614 warning (0, "error writing %qs", bbg_file_name
);
615 unlink (bbg_file_name
);
616 bbg_file_name
= NULL
;
621 struct coverage_data
*item
= 0;
623 /* If the function is extern (i.e. extern inline), then we won't
624 be outputting it, so don't chain it onto the function
626 if (!DECL_EXTERNAL (current_function_decl
))
628 item
= ggc_alloc_coverage_data ();
630 item
->ident
= current_function_funcdef_no
+ 1;
631 item
->lineno_checksum
= lineno_checksum
;
632 item
->cfg_checksum
= cfg_checksum
;
634 item
->fn_decl
= current_function_decl
;
636 *functions_tail
= item
;
637 functions_tail
= &item
->next
;
640 for (i
= 0; i
!= GCOV_COUNTERS
; i
++)
642 tree var
= fn_v_ctrs
[i
];
645 item
->ctr_vars
[i
] = var
;
648 tree array_type
= build_index_type (size_int (fn_n_ctrs
[i
] - 1));
649 array_type
= build_array_type (get_gcov_type (), array_type
);
650 TREE_TYPE (var
) = array_type
;
651 DECL_SIZE (var
) = TYPE_SIZE (array_type
);
652 DECL_SIZE_UNIT (var
) = TYPE_SIZE_UNIT (array_type
);
653 varpool_finalize_decl (var
);
656 fn_b_ctrs
[i
] = fn_n_ctrs
[i
] = 0;
657 fn_v_ctrs
[i
] = NULL_TREE
;
659 prg_ctr_mask
|= fn_ctr_mask
;
664 /* Build a coverage variable of TYPE for function FN_DECL. If COUNTER
665 >= 0 it is a counter array, otherwise it is the function structure. */
668 build_var (tree fn_decl
, tree type
, int counter
)
670 tree var
= build_decl (BUILTINS_LOCATION
, VAR_DECL
, NULL_TREE
, type
);
671 const char *fn_name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn_decl
));
673 size_t fn_name_len
, len
;
675 fn_name
= targetm
.strip_name_encoding (fn_name
);
676 fn_name_len
= strlen (fn_name
);
677 buf
= XALLOCAVEC (char, fn_name_len
+ 8 + sizeof (int) * 3);
680 strcpy (buf
, "__gcov__");
682 sprintf (buf
, "__gcov%u_", counter
);
684 #ifndef NO_DOT_IN_LABEL
686 #elif !defined NO_DOLLAR_IN_LABEL
689 memcpy (buf
+ len
, fn_name
, fn_name_len
+ 1);
690 DECL_NAME (var
) = get_identifier (buf
);
691 TREE_STATIC (var
) = 1;
692 TREE_ADDRESSABLE (var
) = 1;
693 DECL_ALIGN (var
) = TYPE_ALIGN (type
);
698 /* Creates the gcov_fn_info RECORD_TYPE. */
701 build_fn_info_type (tree type
, unsigned counters
, tree gcov_info_type
)
703 tree ctr_info
= lang_hooks
.types
.make_type (RECORD_TYPE
);
707 gcc_assert (counters
);
710 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
711 get_gcov_unsigned_t ());
714 /* ctr_info::values */
715 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
716 build_pointer_type (get_gcov_type ()));
717 DECL_CHAIN (field
) = fields
;
720 finish_builtin_struct (ctr_info
, "__gcov_ctr_info", fields
, NULL_TREE
);
723 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
724 build_pointer_type (build_qualified_type
725 (gcov_info_type
, TYPE_QUAL_CONST
)));
729 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
730 get_gcov_unsigned_t ());
731 DECL_CHAIN (field
) = fields
;
734 /* lineno_checksum */
735 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
736 get_gcov_unsigned_t ());
737 DECL_CHAIN (field
) = fields
;
741 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
742 get_gcov_unsigned_t ());
743 DECL_CHAIN (field
) = fields
;
746 array_type
= build_index_type (size_int (counters
- 1));
747 array_type
= build_array_type (ctr_info
, array_type
);
750 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
, array_type
);
751 DECL_CHAIN (field
) = fields
;
754 finish_builtin_struct (type
, "__gcov_fn_info", fields
, NULL_TREE
);
757 /* Returns a CONSTRUCTOR for a gcov_fn_info. DATA is
758 the coverage data for the function and TYPE is the gcov_fn_info
759 RECORD_TYPE. KEY is the object file key. */
762 build_fn_info (const struct coverage_data
*data
, tree type
, tree key
)
764 tree fields
= TYPE_FIELDS (type
);
767 vec
<constructor_elt
, va_gc
> *v1
= NULL
;
768 vec
<constructor_elt
, va_gc
> *v2
= NULL
;
771 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
772 build1 (ADDR_EXPR
, TREE_TYPE (fields
), key
));
773 fields
= DECL_CHAIN (fields
);
776 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
777 build_int_cstu (get_gcov_unsigned_t (),
779 fields
= DECL_CHAIN (fields
);
781 /* lineno_checksum */
782 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
783 build_int_cstu (get_gcov_unsigned_t (),
784 data
->lineno_checksum
));
785 fields
= DECL_CHAIN (fields
);
788 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
789 build_int_cstu (get_gcov_unsigned_t (),
790 data
->cfg_checksum
));
791 fields
= DECL_CHAIN (fields
);
794 ctr_type
= TREE_TYPE (TREE_TYPE (fields
));
795 for (ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
796 if (prg_ctr_mask
& (1 << ix
))
798 vec
<constructor_elt
, va_gc
> *ctr
= NULL
;
799 tree var
= data
->ctr_vars
[ix
];
804 = tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var
))), 0)
807 CONSTRUCTOR_APPEND_ELT (ctr
, TYPE_FIELDS (ctr_type
),
808 build_int_cstu (get_gcov_unsigned_t (),
812 CONSTRUCTOR_APPEND_ELT (ctr
, DECL_CHAIN (TYPE_FIELDS (ctr_type
)),
813 build_fold_addr_expr (var
));
815 CONSTRUCTOR_APPEND_ELT (v2
, NULL
, build_constructor (ctr_type
, ctr
));
818 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
819 build_constructor (TREE_TYPE (fields
), v2
));
821 return build_constructor (type
, v1
);
824 /* Create gcov_info struct. TYPE is the incomplete RECORD_TYPE to be
825 completed, and FN_INFO_PTR_TYPE is a pointer to the function info type. */
828 build_info_type (tree type
, tree fn_info_ptr_type
)
830 tree field
, fields
= NULL_TREE
;
834 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
835 get_gcov_unsigned_t ());
836 DECL_CHAIN (field
) = fields
;
840 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
841 build_pointer_type (build_qualified_type
842 (type
, TYPE_QUAL_CONST
)));
843 DECL_CHAIN (field
) = fields
;
847 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
848 get_gcov_unsigned_t ());
849 DECL_CHAIN (field
) = fields
;
853 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
854 build_pointer_type (build_qualified_type
855 (char_type_node
, TYPE_QUAL_CONST
)));
856 DECL_CHAIN (field
) = fields
;
861 = build_function_type_list (void_type_node
,
862 build_pointer_type (get_gcov_type ()),
863 get_gcov_unsigned_t (), NULL_TREE
);
865 = build_array_type (build_pointer_type (merge_fn_type
),
866 build_index_type (size_int (GCOV_COUNTERS
- 1)));
867 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
869 DECL_CHAIN (field
) = fields
;
873 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
874 get_gcov_unsigned_t ());
875 DECL_CHAIN (field
) = fields
;
878 /* function_info pointer pointer */
879 fn_info_ptr_type
= build_pointer_type
880 (build_qualified_type (fn_info_ptr_type
, TYPE_QUAL_CONST
));
881 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
883 DECL_CHAIN (field
) = fields
;
886 finish_builtin_struct (type
, "__gcov_info", fields
, NULL_TREE
);
889 /* Returns a CONSTRUCTOR for the gcov_info object. INFO_TYPE is the
890 gcov_info structure type, FN_ARY is the array of pointers to
891 function info objects. */
894 build_info (tree info_type
, tree fn_ary
)
896 tree info_fields
= TYPE_FIELDS (info_type
);
897 tree merge_fn_type
, n_funcs
;
899 tree filename_string
;
900 int da_file_name_len
;
901 vec
<constructor_elt
, va_gc
> *v1
= NULL
;
902 vec
<constructor_elt
, va_gc
> *v2
= NULL
;
905 CONSTRUCTOR_APPEND_ELT (v1
, info_fields
,
906 build_int_cstu (TREE_TYPE (info_fields
),
908 info_fields
= DECL_CHAIN (info_fields
);
911 CONSTRUCTOR_APPEND_ELT (v1
, info_fields
, null_pointer_node
);
912 info_fields
= DECL_CHAIN (info_fields
);
915 CONSTRUCTOR_APPEND_ELT (v1
, info_fields
,
916 build_int_cstu (TREE_TYPE (info_fields
),
918 info_fields
= DECL_CHAIN (info_fields
);
921 da_file_name_len
= strlen (da_file_name
);
922 filename_string
= build_string (da_file_name_len
+ 1, da_file_name
);
923 TREE_TYPE (filename_string
) = build_array_type
924 (char_type_node
, build_index_type (size_int (da_file_name_len
)));
925 CONSTRUCTOR_APPEND_ELT (v1
, info_fields
,
926 build1 (ADDR_EXPR
, TREE_TYPE (info_fields
),
928 info_fields
= DECL_CHAIN (info_fields
);
930 /* merge fn array -- NULL slots indicate unmeasured counters */
931 merge_fn_type
= TREE_TYPE (TREE_TYPE (info_fields
));
932 for (ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
934 tree ptr
= null_pointer_node
;
936 if ((1u << ix
) & prg_ctr_mask
)
938 tree merge_fn
= build_decl (BUILTINS_LOCATION
,
940 get_identifier (ctr_merge_functions
[ix
]),
941 TREE_TYPE (merge_fn_type
));
942 DECL_EXTERNAL (merge_fn
) = 1;
943 TREE_PUBLIC (merge_fn
) = 1;
944 DECL_ARTIFICIAL (merge_fn
) = 1;
945 TREE_NOTHROW (merge_fn
) = 1;
946 /* Initialize assembler name so we can stream out. */
947 DECL_ASSEMBLER_NAME (merge_fn
);
948 ptr
= build1 (ADDR_EXPR
, merge_fn_type
, merge_fn
);
950 CONSTRUCTOR_APPEND_ELT (v2
, NULL
, ptr
);
952 CONSTRUCTOR_APPEND_ELT (v1
, info_fields
,
953 build_constructor (TREE_TYPE (info_fields
), v2
));
954 info_fields
= DECL_CHAIN (info_fields
);
957 n_funcs
= TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (fn_ary
)));
958 n_funcs
= fold_build2 (PLUS_EXPR
, TREE_TYPE (info_fields
),
959 n_funcs
, size_one_node
);
960 CONSTRUCTOR_APPEND_ELT (v1
, info_fields
, n_funcs
);
961 info_fields
= DECL_CHAIN (info_fields
);
964 CONSTRUCTOR_APPEND_ELT (v1
, info_fields
,
965 build1 (ADDR_EXPR
, TREE_TYPE (info_fields
), fn_ary
));
966 info_fields
= DECL_CHAIN (info_fields
);
968 gcc_assert (!info_fields
);
969 return build_constructor (info_type
, v1
);
972 /* Create the gcov_info types and object. Generate the constructor
973 function to call __gcov_init. Does not generate the initializer
974 for the object. Returns TRUE if coverage data is being emitted. */
977 coverage_obj_init (void)
979 tree gcov_info_type
, ctor
, stmt
, init_fn
;
980 unsigned n_counters
= 0;
982 struct coverage_data
*fn
;
983 struct coverage_data
**fn_prev
;
986 no_coverage
= 1; /* Disable any further coverage. */
991 if (cgraph_dump_file
)
992 fprintf (cgraph_dump_file
, "Using data file %s\n", da_file_name
);
994 /* Prune functions. */
995 for (fn_prev
= &functions_head
; (fn
= *fn_prev
);)
996 if (DECL_STRUCT_FUNCTION (fn
->fn_decl
))
999 /* The function is not being emitted, remove from list. */
1000 *fn_prev
= fn
->next
;
1002 for (ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
1003 if ((1u << ix
) & prg_ctr_mask
)
1006 /* Build the info and fn_info types. These are mutually recursive. */
1007 gcov_info_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1008 gcov_fn_info_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1009 gcov_fn_info_ptr_type
= build_pointer_type
1010 (build_qualified_type (gcov_fn_info_type
, TYPE_QUAL_CONST
));
1011 build_fn_info_type (gcov_fn_info_type
, n_counters
, gcov_info_type
);
1012 build_info_type (gcov_info_type
, gcov_fn_info_ptr_type
);
1014 /* Build the gcov info var, this is referred to in its own
1016 gcov_info_var
= build_decl (BUILTINS_LOCATION
,
1017 VAR_DECL
, NULL_TREE
, gcov_info_type
);
1018 TREE_STATIC (gcov_info_var
) = 1;
1019 ASM_GENERATE_INTERNAL_LABEL (name_buf
, "LPBX", 0);
1020 DECL_NAME (gcov_info_var
) = get_identifier (name_buf
);
1022 /* Build a decl for __gcov_init. */
1023 init_fn
= build_pointer_type (gcov_info_type
);
1024 init_fn
= build_function_type_list (void_type_node
, init_fn
, NULL
);
1025 init_fn
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
1026 get_identifier ("__gcov_init"), init_fn
);
1027 TREE_PUBLIC (init_fn
) = 1;
1028 DECL_EXTERNAL (init_fn
) = 1;
1029 DECL_ASSEMBLER_NAME (init_fn
);
1031 /* Generate a call to __gcov_init(&gcov_info). */
1033 stmt
= build_fold_addr_expr (gcov_info_var
);
1034 stmt
= build_call_expr (init_fn
, 1, stmt
);
1035 append_to_statement_list (stmt
, &ctor
);
1037 /* Generate a constructor to run it. */
1038 cgraph_build_static_cdtor ('I', ctor
, DEFAULT_INIT_PRIORITY
);
1043 /* Generate the coverage function info for FN and DATA. Append a
1044 pointer to that object to CTOR and return the appended CTOR. */
1046 static vec
<constructor_elt
, va_gc
> *
1047 coverage_obj_fn (vec
<constructor_elt
, va_gc
> *ctor
, tree fn
,
1048 struct coverage_data
const *data
)
1050 tree init
= build_fn_info (data
, gcov_fn_info_type
, gcov_info_var
);
1051 tree var
= build_var (fn
, gcov_fn_info_type
, -1);
1053 DECL_INITIAL (var
) = init
;
1054 varpool_finalize_decl (var
);
1056 CONSTRUCTOR_APPEND_ELT (ctor
, NULL
,
1057 build1 (ADDR_EXPR
, gcov_fn_info_ptr_type
, var
));
1061 /* Finalize the coverage data. Generates the array of pointers to
1062 function objects from CTOR. Generate the gcov_info initializer. */
1065 coverage_obj_finish (vec
<constructor_elt
, va_gc
> *ctor
)
1067 unsigned n_functions
= vec_safe_length (ctor
);
1068 tree fn_info_ary_type
= build_array_type
1069 (build_qualified_type (gcov_fn_info_ptr_type
, TYPE_QUAL_CONST
),
1070 build_index_type (size_int (n_functions
- 1)));
1071 tree fn_info_ary
= build_decl (BUILTINS_LOCATION
, VAR_DECL
, NULL_TREE
,
1075 TREE_STATIC (fn_info_ary
) = 1;
1076 ASM_GENERATE_INTERNAL_LABEL (name_buf
, "LPBX", 1);
1077 DECL_NAME (fn_info_ary
) = get_identifier (name_buf
);
1078 DECL_INITIAL (fn_info_ary
) = build_constructor (fn_info_ary_type
, ctor
);
1079 varpool_finalize_decl (fn_info_ary
);
1081 DECL_INITIAL (gcov_info_var
)
1082 = build_info (TREE_TYPE (gcov_info_var
), fn_info_ary
);
1083 varpool_finalize_decl (gcov_info_var
);
1086 /* Perform file-level initialization. Read in data file, generate name
1090 coverage_init (const char *filename
)
1092 int len
= strlen (filename
);
1095 if (!profile_data_prefix
&& !IS_ABSOLUTE_PATH (filename
))
1096 profile_data_prefix
= getpwd ();
1098 if (profile_data_prefix
)
1099 prefix_len
= strlen (profile_data_prefix
);
1101 /* Name of da file. */
1102 da_file_name
= XNEWVEC (char, len
+ strlen (GCOV_DATA_SUFFIX
)
1105 if (profile_data_prefix
)
1107 memcpy (da_file_name
, profile_data_prefix
, prefix_len
);
1108 da_file_name
[prefix_len
++] = '/';
1110 memcpy (da_file_name
+ prefix_len
, filename
, len
);
1111 strcpy (da_file_name
+ prefix_len
+ len
, GCOV_DATA_SUFFIX
);
1113 bbg_file_stamp
= local_tick
;
1115 if (flag_branch_probabilities
)
1116 read_counts_file ();
1118 /* Name of bbg file. */
1119 if (flag_test_coverage
&& !flag_compare_debug
)
1121 bbg_file_name
= XNEWVEC (char, len
+ strlen (GCOV_NOTE_SUFFIX
) + 1);
1122 memcpy (bbg_file_name
, filename
, len
);
1123 strcpy (bbg_file_name
+ len
, GCOV_NOTE_SUFFIX
);
1125 if (!gcov_open (bbg_file_name
, -1))
1127 error ("cannot open %s", bbg_file_name
);
1128 bbg_file_name
= NULL
;
1132 gcov_write_unsigned (GCOV_NOTE_MAGIC
);
1133 gcov_write_unsigned (GCOV_VERSION
);
1134 gcov_write_unsigned (bbg_file_stamp
);
1139 /* Performs file-level cleanup. Close notes file, generate coverage
1140 variables and constructor. */
1143 coverage_finish (void)
1145 if (bbg_file_name
&& gcov_close ())
1146 unlink (bbg_file_name
);
1148 if (!flag_branch_probabilities
&& flag_test_coverage
1149 && (!local_tick
|| local_tick
== (unsigned)-1))
1150 /* Only remove the da file, if we're emitting coverage code and
1151 cannot uniquely stamp it. If we can stamp it, libgcov will DTRT. */
1152 unlink (da_file_name
);
1154 if (coverage_obj_init ())
1156 vec
<constructor_elt
, va_gc
> *fn_ctor
= NULL
;
1157 struct coverage_data
*fn
;
1159 for (fn
= functions_head
; fn
; fn
= fn
->next
)
1160 fn_ctor
= coverage_obj_fn (fn_ctor
, fn
->fn_decl
, fn
);
1161 coverage_obj_finish (fn_ctor
);
1165 #include "gt-coverage.h"