OSDN Git Service

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