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 Free Software Foundation, Inc.
4 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
5 based on some ideas from Dain Samples of UC Berkeley.
6 Further mangling by Bob Manson, Cygnus Support.
7 Further mangled by Nathan Sidwell, CodeSourcery
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 2, or (at your option) any later
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING. If not, write to the Free
23 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
31 #include "coretypes.h"
45 #include "langhooks.h"
52 struct function_list *next; /* next function */
53 unsigned ident; /* function ident */
54 unsigned checksum; /* function checksum */
55 unsigned n_ctrs[GCOV_COUNTERS];/* number of counters. */
58 /* Counts information for a function. */
59 typedef struct counts_entry
68 struct gcov_ctr_summary summary;
71 struct counts_entry *chain;
75 static struct function_list *functions_head = 0;
76 static struct function_list **functions_tail = &functions_head;
77 static unsigned no_coverage = 0;
79 /* Cumulative counter information for whole program. */
80 static unsigned prg_ctr_mask; /* Mask of counter types generated. */
81 static unsigned prg_n_ctrs[GCOV_COUNTERS]; /* Total counters allocated. */
83 /* Counter information for current function. */
84 static unsigned fn_ctr_mask; /* Mask of counters used. */
85 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated. */
86 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base. */
88 /* Name of the output file for coverage output file. */
89 static char *bbg_file_name;
90 static unsigned bbg_file_opened;
91 static int bbg_function_announced;
93 /* Name of the count data file. */
94 static char *da_file_name;
96 /* Hash table of count data. */
97 static htab_t counts_hash = NULL;
99 /* The names of the counter tables. */
100 static GTY(()) rtx ctr_labels[GCOV_COUNTERS];
102 /* The names of merge functions for counters. */
103 static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
104 static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
106 /* Forward declarations. */
107 static hashval_t htab_counts_entry_hash (const void *);
108 static int htab_counts_entry_eq (const void *, const void *);
109 static void htab_counts_entry_del (void *);
110 static void read_counts_file (void);
111 static unsigned compute_checksum (void);
112 static unsigned checksum_string (unsigned, const char *);
113 static tree build_fn_info_type (unsigned);
114 static tree build_fn_info_value (const struct function_list *, tree);
115 static tree build_ctr_info_type (void);
116 static tree build_ctr_info_value (unsigned, tree);
117 static tree build_gcov_info (void);
118 static void create_coverage (void);
122 htab_counts_entry_hash (const void *of)
124 const counts_entry_t *entry = of;
126 return entry->ident * GCOV_COUNTERS + entry->ctr;
130 htab_counts_entry_eq (const void *of1, const void *of2)
132 const counts_entry_t *entry1 = of1;
133 const counts_entry_t *entry2 = of2;
135 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
139 htab_counts_entry_del (void *of)
141 counts_entry_t *entry = of;
143 free (entry->counts);
147 /* Read in the counts file, if available. */
150 read_counts_file (void)
152 gcov_unsigned_t fn_ident = 0;
153 gcov_unsigned_t checksum = -1;
154 counts_entry_t *summaried = NULL;
155 unsigned seen_summary = 0;
159 if (!gcov_open (da_file_name, 1))
162 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
164 warning ("`%s' is not a gcov data file", da_file_name);
168 else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
172 GCOV_UNSIGNED2STRING (v, tag);
173 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
175 warning ("`%s' is version `%.4s', expected version `%.4s'",
181 /* Read and discard the stamp. */
182 gcov_read_unsigned ();
184 counts_hash = htab_create (10,
185 htab_counts_entry_hash, htab_counts_entry_eq,
186 htab_counts_entry_del);
187 while ((tag = gcov_read_unsigned ()))
189 gcov_unsigned_t length;
190 gcov_position_t offset;
192 length = gcov_read_unsigned ();
193 offset = gcov_position ();
194 if (tag == GCOV_TAG_FUNCTION)
196 fn_ident = gcov_read_unsigned ();
197 checksum = gcov_read_unsigned ();
200 /* We have already seen a summary, this means that this
201 new function begins a new set of program runs. We
202 must unlink the summaried chain. */
203 counts_entry_t *entry, *chain;
205 for (entry = summaried; entry; entry = chain)
207 chain = entry->chain;
214 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
216 counts_entry_t *entry;
217 struct gcov_summary summary;
219 gcov_read_summary (&summary);
221 for (entry = summaried; entry; entry = entry->chain)
223 struct gcov_ctr_summary *csum = &summary.ctrs[entry->ctr];
225 entry->summary.runs += csum->runs;
226 entry->summary.sum_all += csum->sum_all;
227 if (entry->summary.run_max < csum->run_max)
228 entry->summary.run_max = csum->run_max;
229 entry->summary.sum_max += csum->sum_max;
232 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
234 counts_entry_t **slot, *entry, elt;
235 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
238 elt.ident = fn_ident;
239 elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
241 slot = (counts_entry_t **) htab_find_slot
242 (counts_hash, &elt, INSERT);
246 *slot = entry = xcalloc (1, sizeof (counts_entry_t));
247 entry->ident = elt.ident;
248 entry->ctr = elt.ctr;
249 entry->checksum = checksum;
250 entry->summary.num = n_counts;
251 entry->counts = xcalloc (n_counts, sizeof (gcov_type));
253 else if (entry->checksum != checksum)
255 error ("coverage mismatch for function %u while reading execution counters.",
257 error ("checksum is %x instead of %x", entry->checksum, checksum);
258 htab_delete (counts_hash);
261 else if (entry->summary.num != n_counts)
263 error ("coverage mismatch for function %u while reading execution counters.",
265 error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
266 htab_delete (counts_hash);
269 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
271 error ("cannot merge separate %s counters for function %u",
272 ctr_names[elt.ctr], fn_ident);
276 if (elt.ctr < GCOV_COUNTERS_SUMMABLE
277 /* This should always be true for a just allocated entry,
278 and always false for an existing one. Check this way, in
279 case the gcov file is corrupt. */
280 && (!entry->chain || summaried != entry))
282 entry->chain = summaried;
285 for (ix = 0; ix != n_counts; ix++)
286 entry->counts[ix] += gcov_read_counter ();
289 gcov_sync (offset, length);
290 if ((is_error = gcov_is_error ()))
296 error (is_error < 0 ? "`%s' has overflowed" : "`%s' is corrupted",
298 htab_delete (counts_hash);
304 /* Returns the counters for a particular tag. */
307 get_coverage_counts (unsigned counter, unsigned expected,
308 const struct gcov_ctr_summary **summary)
310 counts_entry_t *entry, elt;
311 gcov_unsigned_t checksum = -1;
313 /* No hash table, no counts. */
316 static int warned = 0;
319 inform ("file %s not found, execution counts assumed to be zero",
324 elt.ident = current_function_funcdef_no + 1;
326 entry = htab_find (counts_hash, &elt);
329 warning ("no coverage for function '%s' found.", IDENTIFIER_POINTER
330 (DECL_ASSEMBLER_NAME (current_function_decl)));
334 checksum = compute_checksum ();
335 if (entry->checksum != checksum)
337 error ("coverage mismatch for function '%s' while reading counter '%s'.",
338 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)),
340 error ("checksum is %x instead of %x", entry->checksum, checksum);
343 else if (entry->summary.num != expected)
345 error ("coverage mismatch for function '%s' while reading counter '%s'.",
346 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)),
348 error ("number of counters is %d instead of %d", entry->summary.num, expected);
353 *summary = &entry->summary;
355 return entry->counts;
358 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
359 allocation succeeded. */
362 coverage_counter_alloc (unsigned counter, unsigned num)
370 if (!ctr_labels[counter])
372 /* Generate and save a copy of this so it can be shared. */
375 ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", counter + 1);
376 ctr_labels[counter] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
378 fn_b_ctrs[counter] = fn_n_ctrs[counter];
379 fn_n_ctrs[counter] += num;
380 fn_ctr_mask |= 1 << counter;
384 /* Generate a MEM rtl to access COUNTER NO. */
387 coverage_counter_ref (unsigned counter, unsigned no)
389 unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
390 enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
393 if (no >= fn_n_ctrs[counter] - fn_b_ctrs[counter])
395 no += prg_n_ctrs[counter] + fn_b_ctrs[counter];
396 ref = plus_constant (ctr_labels[counter], gcov_size / BITS_PER_UNIT * no);
397 ref = gen_rtx_MEM (mode, ref);
398 set_mem_alias_set (ref, new_alias_set ());
403 /* Generate a checksum for a string. CHKSUM is the current
407 checksum_string (unsigned chksum, const char *string)
411 unsigned value = *string << 24;
414 for (ix = 8; ix--; value <<= 1)
418 feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0;
428 /* Compute checksum for the current function. We generate a CRC32. */
431 compute_checksum (void)
433 unsigned chksum = DECL_SOURCE_LINE (current_function_decl);
435 chksum = checksum_string (chksum, DECL_SOURCE_FILE (current_function_decl));
436 chksum = checksum_string
437 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
442 /* Begin output to the graph file for the current function.
443 Opens the output file, if not already done. Writes the
444 function header, if not already done. Returns nonzero if data
448 coverage_begin_output (void)
453 if (!bbg_function_announced)
455 const char *file = DECL_SOURCE_FILE (current_function_decl);
456 unsigned line = DECL_SOURCE_LINE (current_function_decl);
457 unsigned long offset;
459 if (!bbg_file_opened)
461 if (!gcov_open (bbg_file_name, -1))
462 error ("cannot open %s", bbg_file_name);
465 gcov_write_unsigned (GCOV_NOTE_MAGIC);
466 gcov_write_unsigned (GCOV_VERSION);
467 gcov_write_unsigned (local_tick);
472 /* Announce function */
473 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
474 gcov_write_unsigned (current_function_funcdef_no + 1);
475 gcov_write_unsigned (compute_checksum ());
476 gcov_write_string (IDENTIFIER_POINTER
477 (DECL_ASSEMBLER_NAME (current_function_decl)));
478 gcov_write_string (file);
479 gcov_write_unsigned (line);
480 gcov_write_length (offset);
482 bbg_function_announced = 1;
484 return !gcov_is_error ();
487 /* Finish coverage data for the current function. Verify no output
488 error has occurred. Save function coverage counts. */
491 coverage_end_function (void)
495 if (bbg_file_opened > 1 && gcov_is_error ())
497 warning ("error writing `%s'", bbg_file_name);
498 bbg_file_opened = -1;
503 struct function_list *item;
505 item = xmalloc (sizeof (struct function_list));
507 *functions_tail = item;
508 functions_tail = &item->next;
511 item->ident = current_function_funcdef_no + 1;
512 item->checksum = compute_checksum ();
513 for (i = 0; i != GCOV_COUNTERS; i++)
515 item->n_ctrs[i] = fn_n_ctrs[i];
516 prg_n_ctrs[i] += fn_n_ctrs[i];
517 fn_n_ctrs[i] = fn_b_ctrs[i] = 0;
519 prg_ctr_mask |= fn_ctr_mask;
522 bbg_function_announced = 0;
525 /* Creates the gcov_fn_info RECORD_TYPE. */
528 build_fn_info_type (unsigned int counters)
530 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
535 fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
538 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
539 TREE_CHAIN (field) = fields;
542 array_type = build_index_type (build_int_2 (counters - 1, 0));
543 array_type = build_array_type (unsigned_type_node, array_type);
546 field = build_decl (FIELD_DECL, NULL_TREE, array_type);
547 TREE_CHAIN (field) = fields;
550 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
555 /* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is
556 the function being processed and TYPE is the gcov_fn_info
560 build_fn_info_value (const struct function_list *function, tree type)
562 tree value = NULL_TREE;
563 tree fields = TYPE_FIELDS (type);
565 tree array_value = NULL_TREE;
568 value = tree_cons (fields,
569 convert (unsigned_intSI_type_node,
570 build_int_2 (function->ident, 0)),
572 fields = TREE_CHAIN (fields);
575 value = tree_cons (fields,
576 convert (unsigned_intSI_type_node,
577 build_int_2 (function->checksum, 0)),
579 fields = TREE_CHAIN (fields);
582 for (ix = 0; ix != GCOV_COUNTERS; ix++)
583 if (prg_ctr_mask & (1 << ix))
585 tree counters = convert (unsigned_type_node,
586 build_int_2 (function->n_ctrs[ix], 0));
588 array_value = tree_cons (NULL_TREE, counters, array_value);
591 array_value = build_constructor (TREE_TYPE (fields), nreverse (array_value));
592 value = tree_cons (fields, array_value, value);
594 value = build_constructor (type, nreverse (value));
599 /* Creates the gcov_ctr_info RECORD_TYPE. */
602 build_ctr_info_type (void)
604 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
605 tree field, fields = NULL_TREE;
606 tree gcov_ptr_type = build_pointer_type (GCOV_TYPE_NODE);
607 tree gcov_merge_fn_type;
610 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
611 TREE_CHAIN (field) = fields;
615 field = build_decl (FIELD_DECL, NULL_TREE, gcov_ptr_type);
616 TREE_CHAIN (field) = fields;
621 build_function_type_list (void_type_node,
622 gcov_ptr_type, unsigned_type_node,
624 field = build_decl (FIELD_DECL, NULL_TREE,
625 build_pointer_type (gcov_merge_fn_type));
626 TREE_CHAIN (field) = fields;
629 finish_builtin_struct (type, "__gcov_ctr_info", fields, NULL_TREE);
634 /* Creates a CONSTRUCTOR for a gcov_ctr_info. COUNTER is
635 the counter being processed and TYPE is the gcov_ctr_info
639 build_ctr_info_value (unsigned int counter, tree type)
641 tree value = NULL_TREE;
642 tree fields = TYPE_FIELDS (type);
646 value = tree_cons (fields,
647 convert (unsigned_intSI_type_node,
648 build_int_2 (prg_n_ctrs[counter], 0)),
650 fields = TREE_CHAIN (fields);
652 if (prg_n_ctrs[counter])
654 tree array_type, array;
656 array_type = build_index_type (build_int_2 (prg_n_ctrs[counter] - 1, 0));
657 array_type = build_array_type (TREE_TYPE (TREE_TYPE (fields)),
660 array = build_decl (VAR_DECL, NULL_TREE, array_type);
661 TREE_STATIC (array) = 1;
662 DECL_NAME (array) = get_identifier (XSTR (ctr_labels[counter], 0));
663 assemble_variable (array, 0, 0, 0);
665 value = tree_cons (fields,
666 build1 (ADDR_EXPR, TREE_TYPE (fields), array),
670 value = tree_cons (fields, null_pointer_node, value);
671 fields = TREE_CHAIN (fields);
673 fn = build_decl (FUNCTION_DECL,
674 get_identifier (ctr_merge_functions[counter]),
675 TREE_TYPE (TREE_TYPE (fields)));
676 DECL_EXTERNAL (fn) = 1;
677 TREE_PUBLIC (fn) = 1;
678 DECL_ARTIFICIAL (fn) = 1;
679 TREE_NOTHROW (fn) = 1;
680 value = tree_cons (fields,
681 build1 (ADDR_EXPR, TREE_TYPE (fields), fn),
684 value = build_constructor (type, nreverse (value));
689 /* Creates the gcov_info RECORD_TYPE and initializer for it. Returns a
693 build_gcov_info (void)
695 unsigned n_ctr_types, ix;
696 tree type, const_type;
697 tree fn_info_type, fn_info_value = NULL_TREE;
698 tree fn_info_ptr_type;
699 tree ctr_info_type, ctr_info_ary_type, ctr_info_value = NULL_TREE;
700 tree field, fields = NULL_TREE;
701 tree value = NULL_TREE;
702 tree filename_string;
706 const struct function_list *fn;
709 /* Count the number of active counters. */
710 for (n_ctr_types = 0, ix = 0; ix != GCOV_COUNTERS; ix++)
711 if (prg_ctr_mask & (1 << ix))
714 type = (*lang_hooks.types.make_type) (RECORD_TYPE);
715 const_type = build_qualified_type (type, TYPE_QUAL_CONST);
718 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
719 TREE_CHAIN (field) = fields;
721 value = tree_cons (field, convert (unsigned_intSI_type_node,
722 build_int_2 (GCOV_VERSION, 0)),
726 field = build_decl (FIELD_DECL, NULL_TREE, build_pointer_type (const_type));
727 TREE_CHAIN (field) = fields;
729 value = tree_cons (field, null_pointer_node, value);
732 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
733 TREE_CHAIN (field) = fields;
735 value = tree_cons (field, convert (unsigned_intSI_type_node,
736 build_int_2 (local_tick, 0)),
740 string_type = build_pointer_type (build_qualified_type (char_type_node,
742 field = build_decl (FIELD_DECL, NULL_TREE, string_type);
743 TREE_CHAIN (field) = fields;
745 filename = getpwd ();
746 filename = (filename && da_file_name[0] != '/'
747 ? concat (filename, "/", da_file_name, NULL)
749 filename_len = strlen (filename);
750 filename_string = build_string (filename_len + 1, filename);
751 if (filename != da_file_name)
753 TREE_TYPE (filename_string) =
754 build_array_type (char_type_node,
755 build_index_type (build_int_2 (filename_len, 0)));
756 value = tree_cons (field, build1 (ADDR_EXPR, string_type, filename_string),
759 /* Build the fn_info type and initializer. */
760 fn_info_type = build_fn_info_type (n_ctr_types);
761 fn_info_ptr_type = build_pointer_type (build_qualified_type
762 (fn_info_type, TYPE_QUAL_CONST));
763 for (fn = functions_head, n_fns = 0; fn; fn = fn->next, n_fns++)
764 fn_info_value = tree_cons (NULL_TREE,
765 build_fn_info_value (fn, fn_info_type),
771 array_type = build_index_type (build_int_2 (n_fns - 1, 0));
772 array_type = build_array_type (fn_info_type, array_type);
774 fn_info_value = build_constructor (array_type, nreverse (fn_info_value));
775 fn_info_value = build1 (ADDR_EXPR, fn_info_ptr_type, fn_info_value);
778 fn_info_value = null_pointer_node;
780 /* number of functions */
781 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
782 TREE_CHAIN (field) = fields;
784 value = tree_cons (field,
785 convert (unsigned_type_node, build_int_2 (n_fns, 0)),
789 field = build_decl (FIELD_DECL, NULL_TREE, fn_info_ptr_type);
790 TREE_CHAIN (field) = fields;
792 value = tree_cons (field, fn_info_value, value);
795 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
796 TREE_CHAIN (field) = fields;
798 value = tree_cons (field,
799 convert (unsigned_type_node,
800 build_int_2 (prg_ctr_mask, 0)),
804 ctr_info_type = build_ctr_info_type ();
805 ctr_info_ary_type = build_index_type (build_int_2 (n_ctr_types, 0));
806 ctr_info_ary_type = build_array_type (ctr_info_type, ctr_info_ary_type);
807 for (ix = 0; ix != GCOV_COUNTERS; ix++)
808 if (prg_ctr_mask & (1 << ix))
809 ctr_info_value = tree_cons (NULL_TREE,
810 build_ctr_info_value (ix, ctr_info_type),
812 ctr_info_value = build_constructor (ctr_info_ary_type,
813 nreverse (ctr_info_value));
815 field = build_decl (FIELD_DECL, NULL_TREE, ctr_info_ary_type);
816 TREE_CHAIN (field) = fields;
818 value = tree_cons (field, ctr_info_value, value);
820 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
822 value = build_constructor (type, nreverse (value));
827 /* Write out the structure which libgcov uses to locate all the
828 counters. The structures used here must match those defined in
829 gcov-io.h. Write out the constructor to call __gcov_init. */
832 create_coverage (void)
834 tree gcov_info, gcov_info_value;
838 rtx gcov_info_address;
840 no_coverage = 1; /* Disable any further coverage. */
845 gcov_info_value = build_gcov_info ();
847 gcov_info = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (gcov_info_value));
848 DECL_INITIAL (gcov_info) = gcov_info_value;
850 TREE_STATIC (gcov_info) = 1;
851 ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
852 DECL_NAME (gcov_info) = get_identifier (name);
854 /* Build structure. */
855 assemble_variable (gcov_info, 0, 0, 0);
857 /* Build the constructor function to invoke __gcov_init. */
858 ctor_name = concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
860 ctor = build_decl (FUNCTION_DECL, get_identifier (ctor_name),
861 build_function_type (void_type_node, NULL_TREE));
863 DECL_EXTERNAL (ctor) = 0;
865 /* It can be a static function as long as collect2 does not have
866 to scan the object file to find its ctor/dtor routine. */
867 TREE_PUBLIC (ctor) = ! targetm.have_ctors_dtors;
868 TREE_USED (ctor) = 1;
869 DECL_RESULT (ctor) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
870 DECL_UNINLINABLE (ctor) = 1;
872 ctor = (*lang_hooks.decls.pushdecl) (ctor);
873 rest_of_decl_compilation (ctor, 0, 1, 0);
874 announce_function (ctor);
875 current_function_decl = ctor;
876 make_decl_rtl (ctor, NULL);
877 init_function_start (ctor);
878 expand_function_start (ctor, 0);
879 /* Actually generate the code to call __gcov_init. */
880 gcov_info_address = force_reg (Pmode, XEXP (DECL_RTL (gcov_info), 0));
881 emit_library_call (gcov_init_libfunc, LCT_NORMAL, VOIDmode, 1,
882 gcov_info_address, Pmode);
884 expand_function_end ();
885 /* Create a dummy BLOCK. */
886 DECL_INITIAL (ctor) = make_node (BLOCK);
887 TREE_USED (DECL_INITIAL (ctor)) = 1;
889 rest_of_compilation (ctor);
892 fflush (asm_out_file);
893 current_function_decl = NULL_TREE;
895 if (targetm.have_ctors_dtors)
896 (* targetm.asm_out.constructor) (XEXP (DECL_RTL (ctor), 0),
897 DEFAULT_INIT_PRIORITY);
900 /* Perform file-level initialization. Read in data file, generate name
904 coverage_init (const char *filename)
906 int len = strlen (filename);
908 /* Name of da file. */
909 da_file_name = xmalloc (len + strlen (GCOV_DATA_SUFFIX) + 1);
910 strcpy (da_file_name, filename);
911 strcat (da_file_name, GCOV_DATA_SUFFIX);
913 /* Name of bbg file. */
914 bbg_file_name = xmalloc (len + strlen (GCOV_NOTE_SUFFIX) + 1);
915 strcpy (bbg_file_name, filename);
916 strcat (bbg_file_name, GCOV_NOTE_SUFFIX);
921 /* Performs file-level cleanup. Close graph file, generate coverage
922 variables and constructor. */
925 coverage_finish (void)
930 int error = gcov_close ();
933 unlink (bbg_file_name);
935 /* Only remove the da file, if we cannot stamp it. If we can
936 stamp it, libgcov will DTRT. */
937 unlink (da_file_name);
941 #include "gt-coverage.h"