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"
47 #include "tree-iterator.h"
49 #include "tree-pass.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
;
82 static GTY(()) struct coverage_data
*functions_head
= 0;
83 static struct coverage_data
**functions_tail
= &functions_head
;
84 static unsigned no_coverage
= 0;
86 /* Cumulative counter information for whole program. */
87 static unsigned prg_ctr_mask
; /* Mask of counter types generated. */
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. */
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
;
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
;
104 /* File stamp for graph file. */
105 static unsigned bbg_file_stamp
;
107 /* Name of the count data file. */
108 static char *da_file_name
;
110 /* Hash table of count data. */
111 static htab_t counts_hash
= NULL
;
113 /* The names of merge functions for counters. */
114 static const char *const ctr_merge_functions
[GCOV_COUNTERS
] = GCOV_MERGE_FUNCTIONS
;
115 static const char *const ctr_names
[GCOV_COUNTERS
] = GCOV_COUNTER_NAMES
;
117 /* Forward declarations. */
118 static hashval_t
htab_counts_entry_hash (const void *);
119 static int htab_counts_entry_eq (const void *, const void *);
120 static void htab_counts_entry_del (void *);
121 static void read_counts_file (void);
122 static tree
build_var (tree
, tree
, int);
123 static void build_fn_info_type (tree
, unsigned, tree
);
124 static void build_info_type (tree
, tree
);
125 static tree
build_fn_info (const struct coverage_data
*, tree
, tree
);
126 static tree
build_info (tree
, tree
);
127 static bool coverage_obj_init (void);
128 static VEC(constructor_elt
,gc
) *coverage_obj_fn
129 (VEC(constructor_elt
,gc
) *, tree
, struct coverage_data
const *);
130 static void coverage_obj_finish (VEC(constructor_elt
,gc
) *);
132 /* Return the type node for gcov_type. */
137 enum machine_mode mode
= smallest_mode_for_size (GCOV_TYPE_SIZE
, MODE_INT
);
138 return lang_hooks
.types
.type_for_mode (mode
, false);
141 /* Return the type node for gcov_unsigned_t. */
144 get_gcov_unsigned_t (void)
146 enum machine_mode mode
= smallest_mode_for_size (32, MODE_INT
);
147 return lang_hooks
.types
.type_for_mode (mode
, true);
151 htab_counts_entry_hash (const void *of
)
153 const counts_entry_t
*const entry
= (const counts_entry_t
*) of
;
155 return entry
->ident
* GCOV_COUNTERS
+ entry
->ctr
;
159 htab_counts_entry_eq (const void *of1
, const void *of2
)
161 const counts_entry_t
*const entry1
= (const counts_entry_t
*) of1
;
162 const counts_entry_t
*const entry2
= (const counts_entry_t
*) of2
;
164 return entry1
->ident
== entry2
->ident
&& entry1
->ctr
== entry2
->ctr
;
168 htab_counts_entry_del (void *of
)
170 counts_entry_t
*const entry
= (counts_entry_t
*) of
;
172 free (entry
->counts
);
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
= htab_create (10,
216 htab_counts_entry_hash
, htab_counts_entry_eq
,
217 htab_counts_entry_del
);
218 while ((tag
= gcov_read_unsigned ()))
220 gcov_unsigned_t length
;
221 gcov_position_t offset
;
223 length
= gcov_read_unsigned ();
224 offset
= gcov_position ();
225 if (tag
== GCOV_TAG_FUNCTION
)
229 fn_ident
= gcov_read_unsigned ();
230 lineno_checksum
= gcov_read_unsigned ();
231 cfg_checksum
= gcov_read_unsigned ();
234 fn_ident
= lineno_checksum
= cfg_checksum
= 0;
237 else if (tag
== GCOV_TAG_PROGRAM_SUMMARY
)
239 struct gcov_summary sum
;
243 memset (&summary
, 0, sizeof (summary
));
245 gcov_read_summary (&sum
);
246 for (ix
= 0; ix
!= GCOV_COUNTERS_SUMMABLE
; ix
++)
248 summary
.ctrs
[ix
].runs
+= sum
.ctrs
[ix
].runs
;
249 summary
.ctrs
[ix
].sum_all
+= sum
.ctrs
[ix
].sum_all
;
250 if (summary
.ctrs
[ix
].run_max
< sum
.ctrs
[ix
].run_max
)
251 summary
.ctrs
[ix
].run_max
= sum
.ctrs
[ix
].run_max
;
252 summary
.ctrs
[ix
].sum_max
+= sum
.ctrs
[ix
].sum_max
;
256 else if (GCOV_TAG_IS_COUNTER (tag
) && fn_ident
)
258 counts_entry_t
**slot
, *entry
, elt
;
259 unsigned n_counts
= GCOV_TAG_COUNTER_NUM (length
);
262 elt
.ident
= fn_ident
;
263 elt
.ctr
= GCOV_COUNTER_FOR_TAG (tag
);
265 slot
= (counts_entry_t
**) htab_find_slot
266 (counts_hash
, &elt
, INSERT
);
270 *slot
= entry
= XCNEW (counts_entry_t
);
271 entry
->ident
= fn_ident
;
272 entry
->ctr
= elt
.ctr
;
273 entry
->lineno_checksum
= lineno_checksum
;
274 entry
->cfg_checksum
= cfg_checksum
;
275 entry
->summary
= summary
.ctrs
[elt
.ctr
];
276 entry
->summary
.num
= n_counts
;
277 entry
->counts
= XCNEWVEC (gcov_type
, n_counts
);
279 else if (entry
->lineno_checksum
!= lineno_checksum
280 || entry
->cfg_checksum
!= cfg_checksum
)
282 error ("Profile data for function %u is corrupted", fn_ident
);
283 error ("checksum is (%x,%x) instead of (%x,%x)",
284 entry
->lineno_checksum
, entry
->cfg_checksum
,
285 lineno_checksum
, cfg_checksum
);
286 htab_delete (counts_hash
);
289 else if (entry
->summary
.num
!= n_counts
)
291 error ("Profile data for function %u is corrupted", fn_ident
);
292 error ("number of counters is %d instead of %d", entry
->summary
.num
, n_counts
);
293 htab_delete (counts_hash
);
296 else if (elt
.ctr
>= GCOV_COUNTERS_SUMMABLE
)
298 error ("cannot merge separate %s counters for function %u",
299 ctr_names
[elt
.ctr
], fn_ident
);
304 entry
->summary
.runs
+= summary
.ctrs
[elt
.ctr
].runs
;
305 entry
->summary
.sum_all
+= summary
.ctrs
[elt
.ctr
].sum_all
;
306 if (entry
->summary
.run_max
< summary
.ctrs
[elt
.ctr
].run_max
)
307 entry
->summary
.run_max
= summary
.ctrs
[elt
.ctr
].run_max
;
308 entry
->summary
.sum_max
+= summary
.ctrs
[elt
.ctr
].sum_max
;
310 for (ix
= 0; ix
!= n_counts
; ix
++)
311 entry
->counts
[ix
] += gcov_read_counter ();
314 gcov_sync (offset
, length
);
315 if ((is_error
= gcov_is_error ()))
317 error (is_error
< 0 ? "%qs has overflowed" : "%qs is corrupted",
319 htab_delete (counts_hash
);
327 /* Returns the counters for a particular tag. */
330 get_coverage_counts (unsigned counter
, unsigned expected
,
331 unsigned cfg_checksum
, unsigned lineno_checksum
,
332 const struct gcov_ctr_summary
**summary
)
334 counts_entry_t
*entry
, elt
;
336 /* No hash table, no counts. */
339 static int warned
= 0;
342 inform (input_location
, (flag_guess_branch_prob
343 ? "file %s not found, execution counts estimated"
344 : "file %s not found, execution counts assumed to be zero"),
349 elt
.ident
= current_function_funcdef_no
+ 1;
351 entry
= (counts_entry_t
*) htab_find (counts_hash
, &elt
);
352 if (!entry
|| !entry
->summary
.num
)
353 /* The function was not emitted, or is weak and not chosen in the
354 final executable. Silently fail, because there's nothing we
358 if (entry
->cfg_checksum
!= cfg_checksum
359 || entry
->summary
.num
!= expected
)
361 static int warned
= 0;
362 bool warning_printed
= false;
363 tree id
= DECL_ASSEMBLER_NAME (current_function_decl
);
366 warning_at (input_location
, OPT_Wcoverage_mismatch
,
367 "the control flow of function %qE does not match "
368 "its profile data (counter %qs)", id
, ctr_names
[counter
]);
371 inform (input_location
, "use -Wno-error=coverage-mismatch to tolerate "
372 "the mismatch but performance may drop if the function is hot");
377 inform (input_location
, "coverage mismatch ignored");
378 inform (input_location
, flag_guess_branch_prob
379 ? G_("execution counts estimated")
380 : G_("execution counts assumed to be zero"));
381 if (!flag_guess_branch_prob
)
382 inform (input_location
,
383 "this can result in poorly optimized code");
389 else if (entry
->lineno_checksum
!= lineno_checksum
)
391 warning (0, "source locations for function %qE have changed,"
392 " the profile data may be out of date",
393 DECL_ASSEMBLER_NAME (current_function_decl
));
397 *summary
= &entry
->summary
;
399 return entry
->counts
;
402 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
403 allocation succeeded. */
406 coverage_counter_alloc (unsigned counter
, unsigned num
)
414 if (!fn_v_ctrs
[counter
])
416 tree array_type
= build_array_type (get_gcov_type (), NULL_TREE
);
419 = build_var (current_function_decl
, array_type
, counter
);
422 fn_b_ctrs
[counter
] = fn_n_ctrs
[counter
];
423 fn_n_ctrs
[counter
] += num
;
425 fn_ctr_mask
|= 1 << counter
;
429 /* Generate a tree to access COUNTER NO. */
432 tree_coverage_counter_ref (unsigned counter
, unsigned no
)
434 tree gcov_type_node
= get_gcov_type ();
436 gcc_assert (no
< fn_n_ctrs
[counter
] - fn_b_ctrs
[counter
]);
438 no
+= fn_b_ctrs
[counter
];
440 /* "no" here is an array index, scaled to bytes later. */
441 return build4 (ARRAY_REF
, gcov_type_node
, fn_v_ctrs
[counter
],
442 build_int_cst (integer_type_node
, no
), NULL
, NULL
);
445 /* Generate a tree to access the address of COUNTER NO. */
448 tree_coverage_counter_addr (unsigned counter
, unsigned no
)
450 tree gcov_type_node
= get_gcov_type ();
452 gcc_assert (no
< fn_n_ctrs
[counter
] - fn_b_ctrs
[counter
]);
453 no
+= fn_b_ctrs
[counter
];
455 /* "no" here is an array index, scaled to bytes later. */
456 return build_fold_addr_expr (build4 (ARRAY_REF
, gcov_type_node
,
458 build_int_cst (integer_type_node
, no
),
463 /* Generate a checksum for a string. CHKSUM is the current
467 coverage_checksum_string (unsigned chksum
, const char *string
)
472 /* Look for everything that looks if it were produced by
473 get_file_function_name and zero out the second part
474 that may result from flag_random_seed. This is not critical
475 as the checksums are used only for sanity checking. */
476 for (i
= 0; string
[i
]; i
++)
479 if (!strncmp (string
+ i
, "_GLOBAL__N_", 11))
481 if (!strncmp (string
+ i
, "_GLOBAL__", 9))
484 /* C++ namespaces do have scheme:
485 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
486 since filename might contain extra underscores there seems
487 to be no better chance then walk all possible offsets looking
491 for (i
= i
+ offset
; string
[i
]; i
++)
496 for (y
= 1; y
< 9; y
++)
497 if (!(string
[i
+ y
] >= '0' && string
[i
+ y
] <= '9')
498 && !(string
[i
+ y
] >= 'A' && string
[i
+ y
] <= 'F'))
500 if (y
!= 9 || string
[i
+ 9] != '_')
502 for (y
= 10; y
< 18; y
++)
503 if (!(string
[i
+ y
] >= '0' && string
[i
+ y
] <= '9')
504 && !(string
[i
+ y
] >= 'A' && string
[i
+ y
] <= 'F'))
509 string
= dup
= xstrdup (string
);
510 for (y
= 10; y
< 18; y
++)
517 chksum
= crc32_string (chksum
, string
);
523 /* Compute checksum for the current function. We generate a CRC32. */
526 coverage_compute_lineno_checksum (void)
528 expanded_location xloc
529 = expand_location (DECL_SOURCE_LOCATION (current_function_decl
));
530 unsigned chksum
= xloc
.line
;
532 chksum
= coverage_checksum_string (chksum
, xloc
.file
);
533 chksum
= coverage_checksum_string
534 (chksum
, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl
)));
539 /* Compute cfg checksum for the current function.
540 The checksum is calculated carefully so that
541 source code changes that doesn't affect the control flow graph
542 won't change the checksum.
543 This is to make the profile data useable across source code change.
544 The downside of this is that the compiler may use potentially
545 wrong profile data - that the source code change has non-trivial impact
546 on the validity of profile data (e.g. the reversed condition)
547 but the compiler won't detect the change and use the wrong profile data. */
550 coverage_compute_cfg_checksum (void)
553 unsigned chksum
= n_basic_blocks
;
559 chksum
= crc32_byte (chksum
, bb
->index
);
560 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
562 chksum
= crc32_byte (chksum
, e
->dest
->index
);
569 /* Begin output to the graph file for the current function.
570 Writes the function header. Returns nonzero if data should be output. */
573 coverage_begin_function (unsigned lineno_checksum
, unsigned cfg_checksum
)
575 expanded_location xloc
;
576 unsigned long offset
;
578 /* We don't need to output .gcno file unless we're under -ftest-coverage
579 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
580 if (no_coverage
|| !bbg_file_name
)
583 xloc
= expand_location (DECL_SOURCE_LOCATION (current_function_decl
));
585 /* Announce function */
586 offset
= gcov_write_tag (GCOV_TAG_FUNCTION
);
587 gcov_write_unsigned (current_function_funcdef_no
+ 1);
588 gcov_write_unsigned (lineno_checksum
);
589 gcov_write_unsigned (cfg_checksum
);
590 gcov_write_string (IDENTIFIER_POINTER
591 (DECL_ASSEMBLER_NAME (current_function_decl
)));
592 gcov_write_string (xloc
.file
);
593 gcov_write_unsigned (xloc
.line
);
594 gcov_write_length (offset
);
596 return !gcov_is_error ();
599 /* Finish coverage data for the current function. Verify no output
600 error has occurred. Save function coverage counts. */
603 coverage_end_function (unsigned lineno_checksum
, unsigned cfg_checksum
)
607 if (bbg_file_name
&& gcov_is_error ())
609 warning (0, "error writing %qs", bbg_file_name
);
610 unlink (bbg_file_name
);
611 bbg_file_name
= NULL
;
616 struct coverage_data
*item
= 0;
618 /* If the function is extern (i.e. extern inline), then we won't
619 be outputting it, so don't chain it onto the function
621 if (!DECL_EXTERNAL (current_function_decl
))
623 item
= ggc_alloc_coverage_data ();
625 item
->ident
= current_function_funcdef_no
+ 1;
626 item
->lineno_checksum
= lineno_checksum
;
627 item
->cfg_checksum
= cfg_checksum
;
629 item
->fn_decl
= current_function_decl
;
631 *functions_tail
= item
;
632 functions_tail
= &item
->next
;
635 for (i
= 0; i
!= GCOV_COUNTERS
; i
++)
637 tree var
= fn_v_ctrs
[i
];
640 item
->ctr_vars
[i
] = var
;
643 tree array_type
= build_index_type (size_int (fn_n_ctrs
[i
] - 1));
644 array_type
= build_array_type (get_gcov_type (), array_type
);
645 TREE_TYPE (var
) = array_type
;
646 DECL_SIZE (var
) = TYPE_SIZE (array_type
);
647 DECL_SIZE_UNIT (var
) = TYPE_SIZE_UNIT (array_type
);
648 varpool_finalize_decl (var
);
651 fn_b_ctrs
[i
] = fn_n_ctrs
[i
] = 0;
652 fn_v_ctrs
[i
] = NULL_TREE
;
654 prg_ctr_mask
|= fn_ctr_mask
;
659 /* Build a coverage variable of TYPE for function FN_DECL. If COUNTER
660 >= 0 it is a counter array, otherwise it is the function structure. */
663 build_var (tree fn_decl
, tree type
, int counter
)
665 tree var
= build_decl (BUILTINS_LOCATION
, VAR_DECL
, NULL_TREE
, type
);
666 const char *fn_name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn_decl
));
668 size_t fn_name_len
, len
;
670 fn_name
= targetm
.strip_name_encoding (fn_name
);
671 fn_name_len
= strlen (fn_name
);
672 buf
= XALLOCAVEC (char, fn_name_len
+ 8 + sizeof (int) * 3);
675 strcpy (buf
, "__gcov__");
677 sprintf (buf
, "__gcov%u_", counter
);
679 #ifndef NO_DOT_IN_LABEL
681 #elif !defined NO_DOLLAR_IN_LABEL
684 memcpy (buf
+ len
, fn_name
, fn_name_len
+ 1);
685 DECL_NAME (var
) = get_identifier (buf
);
686 TREE_STATIC (var
) = 1;
687 TREE_ADDRESSABLE (var
) = 1;
688 DECL_ALIGN (var
) = TYPE_ALIGN (type
);
693 /* Creates the gcov_fn_info RECORD_TYPE. */
696 build_fn_info_type (tree type
, unsigned counters
, tree gcov_info_type
)
698 tree ctr_info
= lang_hooks
.types
.make_type (RECORD_TYPE
);
702 gcc_assert (counters
);
705 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
706 get_gcov_unsigned_t ());
709 /* ctr_info::values */
710 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
711 build_pointer_type (get_gcov_type ()));
712 DECL_CHAIN (field
) = fields
;
715 finish_builtin_struct (ctr_info
, "__gcov_ctr_info", fields
, NULL_TREE
);
718 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
719 build_pointer_type (build_qualified_type
720 (gcov_info_type
, TYPE_QUAL_CONST
)));
724 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
725 get_gcov_unsigned_t ());
726 DECL_CHAIN (field
) = fields
;
729 /* lineno_checksum */
730 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
731 get_gcov_unsigned_t ());
732 DECL_CHAIN (field
) = fields
;
736 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
737 get_gcov_unsigned_t ());
738 DECL_CHAIN (field
) = fields
;
741 array_type
= build_index_type (size_int (counters
- 1));
742 array_type
= build_array_type (ctr_info
, array_type
);
745 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
, array_type
);
746 DECL_CHAIN (field
) = fields
;
749 finish_builtin_struct (type
, "__gcov_fn_info", fields
, NULL_TREE
);
752 /* Returns a CONSTRUCTOR for a gcov_fn_info. DATA is
753 the coverage data for the function and TYPE is the gcov_fn_info
754 RECORD_TYPE. KEY is the object file key. */
757 build_fn_info (const struct coverage_data
*data
, tree type
, tree key
)
759 tree fields
= TYPE_FIELDS (type
);
762 VEC(constructor_elt
,gc
) *v1
= NULL
;
763 VEC(constructor_elt
,gc
) *v2
= NULL
;
766 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
767 build1 (ADDR_EXPR
, TREE_TYPE (fields
), key
));
768 fields
= DECL_CHAIN (fields
);
771 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
772 build_int_cstu (get_gcov_unsigned_t (),
774 fields
= DECL_CHAIN (fields
);
776 /* lineno_checksum */
777 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
778 build_int_cstu (get_gcov_unsigned_t (),
779 data
->lineno_checksum
));
780 fields
= DECL_CHAIN (fields
);
783 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
784 build_int_cstu (get_gcov_unsigned_t (),
785 data
->cfg_checksum
));
786 fields
= DECL_CHAIN (fields
);
789 ctr_type
= TREE_TYPE (TREE_TYPE (fields
));
790 for (ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
791 if (prg_ctr_mask
& (1 << ix
))
793 VEC(constructor_elt
,gc
) *ctr
= NULL
;
794 tree var
= data
->ctr_vars
[ix
];
799 = tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var
))), 0)
802 CONSTRUCTOR_APPEND_ELT (ctr
, TYPE_FIELDS (ctr_type
),
803 build_int_cstu (get_gcov_unsigned_t (),
807 CONSTRUCTOR_APPEND_ELT (ctr
, DECL_CHAIN (TYPE_FIELDS (ctr_type
)),
808 build_fold_addr_expr (var
));
810 CONSTRUCTOR_APPEND_ELT (v2
, NULL
, build_constructor (ctr_type
, ctr
));
813 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
814 build_constructor (TREE_TYPE (fields
), v2
));
816 return build_constructor (type
, v1
);
819 /* Create gcov_info struct. TYPE is the incomplete RECORD_TYPE to be
820 completed, and FN_INFO_PTR_TYPE is a pointer to the function info type. */
823 build_info_type (tree type
, tree fn_info_ptr_type
)
825 tree field
, fields
= NULL_TREE
;
829 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
830 get_gcov_unsigned_t ());
831 DECL_CHAIN (field
) = fields
;
835 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
836 build_pointer_type (build_qualified_type
837 (type
, TYPE_QUAL_CONST
)));
838 DECL_CHAIN (field
) = fields
;
842 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
843 get_gcov_unsigned_t ());
844 DECL_CHAIN (field
) = fields
;
848 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
849 build_pointer_type (build_qualified_type
850 (char_type_node
, TYPE_QUAL_CONST
)));
851 DECL_CHAIN (field
) = fields
;
856 = build_function_type_list (void_type_node
,
857 build_pointer_type (get_gcov_type ()),
858 get_gcov_unsigned_t (), NULL_TREE
);
860 = build_array_type (build_pointer_type (merge_fn_type
),
861 build_index_type (size_int (GCOV_COUNTERS
- 1)));
862 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
864 DECL_CHAIN (field
) = fields
;
868 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
869 get_gcov_unsigned_t ());
870 DECL_CHAIN (field
) = fields
;
873 /* function_info pointer pointer */
874 fn_info_ptr_type
= build_pointer_type
875 (build_qualified_type (fn_info_ptr_type
, TYPE_QUAL_CONST
));
876 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, NULL_TREE
,
878 DECL_CHAIN (field
) = fields
;
881 finish_builtin_struct (type
, "__gcov_info", fields
, NULL_TREE
);
884 /* Returns a CONSTRUCTOR for the gcov_info object. INFO_TYPE is the
885 gcov_info structure type, FN_ARY is the array of pointers to
886 function info objects. */
889 build_info (tree info_type
, tree fn_ary
)
891 tree info_fields
= TYPE_FIELDS (info_type
);
892 tree merge_fn_type
, n_funcs
;
894 tree filename_string
;
895 int da_file_name_len
;
896 VEC(constructor_elt
,gc
) *v1
= NULL
;
897 VEC(constructor_elt
,gc
) *v2
= NULL
;
900 CONSTRUCTOR_APPEND_ELT (v1
, info_fields
,
901 build_int_cstu (TREE_TYPE (info_fields
),
903 info_fields
= DECL_CHAIN (info_fields
);
906 CONSTRUCTOR_APPEND_ELT (v1
, info_fields
, null_pointer_node
);
907 info_fields
= DECL_CHAIN (info_fields
);
910 CONSTRUCTOR_APPEND_ELT (v1
, info_fields
,
911 build_int_cstu (TREE_TYPE (info_fields
),
913 info_fields
= DECL_CHAIN (info_fields
);
916 da_file_name_len
= strlen (da_file_name
);
917 filename_string
= build_string (da_file_name_len
+ 1, da_file_name
);
918 TREE_TYPE (filename_string
) = build_array_type
919 (char_type_node
, build_index_type (size_int (da_file_name_len
)));
920 CONSTRUCTOR_APPEND_ELT (v1
, info_fields
,
921 build1 (ADDR_EXPR
, TREE_TYPE (info_fields
),
923 info_fields
= DECL_CHAIN (info_fields
);
925 /* merge fn array -- NULL slots indicate unmeasured counters */
926 merge_fn_type
= TREE_TYPE (TREE_TYPE (info_fields
));
927 for (ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
929 tree ptr
= null_pointer_node
;
931 if ((1u << ix
) & prg_ctr_mask
)
933 tree merge_fn
= build_decl (BUILTINS_LOCATION
,
935 get_identifier (ctr_merge_functions
[ix
]),
936 TREE_TYPE (merge_fn_type
));
937 DECL_EXTERNAL (merge_fn
) = 1;
938 TREE_PUBLIC (merge_fn
) = 1;
939 DECL_ARTIFICIAL (merge_fn
) = 1;
940 TREE_NOTHROW (merge_fn
) = 1;
941 /* Initialize assembler name so we can stream out. */
942 DECL_ASSEMBLER_NAME (merge_fn
);
943 ptr
= build1 (ADDR_EXPR
, merge_fn_type
, merge_fn
);
945 CONSTRUCTOR_APPEND_ELT (v2
, NULL
, ptr
);
947 CONSTRUCTOR_APPEND_ELT (v1
, info_fields
,
948 build_constructor (TREE_TYPE (info_fields
), v2
));
949 info_fields
= DECL_CHAIN (info_fields
);
952 n_funcs
= TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (fn_ary
)));
953 n_funcs
= fold_build2 (PLUS_EXPR
, TREE_TYPE (info_fields
),
954 n_funcs
, size_one_node
);
955 CONSTRUCTOR_APPEND_ELT (v1
, info_fields
, n_funcs
);
956 info_fields
= DECL_CHAIN (info_fields
);
959 CONSTRUCTOR_APPEND_ELT (v1
, info_fields
,
960 build1 (ADDR_EXPR
, TREE_TYPE (info_fields
), fn_ary
));
961 info_fields
= DECL_CHAIN (info_fields
);
963 gcc_assert (!info_fields
);
964 return build_constructor (info_type
, v1
);
967 /* Create the gcov_info types and object. Generate the constructor
968 function to call __gcov_init. Does not generate the initializer
969 for the object. Returns TRUE if coverage data is being emitted. */
972 coverage_obj_init (void)
974 tree gcov_info_type
, ctor
, stmt
, init_fn
;
975 unsigned n_counters
= 0;
977 struct coverage_data
*fn
;
978 struct coverage_data
**fn_prev
;
981 no_coverage
= 1; /* Disable any further coverage. */
986 if (cgraph_dump_file
)
987 fprintf (cgraph_dump_file
, "Using data file %s\n", da_file_name
);
989 /* Prune functions. */
990 for (fn_prev
= &functions_head
; (fn
= *fn_prev
);)
991 if (DECL_STRUCT_FUNCTION (fn
->fn_decl
))
994 /* The function is not being emitted, remove from list. */
997 for (ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
998 if ((1u << ix
) & prg_ctr_mask
)
1001 /* Build the info and fn_info types. These are mutually recursive. */
1002 gcov_info_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1003 gcov_fn_info_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1004 gcov_fn_info_ptr_type
= build_pointer_type
1005 (build_qualified_type (gcov_fn_info_type
, TYPE_QUAL_CONST
));
1006 build_fn_info_type (gcov_fn_info_type
, n_counters
, gcov_info_type
);
1007 build_info_type (gcov_info_type
, gcov_fn_info_ptr_type
);
1009 /* Build the gcov info var, this is referred to in its own
1011 gcov_info_var
= build_decl (BUILTINS_LOCATION
,
1012 VAR_DECL
, NULL_TREE
, gcov_info_type
);
1013 TREE_STATIC (gcov_info_var
) = 1;
1014 ASM_GENERATE_INTERNAL_LABEL (name_buf
, "LPBX", 0);
1015 DECL_NAME (gcov_info_var
) = get_identifier (name_buf
);
1017 /* Build a decl for __gcov_init. */
1018 init_fn
= build_pointer_type (gcov_info_type
);
1019 init_fn
= build_function_type_list (void_type_node
, init_fn
, NULL
);
1020 init_fn
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
1021 get_identifier ("__gcov_init"), init_fn
);
1022 TREE_PUBLIC (init_fn
) = 1;
1023 DECL_EXTERNAL (init_fn
) = 1;
1024 DECL_ASSEMBLER_NAME (init_fn
);
1026 /* Generate a call to __gcov_init(&gcov_info). */
1028 stmt
= build_fold_addr_expr (gcov_info_var
);
1029 stmt
= build_call_expr (init_fn
, 1, stmt
);
1030 append_to_statement_list (stmt
, &ctor
);
1032 /* Generate a constructor to run it. */
1033 cgraph_build_static_cdtor ('I', ctor
, DEFAULT_INIT_PRIORITY
);
1038 /* Generate the coverage function info for FN and DATA. Append a
1039 pointer to that object to CTOR and return the appended CTOR. */
1041 static VEC(constructor_elt
,gc
) *
1042 coverage_obj_fn (VEC(constructor_elt
,gc
) *ctor
, tree fn
,
1043 struct coverage_data
const *data
)
1045 tree init
= build_fn_info (data
, gcov_fn_info_type
, gcov_info_var
);
1046 tree var
= build_var (fn
, gcov_fn_info_type
, -1);
1048 DECL_INITIAL (var
) = init
;
1049 varpool_finalize_decl (var
);
1051 CONSTRUCTOR_APPEND_ELT (ctor
, NULL
,
1052 build1 (ADDR_EXPR
, gcov_fn_info_ptr_type
, var
));
1056 /* Finalize the coverage data. Generates the array of pointers to
1057 function objects from CTOR. Generate the gcov_info initializer. */
1060 coverage_obj_finish (VEC(constructor_elt
,gc
) *ctor
)
1062 unsigned n_functions
= VEC_length(constructor_elt
, ctor
);
1063 tree fn_info_ary_type
= build_array_type
1064 (build_qualified_type (gcov_fn_info_ptr_type
, TYPE_QUAL_CONST
),
1065 build_index_type (size_int (n_functions
- 1)));
1066 tree fn_info_ary
= build_decl (BUILTINS_LOCATION
, VAR_DECL
, NULL_TREE
,
1070 TREE_STATIC (fn_info_ary
) = 1;
1071 ASM_GENERATE_INTERNAL_LABEL (name_buf
, "LPBX", 1);
1072 DECL_NAME (fn_info_ary
) = get_identifier (name_buf
);
1073 DECL_INITIAL (fn_info_ary
) = build_constructor (fn_info_ary_type
, ctor
);
1074 varpool_finalize_decl (fn_info_ary
);
1076 DECL_INITIAL (gcov_info_var
)
1077 = build_info (TREE_TYPE (gcov_info_var
), fn_info_ary
);
1078 varpool_finalize_decl (gcov_info_var
);
1081 /* Perform file-level initialization. Read in data file, generate name
1085 coverage_init (const char *filename
)
1087 int len
= strlen (filename
);
1090 if (!profile_data_prefix
&& !IS_ABSOLUTE_PATH (filename
))
1091 profile_data_prefix
= getpwd ();
1093 if (profile_data_prefix
)
1094 prefix_len
= strlen (profile_data_prefix
);
1096 /* Name of da file. */
1097 da_file_name
= XNEWVEC (char, len
+ strlen (GCOV_DATA_SUFFIX
)
1100 if (profile_data_prefix
)
1102 memcpy (da_file_name
, profile_data_prefix
, prefix_len
);
1103 da_file_name
[prefix_len
++] = '/';
1105 memcpy (da_file_name
+ prefix_len
, filename
, len
);
1106 strcpy (da_file_name
+ prefix_len
+ len
, GCOV_DATA_SUFFIX
);
1108 bbg_file_stamp
= local_tick
;
1110 if (flag_branch_probabilities
)
1111 read_counts_file ();
1113 /* Name of bbg file. */
1114 if (flag_test_coverage
&& !flag_compare_debug
)
1116 bbg_file_name
= XNEWVEC (char, len
+ strlen (GCOV_NOTE_SUFFIX
) + 1);
1117 memcpy (bbg_file_name
, filename
, len
);
1118 strcpy (bbg_file_name
+ len
, GCOV_NOTE_SUFFIX
);
1120 if (!gcov_open (bbg_file_name
, -1))
1122 error ("cannot open %s", bbg_file_name
);
1123 bbg_file_name
= NULL
;
1127 gcov_write_unsigned (GCOV_NOTE_MAGIC
);
1128 gcov_write_unsigned (GCOV_VERSION
);
1129 gcov_write_unsigned (bbg_file_stamp
);
1134 /* Performs file-level cleanup. Close graph file, generate coverage
1135 variables and constructor. */
1138 coverage_finish (void)
1140 if (bbg_file_name
&& gcov_close ())
1141 unlink (bbg_file_name
);
1143 if (!flag_branch_probabilities
&& flag_test_coverage
1144 && (!local_tick
|| local_tick
== (unsigned)-1))
1145 /* Only remove the da file, if we're emitting coverage code and
1146 cannot uniquely stamp it. If we can stamp it, libgcov will DTRT. */
1147 unlink (da_file_name
);
1149 if (coverage_obj_init ())
1151 VEC(constructor_elt
,gc
) *fn_ctor
= NULL
;
1152 struct coverage_data
*fn
;
1154 for (fn
= functions_head
; fn
; fn
= fn
->next
)
1155 fn_ctor
= coverage_obj_fn (fn_ctor
, fn
->fn_decl
, fn
);
1156 coverage_obj_finish (fn_ctor
);
1160 #include "gt-coverage.h"