OSDN Git Service

* call.c (print_z_candidates): Do print viable deleted candidates.
[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, 2004, 2005, 2007, 2008, 2009, 2010
4    Free Software Foundation, Inc.
5    Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
6    based on some ideas from Dain Samples of UC Berkeley.
7    Further mangling by Bob Manson, Cygnus Support.
8    Further mangled by Nathan Sidwell, CodeSourcery
9
10 This file is part of GCC.
11
12 GCC is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free
14 Software Foundation; either version 3, or (at your option) any later
15 version.
16
17 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18 WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with GCC; see the file COPYING3.  If not see
24 <http://www.gnu.org/licenses/>.  */
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 "basic-block.h"
41 #include "toplev.h"
42 #include "tm_p.h"
43 #include "ggc.h"
44 #include "coverage.h"
45 #include "langhooks.h"
46 #include "hashtab.h"
47 #include "tree-iterator.h"
48 #include "cgraph.h"
49 #include "tree-pass.h"
50 #include "diagnostic-core.h"
51 #include "intl.h"
52
53 #include "gcov-io.c"
54
55 struct function_list
56 {
57   struct function_list *next;    /* next function */
58   unsigned ident;                /* function ident */
59   unsigned checksum;             /* function checksum */
60   unsigned n_ctrs[GCOV_COUNTERS];/* number of counters.  */
61 };
62
63 /* Counts information for a function.  */
64 typedef struct counts_entry
65 {
66   /* We hash by  */
67   unsigned ident;
68   unsigned ctr;
69
70   /* Store  */
71   unsigned checksum;
72   gcov_type *counts;
73   struct gcov_ctr_summary summary;
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 static unsigned no_coverage = 0;
83
84 /* Cumulative counter information for whole program.  */
85 static unsigned prg_ctr_mask; /* Mask of counter types generated.  */
86 static unsigned prg_n_ctrs[GCOV_COUNTERS]; /* Total counters allocated.  */
87
88 /* Counter information for current function.  */
89 static unsigned fn_ctr_mask; /* Mask of counters used.  */
90 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated.  */
91 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base.  */
92
93 /* Name of the output file for coverage output file.  */
94 static char *bbg_file_name;
95 static unsigned bbg_file_opened;
96 static int bbg_function_announced;
97
98 /* Name of the count data file.  */
99 static char *da_file_name;
100
101 /* Hash table of count data.  */
102 static htab_t counts_hash = NULL;
103
104 /* Trees representing the counter table arrays.  */
105 static GTY(()) tree tree_ctr_tables[GCOV_COUNTERS];
106
107 /* The names of the counter tables.  Not used if we're
108    generating counters at tree level.  */
109 static GTY(()) rtx ctr_labels[GCOV_COUNTERS];
110
111 /* The names of merge functions for counters.  */
112 static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
113 static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
114
115 /* Forward declarations.  */
116 static hashval_t htab_counts_entry_hash (const void *);
117 static int htab_counts_entry_eq (const void *, const void *);
118 static void htab_counts_entry_del (void *);
119 static void read_counts_file (void);
120 static unsigned compute_checksum (void);
121 static unsigned coverage_checksum_string (unsigned, const char *);
122 static tree build_fn_info_type (unsigned);
123 static tree build_fn_info_value (const struct function_list *, tree);
124 static tree build_ctr_info_type (void);
125 static tree build_ctr_info_value (unsigned, tree);
126 static tree build_gcov_info (void);
127 static void create_coverage (void);
128 \f
129 /* Return the type node for gcov_type.  */
130
131 tree
132 get_gcov_type (void)
133 {
134   return lang_hooks.types.type_for_size (GCOV_TYPE_SIZE, false);
135 }
136
137 /* Return the type node for gcov_unsigned_t.  */
138
139 static tree
140 get_gcov_unsigned_t (void)
141 {
142   return lang_hooks.types.type_for_size (32, true);
143 }
144 \f
145 static hashval_t
146 htab_counts_entry_hash (const void *of)
147 {
148   const counts_entry_t *const entry = (const counts_entry_t *) of;
149
150   return entry->ident * GCOV_COUNTERS + entry->ctr;
151 }
152
153 static int
154 htab_counts_entry_eq (const void *of1, const void *of2)
155 {
156   const counts_entry_t *const entry1 = (const counts_entry_t *) of1;
157   const counts_entry_t *const entry2 = (const counts_entry_t *) of2;
158
159   return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
160 }
161
162 static void
163 htab_counts_entry_del (void *of)
164 {
165   counts_entry_t *const entry = (counts_entry_t *) of;
166
167   free (entry->counts);
168   free (entry);
169 }
170
171 /* Read in the counts file, if available.  */
172
173 static void
174 read_counts_file (void)
175 {
176   gcov_unsigned_t fn_ident = 0;
177   gcov_unsigned_t checksum = -1;
178   counts_entry_t *summaried = NULL;
179   unsigned seen_summary = 0;
180   gcov_unsigned_t tag;
181   int is_error = 0;
182
183   if (!gcov_open (da_file_name, 1))
184     return;
185
186   if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
187     {
188       warning (0, "%qs is not a gcov data file", da_file_name);
189       gcov_close ();
190       return;
191     }
192   else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
193     {
194       char v[4], e[4];
195
196       GCOV_UNSIGNED2STRING (v, tag);
197       GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
198
199       warning (0, "%qs is version %q.*s, expected version %q.*s",
200                da_file_name, 4, v, 4, e);
201       gcov_close ();
202       return;
203     }
204
205   /* Read and discard the stamp.  */
206   gcov_read_unsigned ();
207
208   counts_hash = htab_create (10,
209                              htab_counts_entry_hash, htab_counts_entry_eq,
210                              htab_counts_entry_del);
211   while ((tag = gcov_read_unsigned ()))
212     {
213       gcov_unsigned_t length;
214       gcov_position_t offset;
215
216       length = gcov_read_unsigned ();
217       offset = gcov_position ();
218       if (tag == GCOV_TAG_FUNCTION)
219         {
220           fn_ident = gcov_read_unsigned ();
221           checksum = gcov_read_unsigned ();
222           if (seen_summary)
223             {
224               /* We have already seen a summary, this means that this
225                  new function begins a new set of program runs. We
226                  must unlink the summaried chain.  */
227               counts_entry_t *entry, *chain;
228
229               for (entry = summaried; entry; entry = chain)
230                 {
231                   chain = entry->chain;
232                   entry->chain = NULL;
233                 }
234               summaried = NULL;
235               seen_summary = 0;
236             }
237         }
238       else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
239         {
240           counts_entry_t *entry;
241           struct gcov_summary summary;
242
243           gcov_read_summary (&summary);
244           seen_summary = 1;
245           for (entry = summaried; entry; entry = entry->chain)
246             {
247               struct gcov_ctr_summary *csum = &summary.ctrs[entry->ctr];
248
249               entry->summary.runs += csum->runs;
250               entry->summary.sum_all += csum->sum_all;
251               if (entry->summary.run_max < csum->run_max)
252                 entry->summary.run_max = csum->run_max;
253               entry->summary.sum_max += csum->sum_max;
254             }
255         }
256       else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
257         {
258           counts_entry_t **slot, *entry, elt;
259           unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
260           unsigned ix;
261
262           elt.ident = fn_ident;
263           elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
264
265           slot = (counts_entry_t **) htab_find_slot
266             (counts_hash, &elt, INSERT);
267           entry = *slot;
268           if (!entry)
269             {
270               *slot = entry = XCNEW (counts_entry_t);
271               entry->ident = elt.ident;
272               entry->ctr = elt.ctr;
273               entry->checksum = checksum;
274               entry->summary.num = n_counts;
275               entry->counts = XCNEWVEC (gcov_type, n_counts);
276             }
277           else if (entry->checksum != checksum)
278             {
279               error ("coverage mismatch for function %u while reading execution counters",
280                      fn_ident);
281               error ("checksum is %x instead of %x", entry->checksum, checksum);
282               htab_delete (counts_hash);
283               break;
284             }
285           else if (entry->summary.num != n_counts)
286             {
287               error ("coverage mismatch for function %u while reading execution counters",
288                      fn_ident);
289               error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
290               htab_delete (counts_hash);
291               break;
292             }
293           else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
294             {
295               error ("cannot merge separate %s counters for function %u",
296                      ctr_names[elt.ctr], fn_ident);
297               goto skip_merge;
298             }
299
300           if (elt.ctr < GCOV_COUNTERS_SUMMABLE
301               /* This should always be true for a just allocated entry,
302                  and always false for an existing one. Check this way, in
303                  case the gcov file is corrupt.  */
304               && (!entry->chain || summaried != entry))
305             {
306               entry->chain = summaried;
307               summaried = entry;
308             }
309           for (ix = 0; ix != n_counts; ix++)
310             entry->counts[ix] += gcov_read_counter ();
311         skip_merge:;
312         }
313       gcov_sync (offset, length);
314       if ((is_error = gcov_is_error ()))
315         {
316           error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted",
317                  da_file_name);
318           htab_delete (counts_hash);
319           break;
320         }
321     }
322
323   gcov_close ();
324 }
325
326 /* Returns the counters for a particular tag.  */
327
328 gcov_type *
329 get_coverage_counts (unsigned counter, unsigned expected,
330                      const struct gcov_ctr_summary **summary)
331 {
332   counts_entry_t *entry, elt;
333   gcov_unsigned_t checksum = -1;
334
335   /* No hash table, no counts.  */
336   if (!counts_hash)
337     {
338       static int warned = 0;
339
340       if (!warned++)
341         inform (input_location, (flag_guess_branch_prob
342                  ? "file %s not found, execution counts estimated"
343                  : "file %s not found, execution counts assumed to be zero"),
344                 da_file_name);
345       return NULL;
346     }
347
348   elt.ident = current_function_funcdef_no + 1;
349   elt.ctr = counter;
350   entry = (counts_entry_t *) htab_find (counts_hash, &elt);
351   if (!entry)
352     {
353       warning (0, "no coverage for function %qE found",
354                DECL_ASSEMBLER_NAME (current_function_decl));
355       return NULL;
356     }
357
358   checksum = compute_checksum ();
359   if (entry->checksum != checksum
360       || entry->summary.num != expected)
361     {
362       static int warned = 0;
363       bool warning_printed = false;
364       tree id = DECL_ASSEMBLER_NAME (current_function_decl);
365
366       warning_printed = 
367         warning_at (input_location, OPT_Wcoverage_mismatch, 
368                     "coverage mismatch for function "
369                     "%qE while reading counter %qs", id, ctr_names[counter]);
370       if (warning_printed)
371         {
372           if (entry->checksum != checksum)
373             inform (input_location, "checksum is %x instead of %x",
374                     entry->checksum, checksum);
375           else
376             inform (input_location, "number of counters is %d instead of %d",
377                     entry->summary.num, expected);
378           
379           if (!seen_error ()
380               && !warned++)
381             {
382               inform (input_location, "coverage mismatch ignored");
383               inform (input_location, flag_guess_branch_prob
384                       ? G_("execution counts estimated")
385                       : G_("execution counts assumed to be zero"));
386               if (!flag_guess_branch_prob)
387                 inform (input_location,
388                         "this can result in poorly optimized code");
389             }
390         }
391
392       return NULL;
393     }
394
395   if (summary)
396     *summary = &entry->summary;
397
398   return entry->counts;
399 }
400
401 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
402    allocation succeeded.  */
403
404 int
405 coverage_counter_alloc (unsigned counter, unsigned num)
406 {
407   if (no_coverage)
408     return 0;
409
410   if (!num)
411     return 1;
412
413   if (!tree_ctr_tables[counter])
414     {
415       /* Generate and save a copy of this so it can be shared.  Leave
416          the index type unspecified for now; it will be set after all
417          functions have been compiled.  */
418       char buf[20];
419       tree gcov_type_node = get_gcov_type ();
420       tree gcov_type_array_type
421         = build_array_type (gcov_type_node, NULL_TREE);
422       tree_ctr_tables[counter]
423         = build_decl (BUILTINS_LOCATION,
424                       VAR_DECL, NULL_TREE, gcov_type_array_type);
425       TREE_STATIC (tree_ctr_tables[counter]) = 1;
426       ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", counter + 1);
427       DECL_NAME (tree_ctr_tables[counter]) = get_identifier (buf);
428       DECL_ALIGN (tree_ctr_tables[counter]) = TYPE_ALIGN (gcov_type_node);
429
430       if (dump_file)
431         fprintf (dump_file, "Using data file %s\n", da_file_name);
432     }
433   fn_b_ctrs[counter] = fn_n_ctrs[counter];
434   fn_n_ctrs[counter] += num;
435   fn_ctr_mask |= 1 << counter;
436   return 1;
437 }
438
439 /* Generate a tree to access COUNTER NO.  */
440
441 tree
442 tree_coverage_counter_ref (unsigned counter, unsigned no)
443 {
444   tree gcov_type_node = get_gcov_type ();
445
446   gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
447   no += prg_n_ctrs[counter] + fn_b_ctrs[counter];
448
449   /* "no" here is an array index, scaled to bytes later.  */
450   return build4 (ARRAY_REF, gcov_type_node, tree_ctr_tables[counter],
451                  build_int_cst (NULL_TREE, no), NULL, NULL);
452 }
453
454 /* Generate a tree to access the address of COUNTER NO.  */
455
456 tree
457 tree_coverage_counter_addr (unsigned counter, unsigned no)
458 {
459   tree gcov_type_node = get_gcov_type ();
460
461   gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
462   no += prg_n_ctrs[counter] + fn_b_ctrs[counter];
463
464   TREE_ADDRESSABLE (tree_ctr_tables[counter]) = 1;
465
466   /* "no" here is an array index, scaled to bytes later.  */
467   return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node,
468                                        tree_ctr_tables[counter],
469                                        build_int_cst (NULL_TREE, no),
470                                        NULL, NULL));
471 }
472 \f
473 /* Generate a checksum for a string.  CHKSUM is the current
474    checksum.  */
475
476 static unsigned
477 coverage_checksum_string (unsigned chksum, const char *string)
478 {
479   int i;
480   char *dup = NULL;
481
482   /* Look for everything that looks if it were produced by
483      get_file_function_name and zero out the second part
484      that may result from flag_random_seed.  This is not critical
485      as the checksums are used only for sanity checking.  */
486   for (i = 0; string[i]; i++)
487     {
488       int offset = 0;
489       if (!strncmp (string + i, "_GLOBAL__N_", 11))
490       offset = 11;
491       if (!strncmp (string + i, "_GLOBAL__", 9))
492       offset = 9;
493
494       /* C++ namespaces do have scheme:
495          _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
496        since filename might contain extra underscores there seems
497        to be no better chance then walk all possible offsets looking
498        for magicnumber.  */
499       if (offset)
500         {
501           for (i = i + offset; string[i]; i++)
502             if (string[i]=='_')
503               {
504                 int y;
505
506                 for (y = 1; y < 9; y++)
507                   if (!(string[i + y] >= '0' && string[i + y] <= '9')
508                       && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
509                     break;
510                 if (y != 9 || string[i + 9] != '_')
511                   continue;
512                 for (y = 10; y < 18; y++)
513                   if (!(string[i + y] >= '0' && string[i + y] <= '9')
514                       && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
515                     break;
516                 if (y != 18)
517                   continue;
518                 if (!dup)
519                   string = dup = xstrdup (string);
520                 for (y = 10; y < 18; y++)
521                   dup[i + y] = '0';
522               }
523           break;
524         }
525     }
526
527   chksum = crc32_string (chksum, string);
528   if (dup)
529     free (dup);
530
531   return chksum;
532 }
533
534 /* Compute checksum for the current function.  We generate a CRC32.  */
535
536 static unsigned
537 compute_checksum (void)
538 {
539   expanded_location xloc
540     = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
541   unsigned chksum = xloc.line;
542
543   chksum = coverage_checksum_string (chksum, xloc.file);
544   chksum = coverage_checksum_string
545     (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
546
547   return chksum;
548 }
549 \f
550 /* Begin output to the graph file for the current function.
551    Opens the output file, if not already done. Writes the
552    function header, if not already done. Returns nonzero if data
553    should be output.  */
554
555 int
556 coverage_begin_output (void)
557 {
558   /* We don't need to output .gcno file unless we're under -ftest-coverage
559      (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
560   if (no_coverage || !flag_test_coverage || flag_compare_debug)
561     return 0;
562
563   if (!bbg_function_announced)
564     {
565       expanded_location xloc
566         = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
567       unsigned long offset;
568
569       if (!bbg_file_opened)
570         {
571           if (!gcov_open (bbg_file_name, -1))
572             error ("cannot open %s", bbg_file_name);
573           else
574             {
575               gcov_write_unsigned (GCOV_NOTE_MAGIC);
576               gcov_write_unsigned (GCOV_VERSION);
577               gcov_write_unsigned (local_tick);
578             }
579           bbg_file_opened = 1;
580         }
581
582       /* Announce function */
583       offset = gcov_write_tag (GCOV_TAG_FUNCTION);
584       gcov_write_unsigned (current_function_funcdef_no + 1);
585       gcov_write_unsigned (compute_checksum ());
586       gcov_write_string (IDENTIFIER_POINTER
587                          (DECL_ASSEMBLER_NAME (current_function_decl)));
588       gcov_write_string (xloc.file);
589       gcov_write_unsigned (xloc.line);
590       gcov_write_length (offset);
591
592       bbg_function_announced = 1;
593     }
594   return !gcov_is_error ();
595 }
596
597 /* Finish coverage data for the current function. Verify no output
598    error has occurred.  Save function coverage counts.  */
599
600 void
601 coverage_end_function (void)
602 {
603   unsigned i;
604
605   if (bbg_file_opened > 1 && gcov_is_error ())
606     {
607       warning (0, "error writing %qs", bbg_file_name);
608       bbg_file_opened = -1;
609     }
610
611   if (fn_ctr_mask)
612     {
613       struct function_list *item;
614
615       item = XNEW (struct function_list);
616
617       *functions_tail = item;
618       functions_tail = &item->next;
619
620       item->next = 0;
621       item->ident = current_function_funcdef_no + 1;
622       item->checksum = compute_checksum ();
623       for (i = 0; i != GCOV_COUNTERS; i++)
624         {
625           item->n_ctrs[i] = fn_n_ctrs[i];
626           prg_n_ctrs[i] += fn_n_ctrs[i];
627           fn_n_ctrs[i] = fn_b_ctrs[i] = 0;
628         }
629       prg_ctr_mask |= fn_ctr_mask;
630       fn_ctr_mask = 0;
631     }
632   bbg_function_announced = 0;
633 }
634
635 /* Creates the gcov_fn_info RECORD_TYPE.  */
636
637 static tree
638 build_fn_info_type (unsigned int counters)
639 {
640   tree type = lang_hooks.types.make_type (RECORD_TYPE);
641   tree field, fields;
642   tree array_type;
643
644   /* ident */
645   fields = build_decl (BUILTINS_LOCATION,
646                        FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
647
648   /* checksum */
649   field = build_decl (BUILTINS_LOCATION,
650                       FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
651   TREE_CHAIN (field) = fields;
652   fields = field;
653
654   array_type = build_int_cst (NULL_TREE, counters - 1);
655   array_type = build_index_type (array_type);
656   array_type = build_array_type (get_gcov_unsigned_t (), array_type);
657
658   /* counters */
659   field = build_decl (BUILTINS_LOCATION,
660                       FIELD_DECL, NULL_TREE, array_type);
661   TREE_CHAIN (field) = fields;
662   fields = field;
663
664   finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
665
666   return type;
667 }
668
669 /* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is
670    the function being processed and TYPE is the gcov_fn_info
671    RECORD_TYPE.  */
672
673 static tree
674 build_fn_info_value (const struct function_list *function, tree type)
675 {
676   tree fields = TYPE_FIELDS (type);
677   unsigned ix;
678   VEC(constructor_elt,gc) *v1 = NULL;
679   VEC(constructor_elt,gc) *v2 = NULL;
680
681   /* ident */
682   CONSTRUCTOR_APPEND_ELT (v1, fields,
683                           build_int_cstu (get_gcov_unsigned_t (),
684                                           function->ident));
685   fields = TREE_CHAIN (fields);
686
687   /* checksum */
688   CONSTRUCTOR_APPEND_ELT (v1, fields,
689                           build_int_cstu (get_gcov_unsigned_t (),
690                                           function->checksum));
691   fields = TREE_CHAIN (fields);
692
693   /* counters */
694   for (ix = 0; ix != GCOV_COUNTERS; ix++)
695     if (prg_ctr_mask & (1 << ix))
696       CONSTRUCTOR_APPEND_ELT (v2, NULL,
697                               build_int_cstu (get_gcov_unsigned_t (),
698                                               function->n_ctrs[ix]));
699
700   CONSTRUCTOR_APPEND_ELT (v1, fields,
701                           build_constructor (TREE_TYPE (fields), v2));
702
703   return build_constructor (type, v1);
704 }
705
706 /* Creates the gcov_ctr_info RECORD_TYPE.  */
707
708 static tree
709 build_ctr_info_type (void)
710 {
711   tree type = lang_hooks.types.make_type (RECORD_TYPE);
712   tree field, fields = NULL_TREE;
713   tree gcov_ptr_type = build_pointer_type (get_gcov_type ());
714   tree gcov_merge_fn_type;
715
716   /* counters */
717   field = build_decl (BUILTINS_LOCATION,
718                       FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
719   TREE_CHAIN (field) = fields;
720   fields = field;
721
722   /* values */
723   field = build_decl (BUILTINS_LOCATION,
724                       FIELD_DECL, NULL_TREE, gcov_ptr_type);
725   TREE_CHAIN (field) = fields;
726   fields = field;
727
728   /* merge */
729   gcov_merge_fn_type =
730     build_function_type_list (void_type_node,
731                               gcov_ptr_type, get_gcov_unsigned_t (),
732                               NULL_TREE);
733   field = build_decl (BUILTINS_LOCATION,
734                       FIELD_DECL, NULL_TREE,
735                       build_pointer_type (gcov_merge_fn_type));
736   TREE_CHAIN (field) = fields;
737   fields = field;
738
739   finish_builtin_struct (type, "__gcov_ctr_info", fields, NULL_TREE);
740
741   return type;
742 }
743
744 /* Creates a CONSTRUCTOR for a gcov_ctr_info. COUNTER is
745    the counter being processed and TYPE is the gcov_ctr_info
746    RECORD_TYPE.  */
747
748 static tree
749 build_ctr_info_value (unsigned int counter, tree type)
750 {
751   tree fields = TYPE_FIELDS (type);
752   tree fn;
753   VEC(constructor_elt,gc) *v = NULL;
754
755   /* counters */
756   CONSTRUCTOR_APPEND_ELT (v, fields,
757                           build_int_cstu (get_gcov_unsigned_t (),
758                                           prg_n_ctrs[counter]));
759   fields = TREE_CHAIN (fields);
760
761   if (prg_n_ctrs[counter])
762     {
763       tree array_type;
764
765       array_type = build_int_cstu (get_gcov_unsigned_t (),
766                                    prg_n_ctrs[counter] - 1);
767       array_type = build_index_type (array_type);
768       array_type = build_array_type (TREE_TYPE (TREE_TYPE (fields)),
769                                      array_type);
770
771       TREE_TYPE (tree_ctr_tables[counter]) = array_type;
772       DECL_SIZE (tree_ctr_tables[counter]) = TYPE_SIZE (array_type);
773       DECL_SIZE_UNIT (tree_ctr_tables[counter]) = TYPE_SIZE_UNIT (array_type);
774       varpool_finalize_decl (tree_ctr_tables[counter]);
775
776       CONSTRUCTOR_APPEND_ELT (v, fields,
777                               build1 (ADDR_EXPR, TREE_TYPE (fields),
778                                       tree_ctr_tables[counter]));
779     }
780   else
781     CONSTRUCTOR_APPEND_ELT (v, fields, null_pointer_node);
782   fields = TREE_CHAIN (fields);
783
784   fn = build_decl (BUILTINS_LOCATION,
785                    FUNCTION_DECL,
786                    get_identifier (ctr_merge_functions[counter]),
787                    TREE_TYPE (TREE_TYPE (fields)));
788   DECL_EXTERNAL (fn) = 1;
789   TREE_PUBLIC (fn) = 1;
790   DECL_ARTIFICIAL (fn) = 1;
791   TREE_NOTHROW (fn) = 1;
792   DECL_ASSEMBLER_NAME (fn);  /* Initialize assembler name so we can stream out. */
793   CONSTRUCTOR_APPEND_ELT (v, fields, build1 (ADDR_EXPR, TREE_TYPE (fields), fn));
794
795   return build_constructor (type, v);
796 }
797
798 /* Creates the gcov_info RECORD_TYPE and initializer for it. Returns a
799    CONSTRUCTOR.  */
800
801 static tree
802 build_gcov_info (void)
803 {
804   unsigned n_ctr_types, ix;
805   tree type, const_type;
806   tree fn_info_type, fn_info_value = NULL_TREE;
807   tree fn_info_ptr_type;
808   tree ctr_info_type, ctr_info_ary_type, ctr_info_value = NULL_TREE;
809   tree field, fields = NULL_TREE;
810   tree filename_string;
811   int da_file_name_len;
812   unsigned n_fns;
813   const struct function_list *fn;
814   tree string_type;
815   VEC(constructor_elt,gc) *v1 = NULL;
816   VEC(constructor_elt,gc) *v2 = NULL;
817
818   /* Count the number of active counters.  */
819   for (n_ctr_types = 0, ix = 0; ix != GCOV_COUNTERS; ix++)
820     if (prg_ctr_mask & (1 << ix))
821       n_ctr_types++;
822
823   type = lang_hooks.types.make_type (RECORD_TYPE);
824   const_type = build_qualified_type (type, TYPE_QUAL_CONST);
825
826   /* Version ident */
827   field = build_decl (BUILTINS_LOCATION,
828                       FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
829   TREE_CHAIN (field) = fields;
830   fields = field;
831   CONSTRUCTOR_APPEND_ELT (v1, field,
832                           build_int_cstu (TREE_TYPE (field), GCOV_VERSION));
833
834   /* next -- NULL */
835   field = build_decl (BUILTINS_LOCATION,
836                       FIELD_DECL, NULL_TREE, build_pointer_type (const_type));
837   TREE_CHAIN (field) = fields;
838   fields = field;
839   CONSTRUCTOR_APPEND_ELT (v1, field, null_pointer_node);
840
841   /* stamp */
842   field = build_decl (BUILTINS_LOCATION,
843                       FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
844   TREE_CHAIN (field) = fields;
845   fields = field;
846   CONSTRUCTOR_APPEND_ELT (v1, field,
847                           build_int_cstu (TREE_TYPE (field), local_tick));
848
849   /* Filename */
850   string_type = build_pointer_type (build_qualified_type (char_type_node,
851                                                     TYPE_QUAL_CONST));
852   field = build_decl (BUILTINS_LOCATION,
853                       FIELD_DECL, NULL_TREE, string_type);
854   TREE_CHAIN (field) = fields;
855   fields = field;
856   da_file_name_len = strlen (da_file_name);
857   filename_string = build_string (da_file_name_len + 1, da_file_name);
858   TREE_TYPE (filename_string) = build_array_type
859     (char_type_node, build_index_type
860      (build_int_cst (NULL_TREE, da_file_name_len)));
861   CONSTRUCTOR_APPEND_ELT (v1, field,
862                           build1 (ADDR_EXPR, string_type, filename_string));
863
864   /* Build the fn_info type and initializer.  */
865   fn_info_type = build_fn_info_type (n_ctr_types);
866   fn_info_ptr_type = build_pointer_type (build_qualified_type
867                                          (fn_info_type, TYPE_QUAL_CONST));
868   for (fn = functions_head, n_fns = 0; fn; fn = fn->next, n_fns++)
869     CONSTRUCTOR_APPEND_ELT (v2, NULL_TREE,
870                             build_fn_info_value (fn, fn_info_type));
871
872   if (n_fns)
873     {
874       tree array_type;
875
876       array_type = build_index_type (build_int_cst (NULL_TREE, n_fns - 1));
877       array_type = build_array_type (fn_info_type, array_type);
878
879       fn_info_value = build_constructor (array_type, v2);
880       fn_info_value = build1 (ADDR_EXPR, fn_info_ptr_type, fn_info_value);
881     }
882   else
883     fn_info_value = null_pointer_node;
884
885   /* number of functions */
886   field = build_decl (BUILTINS_LOCATION,
887                       FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
888   TREE_CHAIN (field) = fields;
889   fields = field;
890   CONSTRUCTOR_APPEND_ELT (v1, field,
891                           build_int_cstu (get_gcov_unsigned_t (), n_fns));
892
893   /* fn_info table */
894   field = build_decl (BUILTINS_LOCATION,
895                       FIELD_DECL, NULL_TREE, fn_info_ptr_type);
896   TREE_CHAIN (field) = fields;
897   fields = field;
898   CONSTRUCTOR_APPEND_ELT (v1, field, fn_info_value);
899
900   /* counter_mask */
901   field = build_decl (BUILTINS_LOCATION,
902                       FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
903   TREE_CHAIN (field) = fields;
904   fields = field;
905   CONSTRUCTOR_APPEND_ELT (v1, field, 
906                           build_int_cstu (get_gcov_unsigned_t (),
907                                           prg_ctr_mask));
908
909   /* counters */
910   ctr_info_type = build_ctr_info_type ();
911   ctr_info_ary_type = build_index_type (build_int_cst (NULL_TREE,
912                                                        n_ctr_types));
913   ctr_info_ary_type = build_array_type (ctr_info_type, ctr_info_ary_type);
914   v2 = NULL;
915   for (ix = 0; ix != GCOV_COUNTERS; ix++)
916     if (prg_ctr_mask & (1 << ix))
917       CONSTRUCTOR_APPEND_ELT (v2, NULL_TREE,
918                               build_ctr_info_value (ix, ctr_info_type));
919   ctr_info_value = build_constructor (ctr_info_ary_type, v2);
920
921   field = build_decl (BUILTINS_LOCATION,
922                       FIELD_DECL, NULL_TREE, ctr_info_ary_type);
923   TREE_CHAIN (field) = fields;
924   fields = field;
925   CONSTRUCTOR_APPEND_ELT (v1, field, ctr_info_value);
926
927   finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
928
929   return build_constructor (type, v1);
930 }
931
932 /* Write out the structure which libgcov uses to locate all the
933    counters.  The structures used here must match those defined in
934    gcov-io.h.  Write out the constructor to call __gcov_init.  */
935
936 static void
937 create_coverage (void)
938 {
939   tree gcov_info, gcov_init, body, t;
940   char name_buf[32];
941
942   no_coverage = 1; /* Disable any further coverage.  */
943
944   if (!prg_ctr_mask)
945     return;
946
947   t = build_gcov_info ();
948
949   gcov_info = build_decl (BUILTINS_LOCATION,
950                           VAR_DECL, NULL_TREE, TREE_TYPE (t));
951   TREE_STATIC (gcov_info) = 1;
952   ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
953   DECL_NAME (gcov_info) = get_identifier (name_buf);
954   DECL_INITIAL (gcov_info) = t;
955
956   /* Build structure.  */
957   varpool_finalize_decl (gcov_info);
958
959   /* Build a decl for __gcov_init.  */
960   t = build_pointer_type (TREE_TYPE (gcov_info));
961   t = build_function_type_list (void_type_node, t, NULL);
962   t = build_decl (BUILTINS_LOCATION,
963                   FUNCTION_DECL, get_identifier ("__gcov_init"), t);
964   TREE_PUBLIC (t) = 1;
965   DECL_EXTERNAL (t) = 1;
966   DECL_ASSEMBLER_NAME (t);  /* Initialize assembler name so we can stream out. */
967   gcov_init = t;
968
969   /* Generate a call to __gcov_init(&gcov_info).  */
970   body = NULL;
971   t = build_fold_addr_expr (gcov_info);
972   t = build_call_expr (gcov_init, 1, t);
973   append_to_statement_list (t, &body);
974
975   /* Generate a constructor to run it.  */
976   cgraph_build_static_cdtor ('I', body, DEFAULT_INIT_PRIORITY);
977 }
978 \f
979 /* Perform file-level initialization. Read in data file, generate name
980    of graph file.  */
981
982 void
983 coverage_init (const char *filename)
984 {
985   int len = strlen (filename);
986   /* + 1 for extra '/', in case prefix doesn't end with /.  */
987   int prefix_len;
988
989   if (profile_data_prefix == 0 && filename[0] != '/')
990     profile_data_prefix = getpwd ();
991
992   prefix_len = (profile_data_prefix) ? strlen (profile_data_prefix) + 1 : 0;
993
994   /* Name of da file.  */
995   da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
996                           + prefix_len + 1);
997
998   if (profile_data_prefix)
999     {
1000       strcpy (da_file_name, profile_data_prefix);
1001       da_file_name[prefix_len - 1] = '/';
1002       da_file_name[prefix_len] = 0;
1003     }
1004   else
1005     da_file_name[0] = 0;
1006   strcat (da_file_name, filename);
1007   strcat (da_file_name, GCOV_DATA_SUFFIX);
1008
1009   /* Name of bbg file.  */
1010   bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1);
1011   strcpy (bbg_file_name, filename);
1012   strcat (bbg_file_name, GCOV_NOTE_SUFFIX);
1013
1014   if (flag_profile_use)
1015     read_counts_file ();
1016 }
1017
1018 /* Performs file-level cleanup.  Close graph file, generate coverage
1019    variables and constructor.  */
1020
1021 void
1022 coverage_finish (void)
1023 {
1024   create_coverage ();
1025   if (bbg_file_opened)
1026     {
1027       int error = gcov_close ();
1028
1029       if (error)
1030         unlink (bbg_file_name);
1031       if (!local_tick)
1032         /* Only remove the da file, if we cannot stamp it. If we can
1033            stamp it, libgcov will DTRT.  */
1034         unlink (da_file_name);
1035     }
1036 }
1037
1038 #include "gt-coverage.h"