Break out coverage routines to new file.
[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   const char *name;             /* function name */
54   unsigned cfg_checksum;        /* function checksum */
55   unsigned n_counter_sections;  /* number of counter sections */
56   struct gcov_counter_section counter_sections[MAX_COUNTER_SECTIONS];
57                                 /* the sections */
58 };
59
60 /* Counts information for a function.  */
61 typedef struct counts_entry
62 {
63   /* We hash by  */
64   char *function_name;
65   unsigned section;
66   
67   /* Store  */
68   unsigned checksum;
69   unsigned n_counts;
70   gcov_type *counts;
71   unsigned merged;
72   gcov_type max_counter;
73   gcov_type max_counter_sum;
74
75   /* Workspace */
76   struct counts_entry *chain;
77   
78 } counts_entry_t;
79
80 static struct function_list *functions_head = 0;
81 static struct function_list **functions_tail = &functions_head;
82
83 /* Instantiate the profile info structure.  */
84
85 struct profile_info profile_info;
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 name of the count table. Used by the edge profiling code.  */
99 static GTY(()) rtx profiler_label;
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 void set_purpose PARAMS ((tree, tree));
109 static rtx label_for_tag PARAMS ((unsigned));
110 static tree build_counter_section_fields PARAMS ((void));
111 static tree build_counter_section_value PARAMS ((unsigned, unsigned));
112 static tree build_counter_section_data_fields PARAMS ((void));
113 static tree build_counter_section_data_value PARAMS ((unsigned, unsigned));
114 static tree build_function_info_fields PARAMS ((void));
115 static tree build_function_info_value PARAMS ((struct function_list *));
116 static tree build_gcov_info_fields PARAMS ((tree));
117 static tree build_gcov_info_value PARAMS ((void));
118 static void create_coverage PARAMS ((void));
119
120 \f
121 static hashval_t
122 htab_counts_entry_hash (of)
123      const void *of;
124 {
125   const counts_entry_t *entry = of;
126
127   return htab_hash_string (entry->function_name) ^ entry->section;
128 }
129
130 static int
131 htab_counts_entry_eq (of1, of2)
132      const void *of1;
133      const void *of2;
134 {
135   const counts_entry_t *entry1 = of1;
136   const counts_entry_t *entry2 = of2;
137
138   return !strcmp (entry1->function_name, entry2->function_name)
139     && entry1->section == entry2->section;
140 }
141
142 static void
143 htab_counts_entry_del (of)
144      void *of;
145 {
146   counts_entry_t *entry = of;
147
148   free (entry->function_name);
149   free (entry->counts);
150   free (entry);
151 }
152
153 /* Read in the counts file, if available.  */
154
155 static void
156 read_counts_file ()
157 {
158   char *function_name_buffer = NULL;
159   unsigned version, ix, checksum = -1;
160   counts_entry_t *summaried = NULL;
161   unsigned seen_summary = 0;
162   
163   if (!gcov_open (da_file_name, 1))
164     return;
165   
166   if (gcov_read_unsigned () != GCOV_DATA_MAGIC)
167     {
168       warning ("`%s' is not a gcov data file", da_file_name);
169       gcov_close ();
170       return;
171     }
172   else if ((version = gcov_read_unsigned ()) != GCOV_VERSION)
173     {
174       char v[4], e[4];
175       unsigned required = GCOV_VERSION;
176       
177       for (ix = 4; ix--; required >>= 8, version >>= 8)
178         {
179           v[ix] = version;
180           e[ix] = required;
181         }
182       warning ("`%s' is version `%.4s', expected version `%.4s'",
183                da_file_name, v, e);
184       gcov_close ();
185       return;
186     }
187   
188   counts_hash = htab_create (10,
189                              htab_counts_entry_hash, htab_counts_entry_eq,
190                              htab_counts_entry_del);
191   while (!gcov_is_eof ())
192     {
193       unsigned tag, length;
194       unsigned long offset;
195       int error;
196       
197       tag = gcov_read_unsigned ();
198       length = gcov_read_unsigned ();
199       offset = gcov_position ();
200       if (tag == GCOV_TAG_FUNCTION)
201         {
202           const char *string = gcov_read_string ();
203           free (function_name_buffer);
204           function_name_buffer = string ? xstrdup (string) : NULL;
205           checksum = gcov_read_unsigned ();
206           if (seen_summary)
207             {
208               /* We have already seen a summary, this means that this
209                  new function begins a new set of program runs. We
210                  must unlink the summaried chain.  */
211               counts_entry_t *entry, *chain;
212               
213               for (entry = summaried; entry; entry = chain)
214                 {
215                   chain = entry->chain;
216                   
217                   entry->max_counter_sum += entry->max_counter;
218                   entry->chain = NULL;
219                 }
220               summaried = NULL;
221               seen_summary = 0;
222             }
223         }
224       else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
225         {
226           counts_entry_t *entry;
227           struct gcov_summary summary;
228           
229           gcov_read_summary (&summary);
230           seen_summary = 1;
231           for (entry = summaried; entry; entry = entry->chain)
232             {
233               entry->merged += summary.runs;
234               if (entry->max_counter < summary.arc_sum_max)
235                 entry->max_counter = summary.arc_sum_max;
236             }
237         }
238       else if (GCOV_TAG_IS_SUBTAG (GCOV_TAG_FUNCTION, tag)
239                && function_name_buffer)
240         {
241           counts_entry_t **slot, *entry, elt;
242           unsigned n_counts = length / 8;
243           unsigned ix;
244
245           elt.function_name = function_name_buffer;
246           elt.section = tag;
247
248           slot = (counts_entry_t **) htab_find_slot
249             (counts_hash, &elt, INSERT);
250           entry = *slot;
251           if (!entry)
252             {
253               *slot = entry = xmalloc (sizeof (counts_entry_t));
254               entry->function_name = xstrdup (function_name_buffer);
255               entry->section = tag;
256               entry->checksum = checksum;
257               entry->n_counts = n_counts;
258               entry->counts = xcalloc (n_counts, sizeof (gcov_type));
259             }
260           else if (entry->checksum != checksum || entry->n_counts != n_counts)
261             {
262               warning ("profile mismatch for `%s'", function_name_buffer);
263               htab_delete (counts_hash);
264               break;
265             }
266           
267           /* This should always be true for a just allocated entry,
268              and always false for an existing one. Check this way, in
269              case the gcov file is corrupt.  */
270           if (!entry->chain || summaried != entry)
271             {
272               entry->chain = summaried;
273               summaried = entry;
274             }
275           for (ix = 0; ix != n_counts; ix++)
276             entry->counts[ix] += gcov_read_counter ();
277         }
278       gcov_seek (offset, length);
279       if ((error = gcov_is_error ()))
280         {
281           warning (error < 0 ? "`%s' has overflowed" : "`%s' is corrupted",
282                    da_file_name);
283           htab_delete (counts_hash);
284           break;
285         }
286     }
287
288   free (function_name_buffer);
289   gcov_close ();
290 }
291
292 /* Returns the counters for a particular tag.  */
293
294 gcov_type *
295 get_coverage_counts (unsigned tag, unsigned expected)
296 {
297   counts_entry_t *entry, elt;
298
299   profile_info.max_counter_in_program = 0;
300   profile_info.count_profiles_merged = 0;
301
302   /* No hash table, no counts. */
303   if (!counts_hash)
304     {
305       static int warned = 0;
306
307       if (!warned++)
308         warning ("file %s not found, execution counts assumed to be zero",
309                  da_file_name);
310       return NULL;
311     }
312
313   elt.function_name
314     = (char *) IDENTIFIER_POINTER
315     (DECL_ASSEMBLER_NAME (current_function_decl));
316   elt.section = tag;
317   entry = htab_find (counts_hash, &elt);
318   if (!entry)
319     {
320       warning ("No profile for function '%s' found.", elt.function_name);
321       return 0;
322     }
323   
324   if (expected != entry->n_counts
325       || compute_checksum () != entry->checksum)
326     {
327       warning ("profile mismatch for `%s'", elt.function_name);
328       return NULL;
329     }
330
331   profile_info.count_profiles_merged = entry->merged;
332   profile_info.max_counter_in_program = entry->max_counter_sum;
333
334   return entry->counts;
335 }
336 \f
337 /* Generate a checksum for a string.  CHKSUM is the current
338    checksum. */
339
340 static unsigned
341 checksum_string (unsigned chksum, const char *string)
342 {
343   do
344     {
345       unsigned value = *string << 24;
346       unsigned ix;
347
348       for (ix = 8; ix--; value <<= 1)
349         {
350           unsigned feedback;
351           
352           feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0;
353           chksum <<= 1;
354           chksum ^= feedback;
355         }
356     }
357   while (*string++);
358   
359   return chksum;
360 }
361
362 /* Compute checksum for the current function.  We generate a CRC32.  */
363
364 static unsigned
365 compute_checksum ()
366 {
367   unsigned chksum = DECL_SOURCE_LINE (current_function_decl);
368
369   chksum = checksum_string (chksum, DECL_SOURCE_FILE (current_function_decl));
370   chksum = checksum_string
371     (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
372
373   return chksum;
374 }
375 \f
376 /* Begin output to the graph file for the current function.
377    Opens the output file, if not already done. Writes the
378    function header, if not already done. Returns non-zero if data
379    should be output.  */
380
381 int
382 coverage_begin_output ()
383 {
384   if (!bbg_function_announced)
385     {
386       const char *file = DECL_SOURCE_FILE (current_function_decl);
387       unsigned line = DECL_SOURCE_LINE (current_function_decl);
388       unsigned long offset;
389       
390       if (!bbg_file_opened)
391         {
392           if (!gcov_open (bbg_file_name, -1))
393             error ("cannot open %s", bbg_file_name);
394           else
395             {
396               gcov_write_unsigned (GCOV_GRAPH_MAGIC);
397               gcov_write_unsigned (GCOV_VERSION);
398             }
399           bbg_file_opened = 1;
400         }
401       
402       /* Announce function */
403       offset = gcov_write_tag (GCOV_TAG_FUNCTION);
404       gcov_write_string (IDENTIFIER_POINTER
405                          (DECL_ASSEMBLER_NAME (current_function_decl)));
406       gcov_write_unsigned (compute_checksum ());
407       gcov_write_string (file);
408       gcov_write_unsigned (line);
409       gcov_write_length (offset);
410
411       bbg_function_announced = 1;
412     }
413   return !gcov_is_error ();
414 }
415
416 /* Finish coverage data for the current function. Verify no output
417    error has occurred.  Save function coverage counts.  */
418
419 void
420 coverage_end_function ()
421 {
422   unsigned i;
423   
424   if (bbg_file_opened > 1 && gcov_is_error ())
425     {   
426       warning ("error writing `%s'", bbg_file_name);
427       bbg_file_opened = -1;
428     }
429   
430   for (i = 0; i != profile_info.n_sections; i++)
431     if (profile_info.section_info[i].n_counters_now)
432       {
433         struct function_list *item;
434       
435         /* ??? Probably should re-use the existing struct function.  */
436         item = xmalloc (sizeof (struct function_list));
437       
438         *functions_tail = item;
439         functions_tail = &item->next;
440         
441         item->next = 0;
442         item->name = xstrdup (IDENTIFIER_POINTER
443                               (DECL_ASSEMBLER_NAME (current_function_decl)));
444         item->cfg_checksum = compute_checksum ();
445         item->n_counter_sections = 0;
446         for (i = 0; i < profile_info.n_sections; i++)
447           if (profile_info.section_info[i].n_counters_now)
448             {
449               item->counter_sections[item->n_counter_sections].tag = 
450                 profile_info.section_info[i].tag;
451               item->counter_sections[item->n_counter_sections].n_counters =
452                 profile_info.section_info[i].n_counters_now;
453               item->n_counter_sections++;
454               profile_info.section_info[i].n_counters
455                 += profile_info.section_info[i].n_counters_now;
456               profile_info.section_info[i].n_counters_now = 0;
457             }
458         break;
459       }
460   bbg_function_announced = 0;
461 }
462
463 /* Set FIELDS as purpose to VALUE.  */
464 static void
465 set_purpose (value, fields)
466      tree value;
467      tree fields;
468 {
469   tree act_field, act_value;
470   
471   for (act_field = fields, act_value = value;
472        act_field;
473        act_field = TREE_CHAIN (act_field), act_value = TREE_CHAIN (act_value))
474     TREE_PURPOSE (act_value) = act_field;
475 }
476
477 /* Returns label for base of counters inside TAG section.  */
478 static rtx
479 label_for_tag (tag)
480      unsigned tag;
481 {
482   switch (tag)
483     {
484     case GCOV_TAG_ARC_COUNTS:
485       return profiler_label;
486     default:
487       abort ();
488     }
489 }
490
491 /* Creates fields of struct counter_section (in gcov-io.h).  */
492 static tree
493 build_counter_section_fields ()
494 {
495   tree field, fields;
496
497   /* tag */
498   fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
499
500   /* n_counters */
501   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
502   TREE_CHAIN (field) = fields;
503   fields = field;
504
505   return fields;
506 }
507
508 /* Creates value of struct counter_section (in gcov-io.h).  */
509 static tree
510 build_counter_section_value (tag, n_counters)
511      unsigned tag;
512      unsigned n_counters;
513 {
514   tree value = NULL_TREE;
515
516   /* tag */
517   value = tree_cons (NULL_TREE,
518                      convert (unsigned_type_node,
519                               build_int_2 (tag, 0)),
520                      value);
521   
522   /* n_counters */
523   value = tree_cons (NULL_TREE,
524                      convert (unsigned_type_node,
525                               build_int_2 (n_counters, 0)),
526                      value);
527
528   return value;
529 }
530
531 /* Creates fields of struct counter_section_data (in gcov-io.h).  */
532 static tree
533 build_counter_section_data_fields ()
534 {
535   tree field, fields, gcov_type, gcov_ptr_type;
536
537   gcov_type = make_signed_type (GCOV_TYPE_SIZE);
538   gcov_ptr_type =
539           build_pointer_type (build_qualified_type (gcov_type,
540                                                     TYPE_QUAL_CONST));
541
542   /* tag */
543   fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
544
545   /* n_counters */
546   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
547   TREE_CHAIN (field) = fields;
548   fields = field;
549
550   /* counters */
551   field = build_decl (FIELD_DECL, NULL_TREE, gcov_ptr_type);
552   TREE_CHAIN (field) = fields;
553   fields = field;
554
555   return fields;
556 }
557
558 /* Creates value of struct counter_section_data (in gcov-io.h).  */
559 static tree
560 build_counter_section_data_value (tag, n_counters)
561      unsigned tag;
562      unsigned n_counters;
563 {
564   tree value = NULL_TREE, counts_table, gcov_type, gcov_ptr_type;
565
566   gcov_type = make_signed_type (GCOV_TYPE_SIZE);
567   gcov_ptr_type
568     = build_pointer_type (build_qualified_type
569                           (gcov_type, TYPE_QUAL_CONST));
570
571   /* tag */
572   value = tree_cons (NULL_TREE,
573                      convert (unsigned_type_node,
574                               build_int_2 (tag, 0)),
575                      value);
576   
577   /* n_counters */
578   value = tree_cons (NULL_TREE,
579                      convert (unsigned_type_node,
580                               build_int_2 (n_counters, 0)),
581                      value);
582
583   /* counters */
584   if (n_counters)
585     {
586       tree gcov_type_array_type =
587               build_array_type (gcov_type,
588                                 build_index_type (build_int_2 (n_counters - 1,
589                                                                0)));
590       counts_table =
591               build (VAR_DECL, gcov_type_array_type, NULL_TREE, NULL_TREE);
592       TREE_STATIC (counts_table) = 1;
593       DECL_NAME (counts_table) = get_identifier (XSTR (label_for_tag (tag), 0));
594       assemble_variable (counts_table, 0, 0, 0);
595       counts_table = build1 (ADDR_EXPR, gcov_ptr_type, counts_table);
596     }
597   else
598     counts_table = null_pointer_node;
599
600   value = tree_cons (NULL_TREE, counts_table, value);
601
602   return value;
603 }
604
605 /* Creates fields for struct function_info type (in gcov-io.h).  */
606 static tree
607 build_function_info_fields ()
608 {
609   tree field, fields, counter_section_fields, counter_section_type;
610   tree counter_sections_ptr_type;
611   tree string_type =
612           build_pointer_type (build_qualified_type (char_type_node,
613                                                     TYPE_QUAL_CONST));
614   /* name */
615   fields = build_decl (FIELD_DECL, NULL_TREE, string_type);
616
617   /* checksum */
618   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
619   TREE_CHAIN (field) = fields;
620   fields = field;
621
622   /* n_counter_sections */
623   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
624   TREE_CHAIN (field) = fields;
625   fields = field;
626
627   /* counter_sections */
628   counter_section_fields = build_counter_section_fields ();
629   counter_section_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
630   finish_builtin_struct (counter_section_type, "__counter_section",
631                          counter_section_fields, NULL_TREE);
632   counter_sections_ptr_type =
633           build_pointer_type
634                 (build_qualified_type (counter_section_type,
635                                        TYPE_QUAL_CONST));
636   field = build_decl (FIELD_DECL, NULL_TREE, counter_sections_ptr_type);
637   TREE_CHAIN (field) = fields;
638   fields = field;
639
640   return fields;
641 }
642
643 /* Creates value for struct function_info (in gcov-io.h).  */
644 static tree
645 build_function_info_value (function)
646      struct function_list *function;
647 {
648   tree value = NULL_TREE;
649   size_t name_len = strlen (function->name);
650   tree fname = build_string (name_len + 1, function->name);
651   tree string_type =
652           build_pointer_type (build_qualified_type (char_type_node,
653                                                     TYPE_QUAL_CONST));
654   tree counter_section_fields, counter_section_type, counter_sections_value;
655   tree counter_sections_ptr_type, counter_sections_array_type;
656   unsigned i;
657
658   /* name */
659   TREE_TYPE (fname) =
660           build_array_type (char_type_node,
661                             build_index_type (build_int_2 (name_len, 0)));
662   value = tree_cons (NULL_TREE,
663                      build1 (ADDR_EXPR,
664                              string_type,
665                              fname),
666                      value);
667
668   /* checksum */
669   value = tree_cons (NULL_TREE,
670                      convert (unsigned_type_node,
671                               build_int_2 (function->cfg_checksum, 0)),
672                      value);
673
674   /* n_counter_sections */
675
676   value = tree_cons (NULL_TREE,
677                      convert (unsigned_type_node,
678                               build_int_2 (function->n_counter_sections, 0)),
679                     value);
680
681   /* counter_sections */
682   counter_section_fields = build_counter_section_fields ();
683   counter_section_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
684   counter_sections_ptr_type =
685           build_pointer_type
686                 (build_qualified_type (counter_section_type,
687                                        TYPE_QUAL_CONST));
688   counter_sections_array_type =
689           build_array_type (counter_section_type,
690                             build_index_type (
691                                 build_int_2 (function->n_counter_sections - 1,
692                                              0)));
693
694   counter_sections_value = NULL_TREE;
695   for (i = 0; i < function->n_counter_sections; i++)
696     {
697       tree counter_section_value
698         = build_counter_section_value (function->counter_sections[i].tag,
699                                        function->counter_sections[i].n_counters);
700       set_purpose (counter_section_value, counter_section_fields);
701       counter_sections_value =
702         tree_cons (NULL_TREE,
703                    build_constructor (counter_section_type,
704                                       nreverse (counter_section_value)),
705                    counter_sections_value);
706     }
707   finish_builtin_struct (counter_section_type, "__counter_section",
708                          counter_section_fields, NULL_TREE);
709
710   if (function->n_counter_sections)
711     {
712       counter_sections_value = 
713               build_constructor (counter_sections_array_type,
714                                  nreverse (counter_sections_value)),
715       counter_sections_value = build1 (ADDR_EXPR,
716                                        counter_sections_ptr_type,
717                                        counter_sections_value);
718     }
719   else
720     counter_sections_value = null_pointer_node;
721
722   value = tree_cons (NULL_TREE, counter_sections_value, value);
723
724   return value;
725 }
726
727 /* Creates fields of struct gcov_info type (in gcov-io.h).  */
728 static tree
729 build_gcov_info_fields (gcov_info_type)
730      tree gcov_info_type;
731 {
732   tree field, fields;
733   char *filename;
734   int filename_len;
735   tree string_type =
736           build_pointer_type (build_qualified_type (char_type_node,
737                                                     TYPE_QUAL_CONST));
738   tree function_info_fields, function_info_type, function_info_ptr_type;
739   tree counter_section_data_fields, counter_section_data_type;
740   tree counter_section_data_ptr_type;
741
742   /* Version ident */
743   fields = build_decl (FIELD_DECL, NULL_TREE, long_unsigned_type_node);
744
745   /* next -- NULL */
746   field = build_decl (FIELD_DECL, NULL_TREE,
747                       build_pointer_type
748                       (build_qualified_type
749                        (gcov_info_type, TYPE_QUAL_CONST)));
750   TREE_CHAIN (field) = fields;
751   fields = field;
752   
753   /* Filename */
754   filename = getpwd ();
755   filename = (filename && da_file_name[0] != '/'
756               ? concat (filename, "/", da_file_name, NULL)
757               : da_file_name);
758   filename_len = strlen (filename);
759   if (filename != da_file_name)
760     free (filename);
761
762   field = build_decl (FIELD_DECL, NULL_TREE, string_type);
763   TREE_CHAIN (field) = fields;
764   fields = field;
765   
766   /* Workspace */
767   field = build_decl (FIELD_DECL, NULL_TREE, long_integer_type_node);
768   TREE_CHAIN (field) = fields;
769   fields = field;
770
771   /* number of functions */
772   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
773   TREE_CHAIN (field) = fields;
774   fields = field;
775       
776   /* function_info table */
777   function_info_fields = build_function_info_fields ();
778   function_info_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
779   finish_builtin_struct (function_info_type, "__function_info",
780                          function_info_fields, NULL_TREE);
781   function_info_ptr_type =
782           build_pointer_type
783                 (build_qualified_type (function_info_type,
784                                        TYPE_QUAL_CONST));
785   field = build_decl (FIELD_DECL, NULL_TREE, function_info_ptr_type);
786   TREE_CHAIN (field) = fields;
787   fields = field;
788     
789   /* n_counter_sections  */
790   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
791   TREE_CHAIN (field) = fields;
792   fields = field;
793   
794   /* counter sections */
795   counter_section_data_fields = build_counter_section_data_fields ();
796   counter_section_data_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
797   finish_builtin_struct (counter_section_data_type, "__counter_section_data",
798                          counter_section_data_fields, NULL_TREE);
799   counter_section_data_ptr_type =
800           build_pointer_type
801                 (build_qualified_type (counter_section_data_type,
802                                        TYPE_QUAL_CONST));
803   field = build_decl (FIELD_DECL, NULL_TREE, counter_section_data_ptr_type);
804   TREE_CHAIN (field) = fields;
805   fields = field;
806
807   return fields;
808 }
809
810 /* Creates struct gcov_info value (in gcov-io.h).  */
811 static tree
812 build_gcov_info_value ()
813 {
814   tree value = NULL_TREE;
815   tree filename_string;
816   char *filename;
817   int filename_len;
818   unsigned n_functions, i;
819   struct function_list *item;
820   tree string_type =
821           build_pointer_type (build_qualified_type (char_type_node,
822                                                     TYPE_QUAL_CONST));
823   tree function_info_fields, function_info_type, function_info_ptr_type;
824   tree functions;
825   tree counter_section_data_fields, counter_section_data_type;
826   tree counter_section_data_ptr_type, counter_sections;
827
828   /* Version ident */
829   value = tree_cons (NULL_TREE,
830                      convert (long_unsigned_type_node,
831                               build_int_2 (GCOV_VERSION, 0)),
832                      value);
833
834   /* next -- NULL */
835   value = tree_cons (NULL_TREE, null_pointer_node, value);
836   
837   /* Filename */
838   filename = getpwd ();
839   filename = (filename && da_file_name[0] != '/'
840               ? concat (filename, "/", da_file_name, NULL)
841               : da_file_name);
842   filename_len = strlen (filename);
843   filename_string = build_string (filename_len + 1, filename);
844   if (filename != da_file_name)
845     free (filename);
846   TREE_TYPE (filename_string) =
847           build_array_type (char_type_node,
848                             build_index_type (build_int_2 (filename_len, 0)));
849   value = tree_cons (NULL_TREE,
850                      build1 (ADDR_EXPR,
851                              string_type,
852                              filename_string),
853                      value);
854   
855   /* Workspace */
856   value = tree_cons (NULL_TREE,
857                      convert (long_integer_type_node, integer_zero_node),
858                      value);
859       
860   /* number of functions */
861   n_functions = 0;
862   for (item = functions_head; item != 0; item = item->next, n_functions++)
863     continue;
864   value = tree_cons (NULL_TREE,
865                      convert (unsigned_type_node,
866                               build_int_2 (n_functions, 0)),
867                      value);
868
869   /* function_info table */
870   function_info_fields = build_function_info_fields ();
871   function_info_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
872   function_info_ptr_type =
873           build_pointer_type (
874                 build_qualified_type (function_info_type,
875                                       TYPE_QUAL_CONST));
876   functions = NULL_TREE;
877   for (item = functions_head; item != 0; item = item->next)
878     {
879       tree function_info_value = build_function_info_value (item);
880       set_purpose (function_info_value, function_info_fields);
881       functions
882         = tree_cons (NULL_TREE,
883                      build_constructor (function_info_type,
884                                         nreverse (function_info_value)),
885                      functions);
886     }
887   finish_builtin_struct (function_info_type, "__function_info",
888                          function_info_fields, NULL_TREE);
889
890   /* Create constructor for array.  */
891   if (n_functions)
892     {
893       tree array_type;
894
895       array_type = build_array_type (
896                         function_info_type,
897                         build_index_type (build_int_2 (n_functions - 1, 0)));
898       functions = build_constructor (array_type, nreverse (functions));
899       functions = build1 (ADDR_EXPR,
900                           function_info_ptr_type,
901                           functions);
902     }
903   else
904     functions = null_pointer_node;
905
906   value = tree_cons (NULL_TREE, functions, value);
907
908   /* n_counter_sections  */
909   value = tree_cons (NULL_TREE,
910                      convert (unsigned_type_node,
911                               build_int_2 (profile_info.n_sections, 0)),
912                      value);
913   
914   /* counter sections */
915   counter_section_data_fields = build_counter_section_data_fields ();
916   counter_section_data_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
917   counter_sections = NULL_TREE;
918   for (i = 0; i < profile_info.n_sections; i++)
919     {
920       tree counter_sections_value =
921               build_counter_section_data_value (
922                 profile_info.section_info[i].tag,
923                 profile_info.section_info[i].n_counters);
924       set_purpose (counter_sections_value, counter_section_data_fields);
925       counter_sections =
926         tree_cons (NULL_TREE,
927                    build_constructor (counter_section_data_type,
928                                       nreverse (counter_sections_value)),
929                    counter_sections);
930     }
931   finish_builtin_struct (counter_section_data_type, "__counter_section_data",
932                          counter_section_data_fields, NULL_TREE);
933   counter_section_data_ptr_type =
934           build_pointer_type
935                 (build_qualified_type (counter_section_data_type,
936                                        TYPE_QUAL_CONST));
937
938   if (profile_info.n_sections)
939     {
940       tree cst_type = build_index_type (build_int_2 (profile_info.n_sections-1,
941                                                      0));
942       cst_type = build_array_type (counter_section_data_type, cst_type);
943       counter_sections = build_constructor (cst_type,
944                                             nreverse (counter_sections));
945       counter_sections = build1 (ADDR_EXPR,
946                                  counter_section_data_ptr_type,
947                                  counter_sections);
948     }
949   else
950     counter_sections = null_pointer_node;
951   value = tree_cons (NULL_TREE, counter_sections, value);
952
953   return value;
954 }
955
956 /* Write out the structure which libgcc uses to locate all the arc
957    counters.  The structures used here must match those defined in
958    gcov-io.h.  Write out the constructor to call __gcov_init.  */
959
960 static void
961 create_coverage ()
962 {
963   tree gcov_info_fields, gcov_info_type, gcov_info_value, gcov_info;
964   char name[20];
965   char *ctor_name;
966   tree ctor;
967   rtx gcov_info_address;
968   int save_flag_inline_functions = flag_inline_functions;
969   unsigned i;
970
971   for (i = 0; i < profile_info.n_sections; i++)
972     if (profile_info.section_info[i].n_counters)
973       break;
974   if (i == profile_info.n_sections)
975     return;
976   
977   gcov_info_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
978   gcov_info_fields = build_gcov_info_fields (gcov_info_type);
979   gcov_info_value = build_gcov_info_value ();
980   set_purpose (gcov_info_value, gcov_info_fields);
981   finish_builtin_struct (gcov_info_type, "__gcov_info",
982                          gcov_info_fields, NULL_TREE);
983
984   gcov_info = build (VAR_DECL, gcov_info_type, NULL_TREE, NULL_TREE);
985   DECL_INITIAL (gcov_info) =
986     build_constructor (gcov_info_type, nreverse (gcov_info_value));
987
988   TREE_STATIC (gcov_info) = 1;
989   ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
990   DECL_NAME (gcov_info) = get_identifier (name);
991   
992   /* Build structure.  */
993   assemble_variable (gcov_info, 0, 0, 0);
994
995   /* Build the constructor function to invoke __gcov_init.  */
996   ctor_name = concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
997                       "_GCOV", NULL);
998   ctor = build_decl (FUNCTION_DECL, get_identifier (ctor_name),
999                      build_function_type (void_type_node, NULL_TREE));
1000   free (ctor_name);
1001   DECL_EXTERNAL (ctor) = 0;
1002
1003   /* It can be a static function as long as collect2 does not have
1004      to scan the object file to find its ctor/dtor routine.  */
1005   TREE_PUBLIC (ctor) = ! targetm.have_ctors_dtors;
1006   TREE_USED (ctor) = 1;
1007   DECL_RESULT (ctor) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1008
1009   ctor = (*lang_hooks.decls.pushdecl) (ctor);
1010   rest_of_decl_compilation (ctor, 0, 1, 0);
1011   announce_function (ctor);
1012   current_function_decl = ctor;
1013   DECL_INITIAL (ctor) = error_mark_node;
1014   make_decl_rtl (ctor, NULL);
1015   init_function_start (ctor, input_filename, lineno);
1016   (*lang_hooks.decls.pushlevel) (0);
1017   expand_function_start (ctor, 0);
1018   cfun->arc_profile = 0;
1019
1020   /* Actually generate the code to call __gcov_init.  */
1021   gcov_info_address = force_reg (Pmode, XEXP (DECL_RTL (gcov_info), 0));
1022   emit_library_call (gcov_init_libfunc, LCT_NORMAL, VOIDmode, 1,
1023                      gcov_info_address, Pmode);
1024
1025   expand_function_end (input_filename, lineno, 0);
1026   (*lang_hooks.decls.poplevel) (1, 0, 1);
1027
1028   /* Since ctor isn't in the list of globals, it would never be emitted
1029      when it's considered to be 'safe' for inlining, so turn off
1030      flag_inline_functions.  */
1031   flag_inline_functions = 0;
1032
1033   rest_of_compilation (ctor);
1034
1035   /* Reset flag_inline_functions to its original value.  */
1036   flag_inline_functions = save_flag_inline_functions;
1037
1038   if (! quiet_flag)
1039     fflush (asm_out_file);
1040   current_function_decl = NULL_TREE;
1041
1042   if (targetm.have_ctors_dtors)
1043     (* targetm.asm_out.constructor) (XEXP (DECL_RTL (ctor), 0),
1044                                      DEFAULT_INIT_PRIORITY);
1045 }
1046 \f
1047 /* Find (and create if not present) a section with TAG for the current
1048    function.  */
1049 struct section_info *
1050 find_counters_section (tag)
1051      unsigned tag;
1052 {
1053   unsigned i;
1054
1055   for (i = 0; i < profile_info.n_sections; i++)
1056     if (profile_info.section_info[i].tag == tag)
1057       return profile_info.section_info + i;
1058
1059   if (i == MAX_COUNTER_SECTIONS)
1060     abort ();
1061
1062   profile_info.section_info[i].tag = tag;
1063   profile_info.section_info[i].present = 0;
1064   profile_info.section_info[i].n_counters = 0;
1065   profile_info.section_info[i].n_counters_now = 0;
1066   profile_info.n_sections++;
1067
1068   return profile_info.section_info + i;
1069 }
1070
1071 /* Generate a MEM rtl to access counter NO in counter section TAG.  */
1072
1073 rtx
1074 coverage_counter_ref (unsigned tag, unsigned no)
1075 {
1076   enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
1077   struct section_info *sect = find_counters_section (tag);
1078   rtx ref;
1079
1080   if (!profiler_label)
1081     {
1082       /* Generate and save a copy of this so it can be shared.  */
1083       char buf[20];
1084       
1085       ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 2);
1086       profiler_label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1087     }
1088   if (no + 1 > (unsigned) sect->n_counters_now)
1089     sect->n_counters_now = no + 1;
1090
1091   no += sect->n_counters;
1092   ref = plus_constant (profiler_label, GCOV_TYPE_SIZE / BITS_PER_UNIT * no);
1093   ref = gen_rtx_MEM (mode, ref);
1094   set_mem_alias_set (ref, new_alias_set ());
1095
1096   return ref;
1097 }
1098
1099 \f
1100 /* Perform file-level initialization. Read in data file, generate name
1101    of graph file. */
1102
1103 void
1104 coverage_init (filename)
1105   const char *filename;
1106 {
1107   int len = strlen (filename);
1108
1109   da_file_name = (char *) xmalloc (len + strlen (GCOV_DATA_SUFFIX) + 1);
1110   strcpy (da_file_name, filename);
1111   strcat (da_file_name, GCOV_DATA_SUFFIX);
1112   
1113   read_counts_file ();
1114
1115   /* Open the bbg output file.  */
1116   bbg_file_name = (char *) xmalloc (len + strlen (GCOV_GRAPH_SUFFIX) + 1);
1117   strcpy (bbg_file_name, filename);
1118   strcat (bbg_file_name, GCOV_GRAPH_SUFFIX);
1119 }
1120
1121 /* Performs file-level cleanup.  Close graph file, generate coverage
1122    variables and constructor.  */
1123
1124 void
1125 coverage_finish ()
1126 {
1127   create_coverage ();
1128   if (bbg_file_opened)
1129     {
1130       int error = gcov_close ();
1131       
1132       if (error)
1133         unlink (bbg_file_name);
1134 #if SELF_COVERAGE
1135       /* If the compiler is instrumented, we should not
1136          unconditionally remove the counts file, because we might be
1137          recompiling ourselves. The .da files are all removed during
1138          copying the stage1 files.  */
1139       if (error)
1140 #endif
1141         unlink (da_file_name);
1142     }
1143 }
1144
1145
1146 #include "gt-coverage.h"