OSDN Git Service

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