OSDN Git Service

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