OSDN Git Service

7f0aa8da0128115cecbb3873598283e251bd2cd1
[pf3gnuchains/gcc-fork.git] / gcc / coverage.c
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
8
9 This file is part of GCC.
10
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
14 version.
15
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
19 for more details.
20
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
24 02111-1307, USA.  */
25
26
27 #define GCOV_LINKAGE
28
29 #include "config.h"
30 #include "system.h"
31 #include "coretypes.h"
32 #include "tm.h"
33 #include "rtl.h"
34 #include "tree.h"
35 #include "flags.h"
36 #include "output.h"
37 #include "regs.h"
38 #include "expr.h"
39 #include "function.h"
40 #include "toplev.h"
41 #include "ggc.h"
42 #include "target.h"
43 #include "coverage.h"
44 #include "libfuncs.h"
45 #include "langhooks.h"
46 #include "hashtab.h"
47
48 #include "gcov-io.c"
49
50 struct function_list
51 {
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.  */
56 };
57
58 /* Counts information for a function.  */
59 typedef struct counts_entry
60 {
61   /* We hash by  */
62   unsigned ident;
63   unsigned ctr;
64
65   /* Store  */
66   unsigned checksum;
67   gcov_type *counts;
68   struct gcov_ctr_summary summary;
69
70   /* Workspace */
71   struct counts_entry *chain;
72
73 } counts_entry_t;
74
75 static struct function_list *functions_head = 0;
76 static struct function_list **functions_tail = &functions_head;
77 static unsigned no_coverage = 0;
78
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.  */
82
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.  */
87
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;
92
93 /* Name of the count data file.  */
94 static char *da_file_name;
95
96 /* Hash table of count data.  */
97 static htab_t counts_hash = NULL;
98
99 /* The names of the counter tables.  */
100 static GTY(()) rtx ctr_labels[GCOV_COUNTERS];
101
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;
105
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);
119
120 \f
121 static hashval_t
122 htab_counts_entry_hash (const void *of)
123 {
124   const counts_entry_t *entry = of;
125
126   return entry->ident * GCOV_COUNTERS + entry->ctr;
127 }
128
129 static int
130 htab_counts_entry_eq (const void *of1, const void *of2)
131 {
132   const counts_entry_t *entry1 = of1;
133   const counts_entry_t *entry2 = of2;
134
135   return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
136 }
137
138 static void
139 htab_counts_entry_del (void *of)
140 {
141   counts_entry_t *entry = of;
142
143   free (entry->counts);
144   free (entry);
145 }
146
147 /* Read in the counts file, if available.  */
148
149 static void
150 read_counts_file (void)
151 {
152   gcov_unsigned_t fn_ident = 0;
153   gcov_unsigned_t version, checksum = -1;
154   unsigned ix;
155   counts_entry_t *summaried = NULL;
156   unsigned seen_summary = 0;
157   gcov_unsigned_t tag;
158   int error = 0;
159
160   if (!gcov_open (da_file_name, 1))
161     return;
162
163   if (gcov_read_unsigned () != GCOV_DATA_MAGIC)
164     {
165       warning ("`%s' is not a gcov data file", da_file_name);
166       gcov_close ();
167       return;
168     }
169   else if ((version = gcov_read_unsigned ()) != GCOV_VERSION)
170     {
171       char v[4], e[4];
172       gcov_unsigned_t required = GCOV_VERSION;
173
174       for (ix = 4; ix--; required >>= 8, version >>= 8)
175         {
176           v[ix] = version;
177           e[ix] = required;
178         }
179       warning ("`%s' is version `%.4s', expected version `%.4s'",
180                da_file_name, v, e);
181       gcov_close ();
182       return;
183     }
184
185   counts_hash = htab_create (10,
186                              htab_counts_entry_hash, htab_counts_entry_eq,
187                              htab_counts_entry_del);
188   while ((tag = gcov_read_unsigned ()))
189     {
190       gcov_unsigned_t length;
191       gcov_position_t offset;
192
193       length = gcov_read_unsigned ();
194       offset = gcov_position ();
195       if (tag == GCOV_TAG_FUNCTION)
196         {
197           fn_ident = gcov_read_unsigned ();
198           checksum = gcov_read_unsigned ();
199           if (seen_summary)
200             {
201               /* We have already seen a summary, this means that this
202                  new function begins a new set of program runs. We
203                  must unlink the summaried chain.  */
204               counts_entry_t *entry, *chain;
205
206               for (entry = summaried; entry; entry = chain)
207                 {
208                   chain = entry->chain;
209                   entry->chain = NULL;
210                 }
211               summaried = NULL;
212               seen_summary = 0;
213             }
214         }
215       else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
216         {
217           counts_entry_t *entry;
218           struct gcov_summary summary;
219
220           gcov_read_summary (&summary);
221           seen_summary = 1;
222           for (entry = summaried; entry; entry = entry->chain)
223             {
224               struct gcov_ctr_summary *csum = &summary.ctrs[entry->ctr];
225
226               entry->summary.runs += csum->runs;
227               entry->summary.sum_all += csum->sum_all;
228               if (entry->summary.run_max < csum->run_max)
229                 entry->summary.run_max = csum->run_max;
230               entry->summary.sum_max += csum->sum_max;
231             }
232         }
233       else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
234         {
235           counts_entry_t **slot, *entry, elt;
236           unsigned n_counts = length / 8;
237           unsigned ix;
238
239           elt.ident = fn_ident;
240           elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
241
242           slot = (counts_entry_t **) htab_find_slot
243             (counts_hash, &elt, INSERT);
244           entry = *slot;
245           if (!entry)
246             {
247               *slot = entry = xcalloc (1, sizeof (counts_entry_t));
248               entry->ident = elt.ident;
249               entry->ctr = elt.ctr;
250               entry->checksum = checksum;
251               entry->summary.num = n_counts;
252               entry->counts = xcalloc (n_counts, sizeof (gcov_type));
253             }
254           else if (entry->checksum != checksum
255                    || entry->summary.num != n_counts)
256             {
257               warning ("coverage mismatch for function %u", fn_ident);
258               htab_delete (counts_hash);
259               break;
260             }
261           else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
262             {
263               warning ("cannot merge separate %s counters for function %u",
264                        ctr_names[elt.ctr], fn_ident);
265               goto skip_merge;
266             }
267
268           if (elt.ctr < GCOV_COUNTERS_SUMMABLE
269               /* This should always be true for a just allocated entry,
270                  and always false for an existing one. Check this way, in
271                  case the gcov file is corrupt.  */
272               && (!entry->chain || summaried != entry))
273             {
274               entry->chain = summaried;
275               summaried = entry;
276             }
277           for (ix = 0; ix != n_counts; ix++)
278             entry->counts[ix] += gcov_read_counter ();
279         skip_merge:;
280         }
281       gcov_sync (offset, length);
282       if ((error = gcov_is_error ()))
283         break;
284     }
285
286   if (!gcov_is_eof ())
287     {
288       warning (error < 0 ? "`%s' has overflowed" : "`%s' is corrupted",
289                da_file_name);
290       htab_delete (counts_hash);
291     }
292
293   gcov_close ();
294 }
295
296 /* Returns the counters for a particular tag.  */
297
298 gcov_type *
299 get_coverage_counts (unsigned counter, unsigned expected,
300                      const struct gcov_ctr_summary **summary)
301 {
302   counts_entry_t *entry, elt;
303
304   /* No hash table, no counts.  */
305   if (!counts_hash)
306     {
307       static int warned = 0;
308
309       if (!warned++)
310         warning ("file %s not found, execution counts assumed to be zero",
311                  da_file_name);
312       return NULL;
313     }
314
315   elt.ident = current_function_funcdef_no + 1;
316   elt.ctr = counter;
317   entry = htab_find (counts_hash, &elt);
318   if (!entry)
319     {
320       warning ("no coverage for function '%s' found.", IDENTIFIER_POINTER
321                (DECL_ASSEMBLER_NAME (current_function_decl)));
322       return 0;
323     }
324
325   if (expected != entry->summary.num
326       || compute_checksum () != entry->checksum)
327     {
328       warning ("coverage mismatch for `%s'", IDENTIFIER_POINTER
329                (DECL_ASSEMBLER_NAME (current_function_decl)));
330       return NULL;
331     }
332
333   if (summary)
334     *summary = &entry->summary;
335
336   return entry->counts;
337 }
338
339 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
340    allocation succeeded.  */
341
342 int
343 coverage_counter_alloc (unsigned counter, unsigned num)
344 {
345   if (no_coverage)
346     return 0;
347
348   if (!num)
349     return 1;
350
351   if (!ctr_labels[counter])
352     {
353       /* Generate and save a copy of this so it can be shared.  */
354       char buf[20];
355
356       ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", counter + 1);
357       ctr_labels[counter] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
358     }
359   fn_b_ctrs[counter] = fn_n_ctrs[counter];
360   fn_n_ctrs[counter] += num;
361   fn_ctr_mask |= 1 << counter;
362   return 1;
363 }
364
365 /* Generate a MEM rtl to access COUNTER NO.  */
366
367 rtx
368 coverage_counter_ref (unsigned counter, unsigned no)
369 {
370   unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
371   enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
372   rtx ref;
373
374   if (no >= fn_n_ctrs[counter] - fn_b_ctrs[counter])
375     abort ();
376   no += prg_n_ctrs[counter] + fn_b_ctrs[counter];
377   ref = plus_constant (ctr_labels[counter], gcov_size / BITS_PER_UNIT * no);
378   ref = gen_rtx_MEM (mode, ref);
379   set_mem_alias_set (ref, new_alias_set ());
380
381   return ref;
382 }
383 \f
384 /* Generate a checksum for a string.  CHKSUM is the current
385    checksum.  */
386
387 static unsigned
388 checksum_string (unsigned chksum, const char *string)
389 {
390   do
391     {
392       unsigned value = *string << 24;
393       unsigned ix;
394
395       for (ix = 8; ix--; value <<= 1)
396         {
397           unsigned feedback;
398
399           feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0;
400           chksum <<= 1;
401           chksum ^= feedback;
402         }
403     }
404   while (*string++);
405
406   return chksum;
407 }
408
409 /* Compute checksum for the current function.  We generate a CRC32.  */
410
411 static unsigned
412 compute_checksum (void)
413 {
414   unsigned chksum = DECL_SOURCE_LINE (current_function_decl);
415
416   chksum = checksum_string (chksum, DECL_SOURCE_FILE (current_function_decl));
417   chksum = checksum_string
418     (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
419
420   return chksum;
421 }
422 \f
423 /* Begin output to the graph file for the current function.
424    Opens the output file, if not already done. Writes the
425    function header, if not already done. Returns nonzero if data
426    should be output.  */
427
428 int
429 coverage_begin_output (void)
430 {
431   if (no_coverage)
432     return 0;
433
434   if (!bbg_function_announced)
435     {
436       const char *file = DECL_SOURCE_FILE (current_function_decl);
437       unsigned line = DECL_SOURCE_LINE (current_function_decl);
438       unsigned long offset;
439
440       if (!bbg_file_opened)
441         {
442           if (!gcov_open (bbg_file_name, -1))
443             error ("cannot open %s", bbg_file_name);
444           else
445             {
446               gcov_write_unsigned (GCOV_GRAPH_MAGIC);
447               gcov_write_unsigned (GCOV_VERSION);
448             }
449           bbg_file_opened = 1;
450         }
451
452       /* Announce function */
453       offset = gcov_write_tag (GCOV_TAG_FUNCTION);
454       gcov_write_unsigned (current_function_funcdef_no + 1);
455       gcov_write_unsigned (compute_checksum ());
456       gcov_write_string (IDENTIFIER_POINTER
457                          (DECL_ASSEMBLER_NAME (current_function_decl)));
458       gcov_write_string (file);
459       gcov_write_unsigned (line);
460       gcov_write_length (offset);
461
462       bbg_function_announced = 1;
463     }
464   return !gcov_is_error ();
465 }
466
467 /* Finish coverage data for the current function. Verify no output
468    error has occurred.  Save function coverage counts.  */
469
470 void
471 coverage_end_function (void)
472 {
473   unsigned i;
474
475   if (bbg_file_opened > 1 && gcov_is_error ())
476     {
477       warning ("error writing `%s'", bbg_file_name);
478       bbg_file_opened = -1;
479     }
480
481   if (fn_ctr_mask)
482     {
483       struct function_list *item;
484
485       item = xmalloc (sizeof (struct function_list));
486
487       *functions_tail = item;
488       functions_tail = &item->next;
489
490       item->next = 0;
491       item->ident = current_function_funcdef_no + 1;
492       item->checksum = compute_checksum ();
493       for (i = 0; i != GCOV_COUNTERS; i++)
494         {
495           item->n_ctrs[i] = fn_n_ctrs[i];
496           prg_n_ctrs[i] += fn_n_ctrs[i];
497           fn_n_ctrs[i] = fn_b_ctrs[i] = 0;
498         }
499       prg_ctr_mask |= fn_ctr_mask;
500       fn_ctr_mask = 0;
501     }
502   bbg_function_announced = 0;
503 }
504
505 /* Creates the gcov_fn_info RECORD_TYPE.  */
506
507 static tree
508 build_fn_info_type (unsigned int counters)
509 {
510   tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
511   tree field, fields;
512   tree array_type;
513
514   /* ident */
515   fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
516
517   /* checksum */
518   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
519   TREE_CHAIN (field) = fields;
520   fields = field;
521
522   array_type = build_index_type (build_int_2 (counters - 1, 0));
523   array_type = build_array_type (unsigned_type_node, array_type);
524
525   /* counters */
526   field = build_decl (FIELD_DECL, NULL_TREE, array_type);
527   TREE_CHAIN (field) = fields;
528   fields = field;
529
530   finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
531
532   return type;
533 }
534
535 /* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is
536    the function being processed and TYPE is the gcov_fn_info
537    RECORD_TYPE.  */
538
539 static tree
540 build_fn_info_value (const struct function_list *function, tree type)
541 {
542   tree value = NULL_TREE;
543   tree fields = TYPE_FIELDS (type);
544   unsigned ix;
545   tree array_value = NULL_TREE;
546
547   /* ident */
548   value = tree_cons (fields,
549                      convert (unsigned_intSI_type_node,
550                               build_int_2 (function->ident, 0)),
551                      value);
552   fields = TREE_CHAIN (fields);
553
554   /* checksum */
555   value = tree_cons (fields,
556                      convert (unsigned_intSI_type_node,
557                               build_int_2 (function->checksum, 0)),
558                      value);
559   fields = TREE_CHAIN (fields);
560
561   /* counters */
562   for (ix = 0; ix != GCOV_COUNTERS; ix++)
563     if (prg_ctr_mask & (1 << ix))
564       {
565         tree counters = convert (unsigned_type_node,
566                                  build_int_2 (function->n_ctrs[ix], 0));
567
568         array_value = tree_cons (NULL_TREE, counters, array_value);
569       }
570
571   array_value = build_constructor (TREE_TYPE (fields), nreverse (array_value));
572   value = tree_cons (fields, array_value, value);
573
574   value = build_constructor (type, nreverse (value));
575
576   return value;
577 }
578
579 /* Creates the gcov_ctr_info RECORD_TYPE.  */
580
581 static tree
582 build_ctr_info_type (void)
583 {
584   tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
585   tree field, fields = NULL_TREE;
586   tree gcov_ptr_type = build_pointer_type (GCOV_TYPE_NODE);
587   tree gcov_merge_fn_type;
588
589   /* counters */
590   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
591   TREE_CHAIN (field) = fields;
592   fields = field;
593
594   /* values */
595   field = build_decl (FIELD_DECL, NULL_TREE, gcov_ptr_type);
596   TREE_CHAIN (field) = fields;
597   fields = field;
598
599   /* merge */
600   gcov_merge_fn_type =
601     build_function_type_list (void_type_node,
602                               gcov_ptr_type, unsigned_type_node,
603                               NULL_TREE);
604   field = build_decl (FIELD_DECL, NULL_TREE,
605                       build_pointer_type (gcov_merge_fn_type));
606   TREE_CHAIN (field) = fields;
607   fields = field;
608
609   finish_builtin_struct (type, "__gcov_ctr_info", fields, NULL_TREE);
610
611   return type;
612 }
613
614 /* Creates a CONSTRUCTOR for a gcov_ctr_info. COUNTER is
615    the counter being processed and TYPE is the gcov_ctr_info
616    RECORD_TYPE.  */
617
618 static tree
619 build_ctr_info_value (unsigned int counter, tree type)
620 {
621   tree value = NULL_TREE;
622   tree fields = TYPE_FIELDS (type);
623   tree fn;
624
625   /* counters */
626   value = tree_cons (fields,
627                      convert (unsigned_intSI_type_node,
628                               build_int_2 (prg_n_ctrs[counter], 0)),
629                      value);
630   fields = TREE_CHAIN (fields);
631
632   if (prg_n_ctrs[counter])
633     {
634       tree array_type, array;
635
636       array_type = build_index_type (build_int_2 (prg_n_ctrs[counter] - 1, 0));
637       array_type = build_array_type (TREE_TYPE (TREE_TYPE (fields)),
638                                      array_type);
639
640       array = build (VAR_DECL, array_type, NULL_TREE, NULL_TREE);
641       TREE_STATIC (array) = 1;
642       DECL_NAME (array) = get_identifier (XSTR (ctr_labels[counter], 0));
643       assemble_variable (array, 0, 0, 0);
644
645       value = tree_cons (fields,
646                          build1 (ADDR_EXPR, TREE_TYPE (fields), array),
647                          value);
648     }
649   else
650     value = tree_cons (fields, null_pointer_node, value);
651   fields = TREE_CHAIN (fields);
652
653   fn = build_decl (FUNCTION_DECL,
654                    get_identifier (ctr_merge_functions[counter]),
655                    TREE_TYPE (TREE_TYPE (fields)));
656   DECL_EXTERNAL (fn) = 1;
657   TREE_PUBLIC (fn) = 1;
658   DECL_ARTIFICIAL (fn) = 1;
659   TREE_NOTHROW (fn) = 1;
660   value = tree_cons (fields,
661                      build1 (ADDR_EXPR, TREE_TYPE (fields), fn),
662                      value);
663
664   value = build_constructor (type, nreverse (value));
665
666   return value;
667 }
668
669 /* Creates the gcov_info RECORD_TYPE and initializer for it. Returns a
670    CONSTRUCTOR.  */
671
672 static tree
673 build_gcov_info (void)
674 {
675   unsigned n_ctr_types, ix;
676   tree type, const_type;
677   tree fn_info_type, fn_info_value = NULL_TREE;
678   tree fn_info_ptr_type;
679   tree ctr_info_type, ctr_info_ary_type, ctr_info_value = NULL_TREE;
680   tree field, fields = NULL_TREE;
681   tree value = NULL_TREE;
682   tree filename_string;
683   char *filename;
684   int filename_len;
685   unsigned n_fns;
686   const struct function_list *fn;
687   tree string_type;
688
689   /* Count the number of active counters.  */
690   for (n_ctr_types = 0, ix = 0; ix != GCOV_COUNTERS; ix++)
691     if (prg_ctr_mask & (1 << ix))
692       n_ctr_types++;
693
694   type = (*lang_hooks.types.make_type) (RECORD_TYPE);
695   const_type = build_qualified_type (type, TYPE_QUAL_CONST);
696
697   /* Version ident */
698   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
699   TREE_CHAIN (field) = fields;
700   fields = field;
701   value = tree_cons (field, convert (unsigned_intSI_type_node,
702                                      build_int_2 (GCOV_VERSION, 0)),
703                      value);
704
705   /* next -- NULL */
706   field = build_decl (FIELD_DECL, NULL_TREE, build_pointer_type (const_type));
707   TREE_CHAIN (field) = fields;
708   fields = field;
709   value = tree_cons (field, null_pointer_node, value);
710
711   /* Filename */
712   string_type = build_pointer_type (build_qualified_type (char_type_node,
713                                                     TYPE_QUAL_CONST));
714   field = build_decl (FIELD_DECL, NULL_TREE, string_type);
715   TREE_CHAIN (field) = fields;
716   fields = field;
717   filename = getpwd ();
718   filename = (filename && da_file_name[0] != '/'
719               ? concat (filename, "/", da_file_name, NULL)
720               : da_file_name);
721   filename_len = strlen (filename);
722   filename_string = build_string (filename_len + 1, filename);
723   if (filename != da_file_name)
724     free (filename);
725   TREE_TYPE (filename_string) =
726           build_array_type (char_type_node,
727                             build_index_type (build_int_2 (filename_len, 0)));
728   value = tree_cons (field, build1 (ADDR_EXPR, string_type, filename_string),
729                      value);
730
731   /* Build the fn_info type and initializer.  */
732   fn_info_type = build_fn_info_type (n_ctr_types);
733   fn_info_ptr_type = build_pointer_type (build_qualified_type
734                                          (fn_info_type, TYPE_QUAL_CONST));
735   for (fn = functions_head, n_fns = 0; fn; fn = fn->next, n_fns++)
736     fn_info_value = tree_cons (NULL_TREE,
737                                build_fn_info_value (fn, fn_info_type),
738                                fn_info_value);
739   if (n_fns)
740     {
741       tree array_type;
742
743       array_type = build_index_type (build_int_2 (n_fns - 1, 0));
744       array_type = build_array_type (fn_info_type, array_type);
745
746       fn_info_value = build_constructor (array_type, nreverse (fn_info_value));
747       fn_info_value = build1 (ADDR_EXPR, fn_info_ptr_type, fn_info_value);
748     }
749   else
750     fn_info_value = null_pointer_node;
751
752   /* number of functions */
753   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
754   TREE_CHAIN (field) = fields;
755   fields = field;
756   value = tree_cons (field,
757                      convert (unsigned_type_node, build_int_2 (n_fns, 0)),
758                      value);
759
760   /* fn_info table */
761   field = build_decl (FIELD_DECL, NULL_TREE, fn_info_ptr_type);
762   TREE_CHAIN (field) = fields;
763   fields = field;
764   value = tree_cons (field, fn_info_value, value);
765
766   /* counter_mask */
767   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
768   TREE_CHAIN (field) = fields;
769   fields = field;
770   value = tree_cons (field,
771                      convert (unsigned_type_node,
772                               build_int_2 (prg_ctr_mask, 0)),
773                      value);
774
775   /* counters */
776   ctr_info_type = build_ctr_info_type ();
777   ctr_info_ary_type = build_index_type (build_int_2 (n_ctr_types, 0));
778   ctr_info_ary_type = build_array_type (ctr_info_type, ctr_info_ary_type);
779   for (ix = 0; ix != GCOV_COUNTERS; ix++)
780     if (prg_ctr_mask & (1 << ix))
781       ctr_info_value = tree_cons (NULL_TREE,
782                                   build_ctr_info_value (ix, ctr_info_type),
783                                   ctr_info_value);
784   ctr_info_value = build_constructor (ctr_info_ary_type,
785                                       nreverse (ctr_info_value));
786
787   field = build_decl (FIELD_DECL, NULL_TREE, ctr_info_ary_type);
788   TREE_CHAIN (field) = fields;
789   fields = field;
790   value = tree_cons (field, ctr_info_value, value);
791
792   finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
793
794   value = build_constructor (type, nreverse (value));
795
796   return value;
797 }
798
799 /* Write out the structure which libgcov uses to locate all the
800    counters.  The structures used here must match those defined in
801    gcov-io.h.  Write out the constructor to call __gcov_init.  */
802
803 static void
804 create_coverage (void)
805 {
806   tree gcov_info, gcov_info_value;
807   char name[20];
808   char *ctor_name;
809   tree ctor;
810   rtx gcov_info_address;
811
812   no_coverage = 1; /* Disable any further coverage.  */
813
814   if (!prg_ctr_mask)
815     return;
816
817   gcov_info_value = build_gcov_info ();
818
819   gcov_info = build (VAR_DECL, TREE_TYPE (gcov_info_value),
820                      NULL_TREE, NULL_TREE);
821   DECL_INITIAL (gcov_info) = gcov_info_value;
822
823   TREE_STATIC (gcov_info) = 1;
824   ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
825   DECL_NAME (gcov_info) = get_identifier (name);
826
827   /* Build structure.  */
828   assemble_variable (gcov_info, 0, 0, 0);
829
830   /* Build the constructor function to invoke __gcov_init.  */
831   ctor_name = concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
832                       "_GCOV", NULL);
833   ctor = build_decl (FUNCTION_DECL, get_identifier (ctor_name),
834                      build_function_type (void_type_node, NULL_TREE));
835   free (ctor_name);
836   DECL_EXTERNAL (ctor) = 0;
837
838   /* It can be a static function as long as collect2 does not have
839      to scan the object file to find its ctor/dtor routine.  */
840   TREE_PUBLIC (ctor) = ! targetm.have_ctors_dtors;
841   TREE_USED (ctor) = 1;
842   DECL_RESULT (ctor) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
843   DECL_UNINLINABLE (ctor) = 1;
844
845   ctor = (*lang_hooks.decls.pushdecl) (ctor);
846   rest_of_decl_compilation (ctor, 0, 1, 0);
847   announce_function (ctor);
848   current_function_decl = ctor;
849   DECL_INITIAL (ctor) = error_mark_node;
850   make_decl_rtl (ctor, NULL);
851   init_function_start (ctor);
852   (*lang_hooks.decls.pushlevel) (0);
853   expand_function_start (ctor, 0);
854
855   /* Actually generate the code to call __gcov_init.  */
856   gcov_info_address = force_reg (Pmode, XEXP (DECL_RTL (gcov_info), 0));
857   emit_library_call (gcov_init_libfunc, LCT_NORMAL, VOIDmode, 1,
858                      gcov_info_address, Pmode);
859
860   expand_function_end ();
861   (*lang_hooks.decls.poplevel) (1, 0, 1);
862
863   rest_of_compilation (ctor);
864
865   if (! quiet_flag)
866     fflush (asm_out_file);
867   current_function_decl = NULL_TREE;
868
869   if (targetm.have_ctors_dtors)
870     (* targetm.asm_out.constructor) (XEXP (DECL_RTL (ctor), 0),
871                                      DEFAULT_INIT_PRIORITY);
872 }
873 \f
874 /* Perform file-level initialization. Read in data file, generate name
875    of graph file.  */
876
877 void
878 coverage_init (const char *filename)
879 {
880   int len = strlen (filename);
881
882   /* Name of da file.  */
883   da_file_name = (char *) xmalloc (len + strlen (GCOV_DATA_SUFFIX) + 1);
884   strcpy (da_file_name, filename);
885   strcat (da_file_name, GCOV_DATA_SUFFIX);
886
887   /* Name of bbg file.  */
888   bbg_file_name = (char *) xmalloc (len + strlen (GCOV_GRAPH_SUFFIX) + 1);
889   strcpy (bbg_file_name, filename);
890   strcat (bbg_file_name, GCOV_GRAPH_SUFFIX);
891
892   read_counts_file ();
893 }
894
895 /* Performs file-level cleanup.  Close graph file, generate coverage
896    variables and constructor.  */
897
898 void
899 coverage_finish (void)
900 {
901   create_coverage ();
902   if (bbg_file_opened)
903     {
904       int error = gcov_close ();
905
906       if (error)
907         unlink (bbg_file_name);
908 #if SELF_COVERAGE
909       /* If the compiler is instrumented, we should not
910          unconditionally remove the counts file, because we might be
911          recompiling ourselves. The .da files are all removed during
912          copying the stage1 files.  */
913       if (error)
914 #endif
915         unlink (da_file_name);
916     }
917 }
918
919 #include "gt-coverage.h"