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
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"
59 struct function_list
*next
; /* next function */
60 unsigned ident
; /* function ident */
61 unsigned lineno_checksum
; /* function lineno checksum */
62 unsigned cfg_checksum
; /* function cfg checksum */
63 unsigned n_ctrs
[GCOV_COUNTERS
];/* number of counters. */
66 /* Counts information for a function. */
67 typedef struct counts_entry
74 unsigned lineno_checksum
;
75 unsigned cfg_checksum
;
77 struct gcov_ctr_summary summary
;
80 struct counts_entry
*chain
;
84 static struct function_list
*functions_head
= 0;
85 static struct function_list
**functions_tail
= &functions_head
;
86 static unsigned no_coverage
= 0;
88 /* Cumulative counter information for whole program. */
89 static unsigned prg_ctr_mask
; /* Mask of counter types generated. */
90 static unsigned prg_n_ctrs
[GCOV_COUNTERS
]; /* Total counters allocated. */
92 /* Counter information for current function. */
93 static unsigned fn_ctr_mask
; /* Mask of counters used. */
94 static unsigned fn_n_ctrs
[GCOV_COUNTERS
]; /* Counters allocated. */
95 static unsigned fn_b_ctrs
[GCOV_COUNTERS
]; /* Allocation base. */
97 /* Name of the output file for coverage output file. */
98 static char *bbg_file_name
;
99 static unsigned bbg_file_opened
;
100 static int bbg_function_announced
;
102 /* Name of the count data file. */
103 static char *da_file_name
;
105 /* Hash table of count data. */
106 static htab_t counts_hash
= NULL
;
108 /* Trees representing the counter table arrays. */
109 static GTY(()) tree tree_ctr_tables
[GCOV_COUNTERS
];
111 /* The names of merge functions for counters. */
112 static const char *const ctr_merge_functions
[GCOV_COUNTERS
] = GCOV_MERGE_FUNCTIONS
;
113 static const char *const ctr_names
[GCOV_COUNTERS
] = GCOV_COUNTER_NAMES
;
115 /* Forward declarations. */
116 static hashval_t
htab_counts_entry_hash (const void *);
117 static int htab_counts_entry_eq (const void *, const void *);
118 static void htab_counts_entry_del (void *);
119 static void read_counts_file (void);
120 static tree
build_fn_info_type (unsigned);
121 static tree
build_fn_info_value (const struct function_list
*, tree
);
122 static tree
build_ctr_info_type (void);
123 static tree
build_ctr_info_value (unsigned, tree
);
124 static tree
build_gcov_info (void);
125 static void create_coverage (void);
127 /* Return the type node for gcov_type. */
132 return lang_hooks
.types
.type_for_size (GCOV_TYPE_SIZE
, false);
135 /* Return the type node for gcov_unsigned_t. */
138 get_gcov_unsigned_t (void)
140 return lang_hooks
.types
.type_for_size (32, true);
144 htab_counts_entry_hash (const void *of
)
146 const counts_entry_t
*const entry
= (const counts_entry_t
*) of
;
148 return entry
->ident
* GCOV_COUNTERS
+ entry
->ctr
;
152 htab_counts_entry_eq (const void *of1
, const void *of2
)
154 const counts_entry_t
*const entry1
= (const counts_entry_t
*) of1
;
155 const counts_entry_t
*const entry2
= (const counts_entry_t
*) of2
;
157 return entry1
->ident
== entry2
->ident
&& entry1
->ctr
== entry2
->ctr
;
161 htab_counts_entry_del (void *of
)
163 counts_entry_t
*const entry
= (counts_entry_t
*) of
;
165 free (entry
->counts
);
169 /* Read in the counts file, if available. */
172 read_counts_file (void)
174 gcov_unsigned_t fn_ident
= 0;
175 counts_entry_t
*summaried
= NULL
;
176 unsigned seen_summary
= 0;
179 unsigned lineno_checksum
= 0;
180 unsigned cfg_checksum
= 0;
182 if (!gcov_open (da_file_name
, 1))
185 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC
))
187 warning (0, "%qs is not a gcov data file", da_file_name
);
191 else if ((tag
= gcov_read_unsigned ()) != GCOV_VERSION
)
195 GCOV_UNSIGNED2STRING (v
, tag
);
196 GCOV_UNSIGNED2STRING (e
, GCOV_VERSION
);
198 warning (0, "%qs is version %q.*s, expected version %q.*s",
199 da_file_name
, 4, v
, 4, e
);
204 /* Read and discard the stamp. */
205 gcov_read_unsigned ();
207 counts_hash
= htab_create (10,
208 htab_counts_entry_hash
, htab_counts_entry_eq
,
209 htab_counts_entry_del
);
210 while ((tag
= gcov_read_unsigned ()))
212 gcov_unsigned_t length
;
213 gcov_position_t offset
;
215 length
= gcov_read_unsigned ();
216 offset
= gcov_position ();
217 if (tag
== GCOV_TAG_FUNCTION
)
219 fn_ident
= gcov_read_unsigned ();
220 lineno_checksum
= gcov_read_unsigned ();
221 cfg_checksum
= gcov_read_unsigned ();
224 /* We have already seen a summary, this means that this
225 new function begins a new set of program runs. We
226 must unlink the summaried chain. */
227 counts_entry_t
*entry
, *chain
;
229 for (entry
= summaried
; entry
; entry
= chain
)
231 chain
= entry
->chain
;
238 else if (tag
== GCOV_TAG_PROGRAM_SUMMARY
)
240 counts_entry_t
*entry
;
241 struct gcov_summary summary
;
243 gcov_read_summary (&summary
);
245 for (entry
= summaried
; entry
; entry
= entry
->chain
)
247 struct gcov_ctr_summary
*csum
= &summary
.ctrs
[entry
->ctr
];
249 entry
->summary
.runs
+= csum
->runs
;
250 entry
->summary
.sum_all
+= csum
->sum_all
;
251 if (entry
->summary
.run_max
< csum
->run_max
)
252 entry
->summary
.run_max
= csum
->run_max
;
253 entry
->summary
.sum_max
+= csum
->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
.num
= n_counts
;
276 entry
->counts
= XCNEWVEC (gcov_type
, n_counts
);
278 else if (entry
->lineno_checksum
!= lineno_checksum
279 || entry
->cfg_checksum
!= cfg_checksum
)
281 error ("Profile data for function %u is corrupted", fn_ident
);
282 error ("checksum is (%x,%x) instead of (%x,%x)",
283 entry
->lineno_checksum
, entry
->cfg_checksum
,
284 lineno_checksum
, cfg_checksum
);
285 htab_delete (counts_hash
);
288 else if (entry
->summary
.num
!= n_counts
)
290 error ("Profile data for function %u is corrupted", fn_ident
);
291 error ("number of counters is %d instead of %d", entry
->summary
.num
, n_counts
);
292 htab_delete (counts_hash
);
295 else if (elt
.ctr
>= GCOV_COUNTERS_SUMMABLE
)
297 error ("cannot merge separate %s counters for function %u",
298 ctr_names
[elt
.ctr
], fn_ident
);
302 if (elt
.ctr
< GCOV_COUNTERS_SUMMABLE
303 /* This should always be true for a just allocated entry,
304 and always false for an existing one. Check this way, in
305 case the gcov file is corrupt. */
306 && (!entry
->chain
|| summaried
!= entry
))
308 entry
->chain
= summaried
;
311 for (ix
= 0; ix
!= n_counts
; ix
++)
312 entry
->counts
[ix
] += gcov_read_counter ();
315 gcov_sync (offset
, length
);
316 if ((is_error
= gcov_is_error ()))
318 error (is_error
< 0 ? "%qs has overflowed" : "%qs is corrupted",
320 htab_delete (counts_hash
);
328 /* Returns the counters for a particular tag. */
331 get_coverage_counts (unsigned counter
, unsigned expected
,
332 unsigned cfg_checksum
, unsigned lineno_checksum
,
333 const struct gcov_ctr_summary
**summary
)
335 counts_entry_t
*entry
, elt
;
337 /* No hash table, no counts. */
340 static int warned
= 0;
343 inform (input_location
, (flag_guess_branch_prob
344 ? "file %s not found, execution counts estimated"
345 : "file %s not found, execution counts assumed to be zero"),
350 elt
.ident
= current_function_funcdef_no
+ 1;
352 entry
= (counts_entry_t
*) htab_find (counts_hash
, &elt
);
355 warning (0, "no coverage for function %qE found",
356 DECL_ASSEMBLER_NAME (current_function_decl
));
360 if (entry
->cfg_checksum
!= cfg_checksum
361 || entry
->summary
.num
!= expected
)
363 static int warned
= 0;
364 bool warning_printed
= false;
365 tree id
= DECL_ASSEMBLER_NAME (current_function_decl
);
368 warning_at (input_location
, OPT_Wcoverage_mismatch
,
369 "The control flow of function %qE does not match "
370 "its profile data (counter %qs)", id
, ctr_names
[counter
]);
373 inform (input_location
, "Use -Wno-error=coverage-mismatch to tolerate "
374 "the mismatch but performance may drop if the function is hot");
379 inform (input_location
, "coverage mismatch ignored");
380 inform (input_location
, flag_guess_branch_prob
381 ? G_("execution counts estimated")
382 : G_("execution counts assumed to be zero"));
383 if (!flag_guess_branch_prob
)
384 inform (input_location
,
385 "this can result in poorly optimized code");
391 else if (entry
->lineno_checksum
!= lineno_checksum
)
393 warning (0, "Source location for function %qE have changed,"
394 " the profile data may be out of date",
395 DECL_ASSEMBLER_NAME (current_function_decl
));
399 *summary
= &entry
->summary
;
401 return entry
->counts
;
404 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
405 allocation succeeded. */
408 coverage_counter_alloc (unsigned counter
, unsigned num
)
416 if (!tree_ctr_tables
[counter
])
418 /* Generate and save a copy of this so it can be shared. Leave
419 the index type unspecified for now; it will be set after all
420 functions have been compiled. */
422 tree gcov_type_node
= get_gcov_type ();
423 tree gcov_type_array_type
424 = build_array_type (gcov_type_node
, NULL_TREE
);
425 tree_ctr_tables
[counter
]
426 = build_decl (BUILTINS_LOCATION
,
427 VAR_DECL
, NULL_TREE
, gcov_type_array_type
);
428 TREE_STATIC (tree_ctr_tables
[counter
]) = 1;
429 ASM_GENERATE_INTERNAL_LABEL (buf
, "LPBX", counter
+ 1);
430 DECL_NAME (tree_ctr_tables
[counter
]) = get_identifier (buf
);
431 DECL_ALIGN (tree_ctr_tables
[counter
]) = TYPE_ALIGN (gcov_type_node
);
434 fprintf (dump_file
, "Using data file %s\n", da_file_name
);
436 fn_b_ctrs
[counter
] = fn_n_ctrs
[counter
];
437 fn_n_ctrs
[counter
] += num
;
438 fn_ctr_mask
|= 1 << counter
;
442 /* Generate a tree to access COUNTER NO. */
445 tree_coverage_counter_ref (unsigned counter
, unsigned no
)
447 tree gcov_type_node
= get_gcov_type ();
449 gcc_assert (no
< fn_n_ctrs
[counter
] - fn_b_ctrs
[counter
]);
450 no
+= prg_n_ctrs
[counter
] + fn_b_ctrs
[counter
];
452 /* "no" here is an array index, scaled to bytes later. */
453 return build4 (ARRAY_REF
, gcov_type_node
, tree_ctr_tables
[counter
],
454 build_int_cst (integer_type_node
, no
), NULL
, NULL
);
457 /* Generate a tree to access the address of COUNTER NO. */
460 tree_coverage_counter_addr (unsigned counter
, unsigned no
)
462 tree gcov_type_node
= get_gcov_type ();
464 gcc_assert (no
< fn_n_ctrs
[counter
] - fn_b_ctrs
[counter
]);
465 no
+= prg_n_ctrs
[counter
] + fn_b_ctrs
[counter
];
467 TREE_ADDRESSABLE (tree_ctr_tables
[counter
]) = 1;
469 /* "no" here is an array index, scaled to bytes later. */
470 return build_fold_addr_expr (build4 (ARRAY_REF
, gcov_type_node
,
471 tree_ctr_tables
[counter
],
472 build_int_cst (integer_type_node
, no
),
477 /* Generate a checksum for a string. CHKSUM is the current
481 coverage_checksum_string (unsigned chksum
, const char *string
)
486 /* Look for everything that looks if it were produced by
487 get_file_function_name and zero out the second part
488 that may result from flag_random_seed. This is not critical
489 as the checksums are used only for sanity checking. */
490 for (i
= 0; string
[i
]; i
++)
493 if (!strncmp (string
+ i
, "_GLOBAL__N_", 11))
495 if (!strncmp (string
+ i
, "_GLOBAL__", 9))
498 /* C++ namespaces do have scheme:
499 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
500 since filename might contain extra underscores there seems
501 to be no better chance then walk all possible offsets looking
505 for (i
= i
+ offset
; string
[i
]; i
++)
510 for (y
= 1; y
< 9; y
++)
511 if (!(string
[i
+ y
] >= '0' && string
[i
+ y
] <= '9')
512 && !(string
[i
+ y
] >= 'A' && string
[i
+ y
] <= 'F'))
514 if (y
!= 9 || string
[i
+ 9] != '_')
516 for (y
= 10; y
< 18; y
++)
517 if (!(string
[i
+ y
] >= '0' && string
[i
+ y
] <= '9')
518 && !(string
[i
+ y
] >= 'A' && string
[i
+ y
] <= 'F'))
523 string
= dup
= xstrdup (string
);
524 for (y
= 10; y
< 18; y
++)
531 chksum
= crc32_string (chksum
, string
);
537 /* Compute checksum for the current function. We generate a CRC32. */
540 coverage_compute_lineno_checksum (void)
542 expanded_location xloc
543 = expand_location (DECL_SOURCE_LOCATION (current_function_decl
));
544 unsigned chksum
= xloc
.line
;
546 chksum
= coverage_checksum_string (chksum
, xloc
.file
);
547 chksum
= coverage_checksum_string
548 (chksum
, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl
)));
553 /* Compute cfg checksum for the current function.
554 The checksum is calculated carefully so that
555 source code changes that doesn't affect the control flow graph
556 won't change the checksum.
557 This is to make the profile data useable across source code change.
558 The downside of this is that the compiler may use potentially
559 wrong profile data - that the source code change has non-trivial impact
560 on the validity of profile data (e.g. the reversed condition)
561 but the compiler won't detect the change and use the wrong profile data. */
564 coverage_compute_cfg_checksum (void)
567 unsigned chksum
= n_basic_blocks
;
573 chksum
= crc32_byte (chksum
, bb
->index
);
574 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
576 chksum
= crc32_byte (chksum
, e
->dest
->index
);
583 /* Begin output to the graph file for the current function.
584 Opens the output file, if not already done. Writes the
585 function header, if not already done. Returns nonzero if data
589 coverage_begin_output (unsigned lineno_checksum
, unsigned cfg_checksum
)
591 /* We don't need to output .gcno file unless we're under -ftest-coverage
592 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
593 if (no_coverage
|| !flag_test_coverage
|| flag_compare_debug
)
596 if (!bbg_function_announced
)
598 expanded_location xloc
599 = expand_location (DECL_SOURCE_LOCATION (current_function_decl
));
600 unsigned long offset
;
602 if (!bbg_file_opened
)
604 if (!gcov_open (bbg_file_name
, -1))
605 error ("cannot open %s", bbg_file_name
);
608 gcov_write_unsigned (GCOV_NOTE_MAGIC
);
609 gcov_write_unsigned (GCOV_VERSION
);
610 gcov_write_unsigned (local_tick
);
616 /* Announce function */
617 offset
= gcov_write_tag (GCOV_TAG_FUNCTION
);
618 gcov_write_unsigned (current_function_funcdef_no
+ 1);
619 gcov_write_unsigned (lineno_checksum
);
620 gcov_write_unsigned (cfg_checksum
);
621 gcov_write_string (IDENTIFIER_POINTER
622 (DECL_ASSEMBLER_NAME (current_function_decl
)));
623 gcov_write_string (xloc
.file
);
624 gcov_write_unsigned (xloc
.line
);
625 gcov_write_length (offset
);
627 bbg_function_announced
= 1;
629 return !gcov_is_error ();
632 /* Finish coverage data for the current function. Verify no output
633 error has occurred. Save function coverage counts. */
636 coverage_end_function (unsigned lineno_checksum
, unsigned cfg_checksum
)
640 if (bbg_file_opened
> 1 && gcov_is_error ())
642 warning (0, "error writing %qs", bbg_file_name
);
643 bbg_file_opened
= -1;
648 struct function_list
*item
;
650 item
= XCNEW (struct function_list
);
652 *functions_tail
= item
;
653 functions_tail
= &item
->next
;
657 item
->ident
= current_function_funcdef_no
+ 1;
658 item
->lineno_checksum
= lineno_checksum
;
659 item
->cfg_checksum
= cfg_checksum
;
660 for (i
= 0; i
!= GCOV_COUNTERS
; i
++)
662 item
->n_ctrs
[i
] = fn_n_ctrs
[i
];
663 prg_n_ctrs
[i
] += fn_n_ctrs
[i
];
664 fn_n_ctrs
[i
] = fn_b_ctrs
[i
] = 0;
666 prg_ctr_mask
|= fn_ctr_mask
;
669 bbg_function_announced
= 0;
672 /* Creates the gcov_fn_info RECORD_TYPE. */
675 build_fn_info_type (unsigned int counters
)
677 tree type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
682 fields
= build_decl (BUILTINS_LOCATION
,
683 FIELD_DECL
, NULL_TREE
, get_gcov_unsigned_t ());
684 /* lineno_checksum */
685 field
= build_decl (BUILTINS_LOCATION
,
686 FIELD_DECL
, NULL_TREE
, get_gcov_unsigned_t ());
687 DECL_CHAIN (field
) = fields
;
691 field
= build_decl (BUILTINS_LOCATION
,
692 FIELD_DECL
, NULL_TREE
, get_gcov_unsigned_t ());
693 DECL_CHAIN (field
) = fields
;
696 array_type
= build_index_type (size_int (counters
- 1));
697 array_type
= build_array_type (get_gcov_unsigned_t (), array_type
);
700 field
= build_decl (BUILTINS_LOCATION
,
701 FIELD_DECL
, NULL_TREE
, array_type
);
702 DECL_CHAIN (field
) = fields
;
705 finish_builtin_struct (type
, "__gcov_fn_info", fields
, NULL_TREE
);
710 /* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is
711 the function being processed and TYPE is the gcov_fn_info
715 build_fn_info_value (const struct function_list
*function
, tree type
)
717 tree fields
= TYPE_FIELDS (type
);
719 VEC(constructor_elt
,gc
) *v1
= NULL
;
720 VEC(constructor_elt
,gc
) *v2
= NULL
;
723 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
724 build_int_cstu (get_gcov_unsigned_t (),
726 fields
= DECL_CHAIN (fields
);
728 /* lineno_checksum */
729 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
730 build_int_cstu (get_gcov_unsigned_t (),
731 function
->lineno_checksum
));
732 fields
= DECL_CHAIN (fields
);
735 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
736 build_int_cstu (get_gcov_unsigned_t (),
737 function
->cfg_checksum
));
738 fields
= DECL_CHAIN (fields
);
741 for (ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
742 if (prg_ctr_mask
& (1 << ix
))
743 CONSTRUCTOR_APPEND_ELT (v2
, NULL
,
744 build_int_cstu (get_gcov_unsigned_t (),
745 function
->n_ctrs
[ix
]));
747 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
748 build_constructor (TREE_TYPE (fields
), v2
));
750 return build_constructor (type
, v1
);
753 /* Creates the gcov_ctr_info RECORD_TYPE. */
756 build_ctr_info_type (void)
758 tree type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
759 tree field
, fields
= NULL_TREE
;
760 tree gcov_ptr_type
= build_pointer_type (get_gcov_type ());
761 tree gcov_merge_fn_type
;
764 field
= build_decl (BUILTINS_LOCATION
,
765 FIELD_DECL
, NULL_TREE
, get_gcov_unsigned_t ());
766 DECL_CHAIN (field
) = fields
;
770 field
= build_decl (BUILTINS_LOCATION
,
771 FIELD_DECL
, NULL_TREE
, gcov_ptr_type
);
772 DECL_CHAIN (field
) = fields
;
777 build_function_type_list (void_type_node
,
778 gcov_ptr_type
, get_gcov_unsigned_t (),
780 field
= build_decl (BUILTINS_LOCATION
,
781 FIELD_DECL
, NULL_TREE
,
782 build_pointer_type (gcov_merge_fn_type
));
783 DECL_CHAIN (field
) = fields
;
786 finish_builtin_struct (type
, "__gcov_ctr_info", fields
, NULL_TREE
);
791 /* Creates a CONSTRUCTOR for a gcov_ctr_info. COUNTER is
792 the counter being processed and TYPE is the gcov_ctr_info
796 build_ctr_info_value (unsigned int counter
, tree type
)
798 tree fields
= TYPE_FIELDS (type
);
800 VEC(constructor_elt
,gc
) *v
= NULL
;
803 CONSTRUCTOR_APPEND_ELT (v
, fields
,
804 build_int_cstu (get_gcov_unsigned_t (),
805 prg_n_ctrs
[counter
]));
806 fields
= DECL_CHAIN (fields
);
808 if (prg_n_ctrs
[counter
])
812 array_type
= build_int_cstu (get_gcov_unsigned_t (),
813 prg_n_ctrs
[counter
] - 1);
814 array_type
= build_index_type (array_type
);
815 array_type
= build_array_type (TREE_TYPE (TREE_TYPE (fields
)),
818 TREE_TYPE (tree_ctr_tables
[counter
]) = array_type
;
819 DECL_SIZE (tree_ctr_tables
[counter
]) = TYPE_SIZE (array_type
);
820 DECL_SIZE_UNIT (tree_ctr_tables
[counter
]) = TYPE_SIZE_UNIT (array_type
);
821 varpool_finalize_decl (tree_ctr_tables
[counter
]);
823 CONSTRUCTOR_APPEND_ELT (v
, fields
,
824 build1 (ADDR_EXPR
, TREE_TYPE (fields
),
825 tree_ctr_tables
[counter
]));
828 CONSTRUCTOR_APPEND_ELT (v
, fields
, null_pointer_node
);
829 fields
= DECL_CHAIN (fields
);
831 fn
= build_decl (BUILTINS_LOCATION
,
833 get_identifier (ctr_merge_functions
[counter
]),
834 TREE_TYPE (TREE_TYPE (fields
)));
835 DECL_EXTERNAL (fn
) = 1;
836 TREE_PUBLIC (fn
) = 1;
837 DECL_ARTIFICIAL (fn
) = 1;
838 TREE_NOTHROW (fn
) = 1;
839 DECL_ASSEMBLER_NAME (fn
); /* Initialize assembler name so we can stream out. */
840 CONSTRUCTOR_APPEND_ELT (v
, fields
, build1 (ADDR_EXPR
, TREE_TYPE (fields
), fn
));
842 return build_constructor (type
, v
);
845 /* Creates the gcov_info RECORD_TYPE and initializer for it. Returns a
849 build_gcov_info (void)
851 unsigned n_ctr_types
, ix
;
852 tree type
, const_type
;
853 tree fn_info_type
, fn_info_value
= NULL_TREE
;
854 tree fn_info_ptr_type
;
855 tree ctr_info_type
, ctr_info_ary_type
, ctr_info_value
= NULL_TREE
;
856 tree field
, fields
= NULL_TREE
;
857 tree filename_string
;
858 int da_file_name_len
;
860 const struct function_list
*fn
;
862 VEC(constructor_elt
,gc
) *v1
= NULL
;
863 VEC(constructor_elt
,gc
) *v2
= NULL
;
865 /* Count the number of active counters. */
866 for (n_ctr_types
= 0, ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
867 if (prg_ctr_mask
& (1 << ix
))
870 type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
871 const_type
= build_qualified_type (type
, TYPE_QUAL_CONST
);
874 field
= build_decl (BUILTINS_LOCATION
,
875 FIELD_DECL
, NULL_TREE
, get_gcov_unsigned_t ());
876 DECL_CHAIN (field
) = fields
;
878 CONSTRUCTOR_APPEND_ELT (v1
, field
,
879 build_int_cstu (TREE_TYPE (field
), GCOV_VERSION
));
882 field
= build_decl (BUILTINS_LOCATION
,
883 FIELD_DECL
, NULL_TREE
, build_pointer_type (const_type
));
884 DECL_CHAIN (field
) = fields
;
886 CONSTRUCTOR_APPEND_ELT (v1
, field
, null_pointer_node
);
889 field
= build_decl (BUILTINS_LOCATION
,
890 FIELD_DECL
, NULL_TREE
, get_gcov_unsigned_t ());
891 DECL_CHAIN (field
) = fields
;
893 CONSTRUCTOR_APPEND_ELT (v1
, field
,
894 build_int_cstu (TREE_TYPE (field
), local_tick
));
897 string_type
= build_pointer_type (build_qualified_type (char_type_node
,
899 field
= build_decl (BUILTINS_LOCATION
,
900 FIELD_DECL
, NULL_TREE
, string_type
);
901 DECL_CHAIN (field
) = fields
;
903 da_file_name_len
= strlen (da_file_name
);
904 filename_string
= build_string (da_file_name_len
+ 1, da_file_name
);
905 TREE_TYPE (filename_string
) = build_array_type
906 (char_type_node
, build_index_type (size_int (da_file_name_len
)));
907 CONSTRUCTOR_APPEND_ELT (v1
, field
,
908 build1 (ADDR_EXPR
, string_type
, filename_string
));
910 /* Build the fn_info type and initializer. */
911 fn_info_type
= build_fn_info_type (n_ctr_types
);
912 fn_info_ptr_type
= build_pointer_type (build_qualified_type
913 (fn_info_type
, TYPE_QUAL_CONST
));
914 for (fn
= functions_head
, n_fns
= 0; fn
; fn
= fn
->next
, n_fns
++)
915 CONSTRUCTOR_APPEND_ELT (v2
, NULL_TREE
,
916 build_fn_info_value (fn
, fn_info_type
));
922 array_type
= build_index_type (size_int (n_fns
- 1));
923 array_type
= build_array_type (fn_info_type
, array_type
);
925 fn_info_value
= build_constructor (array_type
, v2
);
926 fn_info_value
= build1 (ADDR_EXPR
, fn_info_ptr_type
, fn_info_value
);
929 fn_info_value
= null_pointer_node
;
931 /* number of functions */
932 field
= build_decl (BUILTINS_LOCATION
,
933 FIELD_DECL
, NULL_TREE
, get_gcov_unsigned_t ());
934 DECL_CHAIN (field
) = fields
;
936 CONSTRUCTOR_APPEND_ELT (v1
, field
,
937 build_int_cstu (get_gcov_unsigned_t (), n_fns
));
940 field
= build_decl (BUILTINS_LOCATION
,
941 FIELD_DECL
, NULL_TREE
, fn_info_ptr_type
);
942 DECL_CHAIN (field
) = fields
;
944 CONSTRUCTOR_APPEND_ELT (v1
, field
, fn_info_value
);
947 field
= build_decl (BUILTINS_LOCATION
,
948 FIELD_DECL
, NULL_TREE
, get_gcov_unsigned_t ());
949 DECL_CHAIN (field
) = fields
;
951 CONSTRUCTOR_APPEND_ELT (v1
, field
,
952 build_int_cstu (get_gcov_unsigned_t (),
956 ctr_info_type
= build_ctr_info_type ();
957 ctr_info_ary_type
= build_index_type (size_int (n_ctr_types
));
958 ctr_info_ary_type
= build_array_type (ctr_info_type
, ctr_info_ary_type
);
960 for (ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
961 if (prg_ctr_mask
& (1 << ix
))
962 CONSTRUCTOR_APPEND_ELT (v2
, NULL_TREE
,
963 build_ctr_info_value (ix
, ctr_info_type
));
964 ctr_info_value
= build_constructor (ctr_info_ary_type
, v2
);
966 field
= build_decl (BUILTINS_LOCATION
,
967 FIELD_DECL
, NULL_TREE
, ctr_info_ary_type
);
968 DECL_CHAIN (field
) = fields
;
970 CONSTRUCTOR_APPEND_ELT (v1
, field
, ctr_info_value
);
972 finish_builtin_struct (type
, "__gcov_info", fields
, NULL_TREE
);
974 return build_constructor (type
, v1
);
977 /* Write out the structure which libgcov uses to locate all the
978 counters. The structures used here must match those defined in
979 gcov-io.h. Write out the constructor to call __gcov_init. */
982 create_coverage (void)
984 tree gcov_info
, gcov_init
, body
, t
;
987 no_coverage
= 1; /* Disable any further coverage. */
992 t
= build_gcov_info ();
994 gcov_info
= build_decl (BUILTINS_LOCATION
,
995 VAR_DECL
, NULL_TREE
, TREE_TYPE (t
));
996 TREE_STATIC (gcov_info
) = 1;
997 ASM_GENERATE_INTERNAL_LABEL (name_buf
, "LPBX", 0);
998 DECL_NAME (gcov_info
) = get_identifier (name_buf
);
999 DECL_INITIAL (gcov_info
) = t
;
1001 /* Build structure. */
1002 varpool_finalize_decl (gcov_info
);
1004 /* Build a decl for __gcov_init. */
1005 t
= build_pointer_type (TREE_TYPE (gcov_info
));
1006 t
= build_function_type_list (void_type_node
, t
, NULL
);
1007 t
= build_decl (BUILTINS_LOCATION
,
1008 FUNCTION_DECL
, get_identifier ("__gcov_init"), t
);
1009 TREE_PUBLIC (t
) = 1;
1010 DECL_EXTERNAL (t
) = 1;
1011 DECL_ASSEMBLER_NAME (t
); /* Initialize assembler name so we can stream out. */
1014 /* Generate a call to __gcov_init(&gcov_info). */
1016 t
= build_fold_addr_expr (gcov_info
);
1017 t
= build_call_expr (gcov_init
, 1, t
);
1018 append_to_statement_list (t
, &body
);
1020 /* Generate a constructor to run it. */
1021 cgraph_build_static_cdtor ('I', body
, DEFAULT_INIT_PRIORITY
);
1024 /* Perform file-level initialization. Read in data file, generate name
1028 coverage_init (const char *filename
)
1030 int len
= strlen (filename
);
1031 /* + 1 for extra '/', in case prefix doesn't end with /. */
1034 if (profile_data_prefix
== 0 && !IS_ABSOLUTE_PATH(&filename
[0]))
1035 profile_data_prefix
= getpwd ();
1037 prefix_len
= (profile_data_prefix
) ? strlen (profile_data_prefix
) + 1 : 0;
1039 /* Name of da file. */
1040 da_file_name
= XNEWVEC (char, len
+ strlen (GCOV_DATA_SUFFIX
)
1043 if (profile_data_prefix
)
1045 strcpy (da_file_name
, profile_data_prefix
);
1046 da_file_name
[prefix_len
- 1] = '/';
1047 da_file_name
[prefix_len
] = 0;
1050 da_file_name
[0] = 0;
1051 strcat (da_file_name
, filename
);
1052 strcat (da_file_name
, GCOV_DATA_SUFFIX
);
1054 /* Name of bbg file. */
1055 bbg_file_name
= XNEWVEC (char, len
+ strlen (GCOV_NOTE_SUFFIX
) + 1);
1056 strcpy (bbg_file_name
, filename
);
1057 strcat (bbg_file_name
, GCOV_NOTE_SUFFIX
);
1059 if (flag_branch_probabilities
)
1060 read_counts_file ();
1063 /* Performs file-level cleanup. Close graph file, generate coverage
1064 variables and constructor. */
1067 coverage_finish (void)
1070 if (bbg_file_opened
)
1072 int error
= gcov_close ();
1075 unlink (bbg_file_name
);
1077 /* Only remove the da file, if we cannot stamp it. If we can
1078 stamp it, libgcov will DTRT. */
1079 unlink (da_file_name
);
1083 #include "gt-coverage.h"