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