OSDN Git Service

Changelog c-family/
[pf3gnuchains/gcc-fork.git] / gcc / gcov.c
1 /* Gcov.c: prepend line execution counts and branch probabilities to a
2    source file.
3    Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
4    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
5    Free Software Foundation, Inc.
6    Contributed by James E. Wilson of Cygnus Support.
7    Mangled by Bob Manson of Cygnus Support.
8    Mangled further by Nathan Sidwell <nathan@codesourcery.com>
9
10 Gcov is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3, or (at your option)
13 any later version.
14
15 Gcov is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with Gcov; see the file COPYING3.  If not see
22 <http://www.gnu.org/licenses/>.  */
23
24 /* ??? Print a list of the ten blocks with the highest execution counts,
25    and list the line numbers corresponding to those blocks.  Also, perhaps
26    list the line numbers with the highest execution counts, only printing
27    the first if there are several which are all listed in the same block.  */
28
29 /* ??? Should have an option to print the number of basic blocks, and the
30    percent of them that are covered.  */
31
32 /* Need an option to show individual block counts, and show
33    probabilities of fall through arcs.  */
34
35 #include "config.h"
36 #include "system.h"
37 #include "coretypes.h"
38 #include "tm.h"
39 #include "intl.h"
40 #include "version.h"
41
42 #include <getopt.h>
43
44 #define IN_GCOV 1
45 #include "gcov-io.h"
46 #include "gcov-io.c"
47
48 /* The gcno file is generated by -ftest-coverage option. The gcda file is
49    generated by a program compiled with -fprofile-arcs. Their formats
50    are documented in gcov-io.h.  */
51
52 /* The functions in this file for creating and solution program flow graphs
53    are very similar to functions in the gcc source file profile.c.  In
54    some places we make use of the knowledge of how profile.c works to
55    select particular algorithms here.  */
56
57 /* This is the size of the buffer used to read in source file lines.  */
58
59 #define STRING_SIZE 200
60
61 struct function_info;
62 struct block_info;
63 struct source_info;
64
65 /* Describes an arc between two basic blocks.  */
66
67 typedef struct arc_info
68 {
69   /* source and destination blocks.  */
70   struct block_info *src;
71   struct block_info *dst;
72
73   /* transition counts.  */
74   gcov_type count;
75   /* used in cycle search, so that we do not clobber original counts.  */
76   gcov_type cs_count;
77
78   unsigned int count_valid : 1;
79   unsigned int on_tree : 1;
80   unsigned int fake : 1;
81   unsigned int fall_through : 1;
82
83   /* Arc is for a function that abnormally returns.  */
84   unsigned int is_call_non_return : 1;
85
86   /* Arc is for catch/setjmp.  */
87   unsigned int is_nonlocal_return : 1;
88
89   /* Is an unconditional branch.  */
90   unsigned int is_unconditional : 1;
91
92   /* Loop making arc.  */
93   unsigned int cycle : 1;
94
95   /* Next branch on line.  */
96   struct arc_info *line_next;
97
98   /* Links to next arc on src and dst lists.  */
99   struct arc_info *succ_next;
100   struct arc_info *pred_next;
101 } arc_t;
102
103 /* Describes a basic block. Contains lists of arcs to successor and
104    predecessor blocks.  */
105
106 typedef struct block_info
107 {
108   /* Chain of exit and entry arcs.  */
109   arc_t *succ;
110   arc_t *pred;
111
112   /* Number of unprocessed exit and entry arcs.  */
113   gcov_type num_succ;
114   gcov_type num_pred;
115
116   /* Block execution count.  */
117   gcov_type count;
118   unsigned flags : 13;
119   unsigned count_valid : 1;
120   unsigned valid_chain : 1;
121   unsigned invalid_chain : 1;
122
123   /* Block is a call instrumenting site.  */
124   unsigned is_call_site : 1; /* Does the call.  */
125   unsigned is_call_return : 1; /* Is the return.  */
126
127   /* Block is a landing pad for longjmp or throw.  */
128   unsigned is_nonlocal_return : 1;
129
130   union
131   {
132     struct
133     {
134      /* Array of line numbers and source files. source files are
135         introduced by a linenumber of zero, the next 'line number' is
136         the number of the source file.  Always starts with a source
137         file.  */
138       unsigned *encoding;
139       unsigned num;
140     } line; /* Valid until blocks are linked onto lines */
141     struct
142     {
143       /* Single line graph cycle workspace.  Used for all-blocks
144          mode.  */
145       arc_t *arc;
146       unsigned ident;
147     } cycle; /* Used in all-blocks mode, after blocks are linked onto
148                lines.  */
149   } u;
150
151   /* Temporary chain for solving graph, and for chaining blocks on one
152      line.  */
153   struct block_info *chain;
154
155 } block_t;
156
157 /* Describes a single function. Contains an array of basic blocks.  */
158
159 typedef struct function_info
160 {
161   /* Name of function.  */
162   char *name;
163   unsigned ident;
164   unsigned checksum;
165
166   /* Array of basic blocks.  */
167   block_t *blocks;
168   unsigned num_blocks;
169   unsigned blocks_executed;
170
171   /* Raw arc coverage counts.  */
172   gcov_type *counts;
173   unsigned num_counts;
174
175   /* First line number.  */
176   unsigned line;
177   struct source_info *src;
178
179   /* Next function in same source file.  */
180   struct function_info *line_next;
181
182   /* Next function.  */
183   struct function_info *next;
184 } function_t;
185
186 /* Describes coverage of a file or function.  */
187
188 typedef struct coverage_info
189 {
190   int lines;
191   int lines_executed;
192
193   int branches;
194   int branches_executed;
195   int branches_taken;
196
197   int calls;
198   int calls_executed;
199
200   char *name;
201 } coverage_t;
202
203 /* Describes a single line of source. Contains a chain of basic blocks
204    with code on it.  */
205
206 typedef struct line_info
207 {
208   gcov_type count;         /* execution count */
209   union
210   {
211     arc_t *branches;       /* branches from blocks that end on this
212                               line. Used for branch-counts when not
213                               all-blocks mode.  */
214     block_t *blocks;       /* blocks which start on this line.  Used
215                               in all-blocks mode.  */
216   } u;
217   unsigned exists : 1;
218 } line_t;
219
220 /* Describes a file mentioned in the block graph.  Contains an array
221    of line info.  */
222
223 typedef struct source_info
224 {
225   /* Name of source file.  */
226   char *name;
227   unsigned index;
228   time_t file_time;
229
230   /* Array of line information.  */
231   line_t *lines;
232   unsigned num_lines;
233
234   coverage_t coverage;
235
236   /* Functions in this source file.  These are in ascending line
237      number order.  */
238   function_t *functions;
239
240   /* Next source file.  */
241   struct source_info *next;
242 } source_t;
243
244 /* Holds a list of function basic block graphs.  */
245
246 static function_t *functions;
247
248 /* This points to the head of the sourcefile structure list.  New elements
249    are always prepended.  */
250
251 static source_t *sources;
252
253 /* Next index for a source file.  */
254
255 static unsigned source_index;
256
257 /* This holds data summary information.  */
258
259 static struct gcov_summary object_summary;
260 static unsigned program_count;
261
262 /* Modification time of graph file.  */
263
264 static time_t bbg_file_time;
265
266 /* Name and file pointer of the input file for the basic block graph.  */
267
268 static char *bbg_file_name;
269
270 /* Stamp of the bbg file */
271 static unsigned bbg_stamp;
272
273 /* Name and file pointer of the input file for the arc count data.  */
274
275 static char *da_file_name;
276
277 /* Data file is missing.  */
278
279 static int no_data_file;
280
281 /* If there is several input files, compute and display results after
282    reading all data files.  This way if two or more gcda file refer to
283    the same source file (eg inline subprograms in a .h file), the
284    counts are added.  */
285
286 static int multiple_files = 0;
287
288 /* Output branch probabilities.  */
289
290 static int flag_branches = 0;
291
292 /* Show unconditional branches too.  */
293 static int flag_unconditional = 0;
294
295 /* Output a gcov file if this is true.  This is on by default, and can
296    be turned off by the -n option.  */
297
298 static int flag_gcov_file = 1;
299
300 /* Output progress indication if this is true.  This is off by default
301    and can be turned on by the -d option.  */
302
303 static int flag_display_progress = 0;
304
305 /* For included files, make the gcov output file name include the name
306    of the input source file.  For example, if x.h is included in a.c,
307    then the output file name is a.c##x.h.gcov instead of x.h.gcov.  */
308
309 static int flag_long_names = 0;
310
311 /* Output count information for every basic block, not merely those
312    that contain line number information.  */
313
314 static int flag_all_blocks = 0;
315
316 /* Output summary info for each function.  */
317
318 static int flag_function_summary = 0;
319
320 /* Object directory file prefix.  This is the directory/file where the
321    graph and data files are looked for, if nonzero.  */
322
323 static char *object_directory = 0;
324
325 /* Preserve all pathname components. Needed when object files and
326    source files are in subdirectories. '/' is mangled as '#', '.' is
327    elided and '..' mangled to '^'.  */
328
329 static int flag_preserve_paths = 0;
330
331 /* Output the number of times a branch was taken as opposed to the percentage
332    of times it was taken.  */
333
334 static int flag_counts = 0;
335
336 /* Forward declarations.  */
337 static void fnotice (FILE *, const char *, ...) ATTRIBUTE_PRINTF_2;
338 static int process_args (int, char **);
339 static void print_usage (int) ATTRIBUTE_NORETURN;
340 static void print_version (void) ATTRIBUTE_NORETURN;
341 static void process_file (const char *);
342 static void generate_results (const char *);
343 static void create_file_names (const char *);
344 static source_t *find_source (const char *);
345 static int read_graph_file (void);
346 static int read_count_file (void);
347 static void solve_flow_graph (function_t *);
348 static void add_branch_counts (coverage_t *, const arc_t *);
349 static void add_line_counts (coverage_t *, function_t *);
350 static void function_summary (const coverage_t *, const char *);
351 static const char *format_gcov (gcov_type, gcov_type, int);
352 static void accumulate_line_counts (source_t *);
353 static int output_branch_count (FILE *, int, const arc_t *);
354 static void output_lines (FILE *, const source_t *);
355 static char *make_gcov_file_name (const char *, const char *);
356 static void release_structures (void);
357 extern int main (int, char **);
358
359 int
360 main (int argc, char **argv)
361 {
362   int argno;
363   int first_arg;
364
365   /* Unlock the stdio streams.  */
366   unlock_std_streams ();
367
368   gcc_init_libintl ();
369
370   /* Handle response files.  */
371   expandargv (&argc, &argv);
372
373   argno = process_args (argc, argv);
374   if (optind == argc)
375     print_usage (true);
376
377   if (argc - argno > 1)
378     multiple_files = 1;
379
380   first_arg = argno;
381   
382   for (; argno != argc; argno++)
383     {
384       if (flag_display_progress)
385         printf("Processing file %d out of %d\n",  
386                argno - first_arg + 1, argc - first_arg);
387       process_file (argv[argno]);
388     }
389
390   generate_results (multiple_files ? NULL : argv[argc - 1]);
391
392   release_structures ();
393
394   return 0;
395 }
396
397 static void
398 fnotice (FILE *file, const char *cmsgid, ...)
399 {
400   va_list ap;
401
402   va_start (ap, cmsgid);
403   vfprintf (file, _(cmsgid), ap);
404   va_end (ap);
405 }
406 \f
407 /* Print a usage message and exit.  If ERROR_P is nonzero, this is an error,
408    otherwise the output of --help.  */
409
410 static void
411 print_usage (int error_p)
412 {
413   FILE *file = error_p ? stderr : stdout;
414   int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
415
416   fnotice (file, "Usage: gcov [OPTION]... SOURCEFILE...\n\n");
417   fnotice (file, "Print code coverage information.\n\n");
418   fnotice (file, "  -h, --help                      Print this help, then exit\n");
419   fnotice (file, "  -v, --version                   Print version number, then exit\n");
420   fnotice (file, "  -a, --all-blocks                Show information for every basic block\n");
421   fnotice (file, "  -b, --branch-probabilities      Include branch probabilities in output\n");
422   fnotice (file, "  -c, --branch-counts             Given counts of branches taken\n\
423                                     rather than percentages\n");
424   fnotice (file, "  -n, --no-output                 Do not create an output file\n");
425   fnotice (file, "  -l, --long-file-names           Use long output file names for included\n\
426                                     source files\n");
427   fnotice (file, "  -f, --function-summaries        Output summaries for each function\n");
428   fnotice (file, "  -o, --object-directory DIR|FILE Search for object files in DIR or called FILE\n");
429   fnotice (file, "  -p, --preserve-paths            Preserve all pathname components\n");
430   fnotice (file, "  -u, --unconditional-branches    Show unconditional branch counts too\n");
431   fnotice (file, "  -d, --display-progress          Display progress information\n");
432   fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
433            bug_report_url);
434   exit (status);
435 }
436
437 /* Print version information and exit.  */
438
439 static void
440 print_version (void)
441 {
442   fnotice (stdout, "gcov %s%s\n", pkgversion_string, version_string);
443   fprintf (stdout, "Copyright %s 2011 Free Software Foundation, Inc.\n",
444            _("(C)"));
445   fnotice (stdout,
446            _("This is free software; see the source for copying conditions.\n"
447              "There is NO warranty; not even for MERCHANTABILITY or \n"
448              "FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
449   exit (SUCCESS_EXIT_CODE);
450 }
451
452 static const struct option options[] =
453 {
454   { "help",                 no_argument,       NULL, 'h' },
455   { "version",              no_argument,       NULL, 'v' },
456   { "all-blocks",           no_argument,       NULL, 'a' },
457   { "branch-probabilities", no_argument,       NULL, 'b' },
458   { "branch-counts",        no_argument,       NULL, 'c' },
459   { "no-output",            no_argument,       NULL, 'n' },
460   { "long-file-names",      no_argument,       NULL, 'l' },
461   { "function-summaries",   no_argument,       NULL, 'f' },
462   { "preserve-paths",       no_argument,       NULL, 'p' },
463   { "object-directory",     required_argument, NULL, 'o' },
464   { "object-file",          required_argument, NULL, 'o' },
465   { "unconditional-branches", no_argument,     NULL, 'u' },
466   { "display-progress",     no_argument,       NULL, 'd' },
467   { 0, 0, 0, 0 }
468 };
469
470 /* Process args, return index to first non-arg.  */
471
472 static int
473 process_args (int argc, char **argv)
474 {
475   int opt;
476
477   while ((opt = getopt_long (argc, argv, "abcdfhlno:puv", options, NULL)) != -1)
478     {
479       switch (opt)
480         {
481         case 'a':
482           flag_all_blocks = 1;
483           break;
484         case 'b':
485           flag_branches = 1;
486           break;
487         case 'c':
488           flag_counts = 1;
489           break;
490         case 'f':
491           flag_function_summary = 1;
492           break;
493         case 'h':
494           print_usage (false);
495           /* print_usage will exit.  */
496         case 'l':
497           flag_long_names = 1;
498           break;
499         case 'n':
500           flag_gcov_file = 0;
501           break;
502         case 'o':
503           object_directory = optarg;
504           break;
505         case 'p':
506           flag_preserve_paths = 1;
507           break;
508         case 'u':
509           flag_unconditional = 1;
510           break;
511         case 'd':
512           flag_display_progress = 1;
513           break;
514         case 'v':
515           print_version ();
516           /* print_version will exit.  */
517         default:
518           print_usage (true);
519           /* print_usage will exit.  */
520         }
521     }
522
523   return optind;
524 }
525
526 /* Process a single source file.  */
527
528 static void
529 process_file (const char *file_name)
530 {
531   function_t *fn;
532   function_t *fn_p;
533   function_t *old_functions;
534
535   /* Save and clear the list of current functions.  They will be appended
536      later.  */
537   old_functions = functions;
538   functions = NULL;
539
540   create_file_names (file_name);
541   if (read_graph_file ())
542     return;
543
544   if (!functions)
545     {
546       fnotice (stderr, "%s:no functions found\n", bbg_file_name);
547       return;
548     }
549
550   if (read_count_file ())
551     return;
552
553   for (fn_p = NULL, fn = functions; fn; fn_p = fn, fn = fn->next)
554     solve_flow_graph (fn);
555
556   if (fn_p)
557     fn_p->next = old_functions;
558 }
559
560 static void
561 generate_results (const char *file_name)
562 {
563   source_t *src;
564   function_t *fn;
565
566   for (src = sources; src; src = src->next)
567     src->lines = XCNEWVEC (line_t, src->num_lines);
568   for (fn = functions; fn; fn = fn->next)
569     {
570       coverage_t coverage;
571
572       memset (&coverage, 0, sizeof (coverage));
573       coverage.name = fn->name;
574       add_line_counts (flag_function_summary ? &coverage : NULL, fn);
575       if (flag_function_summary)
576         {
577           function_summary (&coverage, "Function");
578           fnotice (stdout, "\n");
579         }
580     }
581
582   for (src = sources; src; src = src->next)
583     {
584       accumulate_line_counts (src);
585       function_summary (&src->coverage, "File");
586       if (flag_gcov_file)
587         {
588           char *gcov_file_name = make_gcov_file_name (file_name, src->name);
589           FILE *gcov_file = fopen (gcov_file_name, "w");
590
591           if (gcov_file)
592             {
593               fnotice (stdout, "%s:creating '%s'\n",
594                        src->name, gcov_file_name);
595               output_lines (gcov_file, src);
596               if (ferror (gcov_file))
597                     fnotice (stderr, "%s:error writing output file '%s'\n",
598                              src->name, gcov_file_name);
599               fclose (gcov_file);
600             }
601           else
602             fnotice (stderr, "%s:could not open output file '%s'\n",
603                      src->name, gcov_file_name);
604           free (gcov_file_name);
605         }
606       fnotice (stdout, "\n");
607     }
608 }
609
610 /* Release all memory used.  */
611
612 static void
613 release_structures (void)
614 {
615   function_t *fn;
616   source_t *src;
617
618   while ((src = sources))
619     {
620       sources = src->next;
621
622       free (src->name);
623       free (src->lines);
624     }
625
626   while ((fn = functions))
627     {
628       unsigned ix;
629       block_t *block;
630
631       functions = fn->next;
632       for (ix = fn->num_blocks, block = fn->blocks; ix--; block++)
633         {
634           arc_t *arc, *arc_n;
635
636           for (arc = block->succ; arc; arc = arc_n)
637             {
638               arc_n = arc->succ_next;
639               free (arc);
640             }
641         }
642       free (fn->blocks);
643       free (fn->counts);
644     }
645 }
646
647 /* Generate the names of the graph and data files. If OBJECT_DIRECTORY
648    is not specified, these are looked for in the current directory,
649    and named from the basename of the FILE_NAME sans extension. If
650    OBJECT_DIRECTORY is specified and is a directory, the files are in
651    that directory, but named from the basename of the FILE_NAME, sans
652    extension. Otherwise OBJECT_DIRECTORY is taken to be the name of
653    the object *file*, and the data files are named from that.  */
654
655 static void
656 create_file_names (const char *file_name)
657 {
658   char *cptr;
659   char *name;
660   int length = strlen (file_name);
661   int base;
662
663   /* Free previous file names.  */
664   if (bbg_file_name)
665     free (bbg_file_name);
666   if (da_file_name)
667     free (da_file_name);
668   da_file_name = bbg_file_name = NULL;
669   bbg_file_time = 0;
670   bbg_stamp = 0;
671
672   if (object_directory && object_directory[0])
673     {
674       struct stat status;
675
676       length += strlen (object_directory) + 2;
677       name = XNEWVEC (char, length);
678       name[0] = 0;
679
680       base = !stat (object_directory, &status) && S_ISDIR (status.st_mode);
681       strcat (name, object_directory);
682       if (base && (! IS_DIR_SEPARATOR (name[strlen (name) - 1])))
683         strcat (name, "/");
684     }
685   else
686     {
687       name = XNEWVEC (char, length + 1);
688       name[0] = 0;
689       base = 1;
690     }
691
692   if (base)
693     {
694       /* Append source file name.  */
695       const char *cptr = lbasename (file_name);
696       strcat (name, cptr ? cptr : file_name);
697     }
698
699   /* Remove the extension.  */
700   cptr = strrchr (name, '.');
701   if (cptr)
702     *cptr = 0;
703
704   length = strlen (name);
705
706   bbg_file_name = XNEWVEC (char, length + strlen (GCOV_NOTE_SUFFIX) + 1);
707   strcpy (bbg_file_name, name);
708   strcpy (bbg_file_name + length, GCOV_NOTE_SUFFIX);
709
710   da_file_name = XNEWVEC (char, length + strlen (GCOV_DATA_SUFFIX) + 1);
711   strcpy (da_file_name, name);
712   strcpy (da_file_name + length, GCOV_DATA_SUFFIX);
713
714   free (name);
715   return;
716 }
717
718 /* Find or create a source file structure for FILE_NAME. Copies
719    FILE_NAME on creation */
720
721 static source_t *
722 find_source (const char *file_name)
723 {
724   source_t *src;
725   struct stat status;
726
727   if (!file_name)
728     file_name = "<unknown>";
729
730   for (src = sources; src; src = src->next)
731     if (!filename_cmp (file_name, src->name))
732       break;
733
734   if (!src)
735     {
736       src = XCNEW (source_t);
737       src->name = xstrdup (file_name);
738       src->coverage.name = src->name;
739       src->index = source_index++;
740       src->next = sources;
741       sources = src;
742
743       if (!stat (file_name, &status))
744         src->file_time = status.st_mtime;
745     }
746
747   if (src->file_time > bbg_file_time)
748     {
749       static int info_emitted;
750
751       fnotice (stderr, "%s:source file is newer than graph file '%s'\n",
752                src->name, bbg_file_name);
753       if (!info_emitted)
754         {
755           fnotice (stderr,
756                    "(the message is only displayed one per source file)\n");
757           info_emitted = 1;
758         }
759       src->file_time = 0;
760     }
761
762   return src;
763 }
764
765 /* Read the graph file. Return nonzero on fatal error.  */
766
767 static int
768 read_graph_file (void)
769 {
770   unsigned version;
771   unsigned current_tag = 0;
772   struct function_info *fn = NULL;
773   function_t *old_functions_head = functions;
774   source_t *src = NULL;
775   unsigned ix;
776   unsigned tag;
777
778   if (!gcov_open (bbg_file_name, 1))
779     {
780       fnotice (stderr, "%s:cannot open graph file\n", bbg_file_name);
781       return 1;
782     }
783   bbg_file_time = gcov_time ();
784   if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC))
785     {
786       fnotice (stderr, "%s:not a gcov graph file\n", bbg_file_name);
787       gcov_close ();
788       return 1;
789     }
790
791   version = gcov_read_unsigned ();
792   if (version != GCOV_VERSION)
793     {
794       char v[4], e[4];
795
796       GCOV_UNSIGNED2STRING (v, version);
797       GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
798
799       fnotice (stderr, "%s:version '%.4s', prefer '%.4s'\n",
800                bbg_file_name, v, e);
801     }
802   bbg_stamp = gcov_read_unsigned ();
803
804   while ((tag = gcov_read_unsigned ()))
805     {
806       unsigned length = gcov_read_unsigned ();
807       gcov_position_t base = gcov_position ();
808
809       if (tag == GCOV_TAG_FUNCTION)
810         {
811           char *function_name;
812           unsigned ident, checksum, lineno;
813           source_t *src;
814           function_t *probe, *prev;
815
816           ident = gcov_read_unsigned ();
817           checksum = gcov_read_unsigned ();
818           function_name = xstrdup (gcov_read_string ());
819           src = find_source (gcov_read_string ());
820           lineno = gcov_read_unsigned ();
821
822           fn = XCNEW (function_t);
823           fn->name = function_name;
824           fn->ident = ident;
825           fn->checksum = checksum;
826           fn->src = src;
827           fn->line = lineno;
828
829           fn->next = functions;
830           functions = fn;
831           current_tag = tag;
832
833           if (lineno >= src->num_lines)
834             src->num_lines = lineno + 1;
835           /* Now insert it into the source file's list of
836              functions. Normally functions will be encountered in
837              ascending order, so a simple scan is quick.  */
838           for (probe = src->functions, prev = NULL;
839                probe && probe->line > lineno;
840                prev = probe, probe = probe->line_next)
841             continue;
842           fn->line_next = probe;
843           if (prev)
844             prev->line_next = fn;
845           else
846             src->functions = fn;
847         }
848       else if (fn && tag == GCOV_TAG_BLOCKS)
849         {
850           if (fn->blocks)
851             fnotice (stderr, "%s:already seen blocks for '%s'\n",
852                      bbg_file_name, fn->name);
853           else
854             {
855               unsigned ix, num_blocks = GCOV_TAG_BLOCKS_NUM (length);
856               fn->num_blocks = num_blocks;
857
858               fn->blocks = XCNEWVEC (block_t, fn->num_blocks);
859               for (ix = 0; ix != num_blocks; ix++)
860                 fn->blocks[ix].flags = gcov_read_unsigned ();
861             }
862         }
863       else if (fn && tag == GCOV_TAG_ARCS)
864         {
865           unsigned src = gcov_read_unsigned ();
866           unsigned num_dests = GCOV_TAG_ARCS_NUM (length);
867
868           if (src >= fn->num_blocks || fn->blocks[src].succ)
869             goto corrupt;
870
871           while (num_dests--)
872             {
873               struct arc_info *arc;
874               unsigned dest = gcov_read_unsigned ();
875               unsigned flags = gcov_read_unsigned ();
876
877               if (dest >= fn->num_blocks)
878                 goto corrupt;
879               arc = XCNEW (arc_t);
880
881               arc->dst = &fn->blocks[dest];
882               arc->src = &fn->blocks[src];
883
884               arc->count = 0;
885               arc->count_valid = 0;
886               arc->on_tree = !!(flags & GCOV_ARC_ON_TREE);
887               arc->fake = !!(flags & GCOV_ARC_FAKE);
888               arc->fall_through = !!(flags & GCOV_ARC_FALLTHROUGH);
889
890               arc->succ_next = fn->blocks[src].succ;
891               fn->blocks[src].succ = arc;
892               fn->blocks[src].num_succ++;
893
894               arc->pred_next = fn->blocks[dest].pred;
895               fn->blocks[dest].pred = arc;
896               fn->blocks[dest].num_pred++;
897
898               if (arc->fake)
899                 {
900                   if (src)
901                     {
902                       /* Exceptional exit from this function, the
903                          source block must be a call.  */
904                       fn->blocks[src].is_call_site = 1;
905                       arc->is_call_non_return = 1;
906                     }
907                   else
908                     {
909                       /* Non-local return from a callee of this
910                          function. The destination block is a catch or
911                          setjmp.  */
912                       arc->is_nonlocal_return = 1;
913                       fn->blocks[dest].is_nonlocal_return = 1;
914                     }
915                 }
916
917               if (!arc->on_tree)
918                 fn->num_counts++;
919             }
920         }
921       else if (fn && tag == GCOV_TAG_LINES)
922         {
923           unsigned blockno = gcov_read_unsigned ();
924           unsigned *line_nos = XCNEWVEC (unsigned, length - 1);
925
926           if (blockno >= fn->num_blocks || fn->blocks[blockno].u.line.encoding)
927             goto corrupt;
928
929           for (ix = 0; ;  )
930             {
931               unsigned lineno = gcov_read_unsigned ();
932
933               if (lineno)
934                 {
935                   if (!ix)
936                     {
937                       line_nos[ix++] = 0;
938                       line_nos[ix++] = src->index;
939                     }
940                   line_nos[ix++] = lineno;
941                   if (lineno >= src->num_lines)
942                     src->num_lines = lineno + 1;
943                 }
944               else
945                 {
946                   const char *file_name = gcov_read_string ();
947
948                   if (!file_name)
949                     break;
950                   src = find_source (file_name);
951
952                   line_nos[ix++] = 0;
953                   line_nos[ix++] = src->index;
954                 }
955             }
956
957           fn->blocks[blockno].u.line.encoding = line_nos;
958           fn->blocks[blockno].u.line.num = ix;
959         }
960       else if (current_tag && !GCOV_TAG_IS_SUBTAG (current_tag, tag))
961         {
962           fn = NULL;
963           current_tag = 0;
964         }
965       gcov_sync (base, length);
966       if (gcov_is_error ())
967         {
968         corrupt:;
969           fnotice (stderr, "%s:corrupted\n", bbg_file_name);
970           gcov_close ();
971           return 1;
972         }
973     }
974   gcov_close ();
975
976   /* We built everything backwards, so nreverse them all.  */
977
978   /* Reverse sources. Not strictly necessary, but we'll then process
979      them in the 'expected' order.  */
980   {
981     source_t *src, *src_p, *src_n;
982
983     for (src_p = NULL, src = sources; src; src_p = src, src = src_n)
984       {
985         src_n = src->next;
986         src->next = src_p;
987       }
988     sources =  src_p;
989   }
990
991   /* Reverse functions.  */
992   {
993     function_t *fn, *fn_p, *fn_n;
994
995     for (fn_p = old_functions_head, fn = functions;
996          fn != old_functions_head;
997          fn_p = fn, fn = fn_n)
998       {
999         unsigned ix;
1000
1001         fn_n = fn->next;
1002         fn->next = fn_p;
1003
1004         /* Reverse the arcs.  */
1005         for (ix = fn->num_blocks; ix--;)
1006           {
1007             arc_t *arc, *arc_p, *arc_n;
1008
1009             for (arc_p = NULL, arc = fn->blocks[ix].succ; arc;
1010                  arc_p = arc, arc = arc_n)
1011               {
1012                 arc_n = arc->succ_next;
1013                 arc->succ_next = arc_p;
1014               }
1015             fn->blocks[ix].succ = arc_p;
1016
1017             for (arc_p = NULL, arc = fn->blocks[ix].pred; arc;
1018                  arc_p = arc, arc = arc_n)
1019               {
1020                 arc_n = arc->pred_next;
1021                 arc->pred_next = arc_p;
1022               }
1023             fn->blocks[ix].pred = arc_p;
1024           }
1025       }
1026     functions = fn_p;
1027   }
1028   return 0;
1029 }
1030
1031 /* Reads profiles from the count file and attach to each
1032    function. Return nonzero if fatal error.  */
1033
1034 static int
1035 read_count_file (void)
1036 {
1037   unsigned ix;
1038   unsigned version;
1039   unsigned tag;
1040   function_t *fn = NULL;
1041   int error = 0;
1042
1043   if (!gcov_open (da_file_name, 1))
1044     {
1045       fnotice (stderr, "%s:cannot open data file, assuming not executed\n",
1046                da_file_name);
1047       no_data_file = 1;
1048       return 0;
1049     }
1050   if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
1051     {
1052       fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
1053     cleanup:;
1054       gcov_close ();
1055       return 1;
1056     }
1057   version = gcov_read_unsigned ();
1058   if (version != GCOV_VERSION)
1059     {
1060       char v[4], e[4];
1061
1062       GCOV_UNSIGNED2STRING (v, version);
1063       GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
1064
1065       fnotice (stderr, "%s:version '%.4s', prefer version '%.4s'\n",
1066                da_file_name, v, e);
1067     }
1068   tag = gcov_read_unsigned ();
1069   if (tag != bbg_stamp)
1070     {
1071       fnotice (stderr, "%s:stamp mismatch with graph file\n", da_file_name);
1072       goto cleanup;
1073     }
1074
1075   while ((tag = gcov_read_unsigned ()))
1076     {
1077       unsigned length = gcov_read_unsigned ();
1078       unsigned long base = gcov_position ();
1079
1080       if (tag == GCOV_TAG_OBJECT_SUMMARY)
1081         gcov_read_summary (&object_summary);
1082       else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
1083         program_count++;
1084       else if (tag == GCOV_TAG_FUNCTION)
1085         {
1086           {
1087             unsigned ident = gcov_read_unsigned ();
1088             struct function_info *fn_n = functions;
1089
1090             /* Try to find the function in the list.
1091                To speed up the search, first start from the last function
1092                found.   */
1093             for (fn = fn ? fn->next : NULL; ; fn = fn->next)
1094               {
1095                 if (fn)
1096                   ;
1097                 else if ((fn = fn_n))
1098                   fn_n = NULL;
1099                 else
1100                   {
1101                     fnotice (stderr, "%s:unknown function '%u'\n",
1102                              da_file_name, ident);
1103                     break;
1104                   }
1105                 if (fn->ident == ident)
1106                   break;
1107               }
1108           }
1109
1110           if (!fn)
1111             ;
1112           else if (gcov_read_unsigned () != fn->checksum)
1113             {
1114             mismatch:;
1115               fnotice (stderr, "%s:profile mismatch for '%s'\n",
1116                        da_file_name, fn->name);
1117               goto cleanup;
1118             }
1119         }
1120       else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
1121         {
1122           if (length != GCOV_TAG_COUNTER_LENGTH (fn->num_counts))
1123             goto mismatch;
1124
1125           if (!fn->counts)
1126             fn->counts = XCNEWVEC (gcov_type, fn->num_counts);
1127
1128           for (ix = 0; ix != fn->num_counts; ix++)
1129             fn->counts[ix] += gcov_read_counter ();
1130         }
1131       gcov_sync (base, length);
1132       if ((error = gcov_is_error ()))
1133         {
1134           fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n",
1135                    da_file_name);
1136           goto cleanup;
1137         }
1138     }
1139
1140   gcov_close ();
1141   return 0;
1142 }
1143
1144 /* Solve the flow graph. Propagate counts from the instrumented arcs
1145    to the blocks and the uninstrumented arcs.  */
1146
1147 static void
1148 solve_flow_graph (function_t *fn)
1149 {
1150   unsigned ix;
1151   arc_t *arc;
1152   gcov_type *count_ptr = fn->counts;
1153   block_t *blk;
1154   block_t *valid_blocks = NULL;    /* valid, but unpropagated blocks.  */
1155   block_t *invalid_blocks = NULL;  /* invalid, but inferable blocks.  */
1156
1157   if (fn->num_blocks < 2)
1158     fnotice (stderr, "%s:'%s' lacks entry and/or exit blocks\n",
1159              bbg_file_name, fn->name);
1160   else
1161     {
1162       if (fn->blocks[0].num_pred)
1163         fnotice (stderr, "%s:'%s' has arcs to entry block\n",
1164                  bbg_file_name, fn->name);
1165       else
1166         /* We can't deduce the entry block counts from the lack of
1167            predecessors.  */
1168         fn->blocks[0].num_pred = ~(unsigned)0;
1169
1170       if (fn->blocks[fn->num_blocks - 1].num_succ)
1171         fnotice (stderr, "%s:'%s' has arcs from exit block\n",
1172                  bbg_file_name, fn->name);
1173       else
1174         /* Likewise, we can't deduce exit block counts from the lack
1175            of its successors.  */
1176         fn->blocks[fn->num_blocks - 1].num_succ = ~(unsigned)0;
1177     }
1178
1179   /* Propagate the measured counts, this must be done in the same
1180      order as the code in profile.c  */
1181   for (ix = 0, blk = fn->blocks; ix != fn->num_blocks; ix++, blk++)
1182     {
1183       block_t const *prev_dst = NULL;
1184       int out_of_order = 0;
1185       int non_fake_succ = 0;
1186
1187       for (arc = blk->succ; arc; arc = arc->succ_next)
1188         {
1189           if (!arc->fake)
1190             non_fake_succ++;
1191
1192           if (!arc->on_tree)
1193             {
1194               if (count_ptr)
1195                 arc->count = *count_ptr++;
1196               arc->count_valid = 1;
1197               blk->num_succ--;
1198               arc->dst->num_pred--;
1199             }
1200           if (prev_dst && prev_dst > arc->dst)
1201             out_of_order = 1;
1202           prev_dst = arc->dst;
1203         }
1204       if (non_fake_succ == 1)
1205         {
1206           /* If there is only one non-fake exit, it is an
1207              unconditional branch.  */
1208           for (arc = blk->succ; arc; arc = arc->succ_next)
1209             if (!arc->fake)
1210               {
1211                 arc->is_unconditional = 1;
1212                 /* If this block is instrumenting a call, it might be
1213                    an artificial block. It is not artificial if it has
1214                    a non-fallthrough exit, or the destination of this
1215                    arc has more than one entry.  Mark the destination
1216                    block as a return site, if none of those conditions
1217                    hold.  */
1218                 if (blk->is_call_site && arc->fall_through
1219                     && arc->dst->pred == arc && !arc->pred_next)
1220                   arc->dst->is_call_return = 1;
1221               }
1222         }
1223
1224       /* Sort the successor arcs into ascending dst order. profile.c
1225          normally produces arcs in the right order, but sometimes with
1226          one or two out of order.  We're not using a particularly
1227          smart sort.  */
1228       if (out_of_order)
1229         {
1230           arc_t *start = blk->succ;
1231           unsigned changes = 1;
1232
1233           while (changes)
1234             {
1235               arc_t *arc, *arc_p, *arc_n;
1236
1237               changes = 0;
1238               for (arc_p = NULL, arc = start; (arc_n = arc->succ_next);)
1239                 {
1240                   if (arc->dst > arc_n->dst)
1241                     {
1242                       changes = 1;
1243                       if (arc_p)
1244                         arc_p->succ_next = arc_n;
1245                       else
1246                         start = arc_n;
1247                       arc->succ_next = arc_n->succ_next;
1248                       arc_n->succ_next = arc;
1249                       arc_p = arc_n;
1250                     }
1251                   else
1252                     {
1253                       arc_p = arc;
1254                       arc = arc_n;
1255                     }
1256                 }
1257             }
1258           blk->succ = start;
1259         }
1260
1261       /* Place it on the invalid chain, it will be ignored if that's
1262          wrong.  */
1263       blk->invalid_chain = 1;
1264       blk->chain = invalid_blocks;
1265       invalid_blocks = blk;
1266     }
1267
1268   while (invalid_blocks || valid_blocks)
1269     {
1270       while ((blk = invalid_blocks))
1271         {
1272           gcov_type total = 0;
1273           const arc_t *arc;
1274
1275           invalid_blocks = blk->chain;
1276           blk->invalid_chain = 0;
1277           if (!blk->num_succ)
1278             for (arc = blk->succ; arc; arc = arc->succ_next)
1279               total += arc->count;
1280           else if (!blk->num_pred)
1281             for (arc = blk->pred; arc; arc = arc->pred_next)
1282               total += arc->count;
1283           else
1284             continue;
1285
1286           blk->count = total;
1287           blk->count_valid = 1;
1288           blk->chain = valid_blocks;
1289           blk->valid_chain = 1;
1290           valid_blocks = blk;
1291         }
1292       while ((blk = valid_blocks))
1293         {
1294           gcov_type total;
1295           arc_t *arc, *inv_arc;
1296
1297           valid_blocks = blk->chain;
1298           blk->valid_chain = 0;
1299           if (blk->num_succ == 1)
1300             {
1301               block_t *dst;
1302
1303               total = blk->count;
1304               inv_arc = NULL;
1305               for (arc = blk->succ; arc; arc = arc->succ_next)
1306                 {
1307                   total -= arc->count;
1308                   if (!arc->count_valid)
1309                     inv_arc = arc;
1310                 }
1311               dst = inv_arc->dst;
1312               inv_arc->count_valid = 1;
1313               inv_arc->count = total;
1314               blk->num_succ--;
1315               dst->num_pred--;
1316               if (dst->count_valid)
1317                 {
1318                   if (dst->num_pred == 1 && !dst->valid_chain)
1319                     {
1320                       dst->chain = valid_blocks;
1321                       dst->valid_chain = 1;
1322                       valid_blocks = dst;
1323                     }
1324                 }
1325               else
1326                 {
1327                   if (!dst->num_pred && !dst->invalid_chain)
1328                     {
1329                       dst->chain = invalid_blocks;
1330                       dst->invalid_chain = 1;
1331                       invalid_blocks = dst;
1332                     }
1333                 }
1334             }
1335           if (blk->num_pred == 1)
1336             {
1337               block_t *src;
1338
1339               total = blk->count;
1340               inv_arc = NULL;
1341               for (arc = blk->pred; arc; arc = arc->pred_next)
1342                 {
1343                   total -= arc->count;
1344                   if (!arc->count_valid)
1345                     inv_arc = arc;
1346                 }
1347               src = inv_arc->src;
1348               inv_arc->count_valid = 1;
1349               inv_arc->count = total;
1350               blk->num_pred--;
1351               src->num_succ--;
1352               if (src->count_valid)
1353                 {
1354                   if (src->num_succ == 1 && !src->valid_chain)
1355                     {
1356                       src->chain = valid_blocks;
1357                       src->valid_chain = 1;
1358                       valid_blocks = src;
1359                     }
1360                 }
1361               else
1362                 {
1363                   if (!src->num_succ && !src->invalid_chain)
1364                     {
1365                       src->chain = invalid_blocks;
1366                       src->invalid_chain = 1;
1367                       invalid_blocks = src;
1368                     }
1369                 }
1370             }
1371         }
1372     }
1373
1374   /* If the graph has been correctly solved, every block will have a
1375      valid count.  */
1376   for (ix = 0; ix < fn->num_blocks; ix++)
1377     if (!fn->blocks[ix].count_valid)
1378       {
1379         fnotice (stderr, "%s:graph is unsolvable for '%s'\n",
1380                  bbg_file_name, fn->name);
1381         break;
1382       }
1383 }
1384
1385 \f
1386
1387 /* Increment totals in COVERAGE according to arc ARC.  */
1388
1389 static void
1390 add_branch_counts (coverage_t *coverage, const arc_t *arc)
1391 {
1392   if (arc->is_call_non_return)
1393     {
1394       coverage->calls++;
1395       if (arc->src->count)
1396         coverage->calls_executed++;
1397     }
1398   else if (!arc->is_unconditional)
1399     {
1400       coverage->branches++;
1401       if (arc->src->count)
1402         coverage->branches_executed++;
1403       if (arc->count)
1404         coverage->branches_taken++;
1405     }
1406 }
1407
1408 /* Format a HOST_WIDE_INT as either a percent ratio, or absolute
1409    count.  If dp >= 0, format TOP/BOTTOM * 100 to DP decimal places.
1410    If DP is zero, no decimal point is printed. Only print 100% when
1411    TOP==BOTTOM and only print 0% when TOP=0.  If dp < 0, then simply
1412    format TOP.  Return pointer to a static string.  */
1413
1414 static char const *
1415 format_gcov (gcov_type top, gcov_type bottom, int dp)
1416 {
1417   static char buffer[20];
1418
1419   if (dp >= 0)
1420     {
1421       float ratio = bottom ? (float)top / bottom : 0;
1422       int ix;
1423       unsigned limit = 100;
1424       unsigned percent;
1425
1426       for (ix = dp; ix--; )
1427         limit *= 10;
1428
1429       percent = (unsigned) (ratio * limit + (float)0.5);
1430       if (percent <= 0 && top)
1431         percent = 1;
1432       else if (percent >= limit && top != bottom)
1433         percent = limit - 1;
1434       ix = sprintf (buffer, "%.*u%%", dp + 1, percent);
1435       if (dp)
1436         {
1437           dp++;
1438           do
1439             {
1440               buffer[ix+1] = buffer[ix];
1441               ix--;
1442             }
1443           while (dp--);
1444           buffer[ix + 1] = '.';
1445         }
1446     }
1447   else
1448     sprintf (buffer, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT)top);
1449
1450   return buffer;
1451 }
1452
1453
1454 /* Output summary info for a function.  */
1455
1456 static void
1457 function_summary (const coverage_t *coverage, const char *title)
1458 {
1459   fnotice (stdout, "%s '%s'\n", title, coverage->name);
1460
1461   if (coverage->lines)
1462     fnotice (stdout, "Lines executed:%s of %d\n",
1463              format_gcov (coverage->lines_executed, coverage->lines, 2),
1464              coverage->lines);
1465   else
1466     fnotice (stdout, "No executable lines\n");
1467
1468   if (flag_branches)
1469     {
1470       if (coverage->branches)
1471         {
1472           fnotice (stdout, "Branches executed:%s of %d\n",
1473                    format_gcov (coverage->branches_executed,
1474                                 coverage->branches, 2),
1475                    coverage->branches);
1476           fnotice (stdout, "Taken at least once:%s of %d\n",
1477                    format_gcov (coverage->branches_taken,
1478                                 coverage->branches, 2),
1479                    coverage->branches);
1480         }
1481       else
1482         fnotice (stdout, "No branches\n");
1483       if (coverage->calls)
1484         fnotice (stdout, "Calls executed:%s of %d\n",
1485                  format_gcov (coverage->calls_executed, coverage->calls, 2),
1486                  coverage->calls);
1487       else
1488         fnotice (stdout, "No calls\n");
1489     }
1490 }
1491
1492 /* Generate an output file name. LONG_OUTPUT_NAMES and PRESERVE_PATHS
1493    affect name generation. With preserve_paths we create a filename
1494    from all path components of the source file, replacing '/' with
1495    '#', without it we simply take the basename component. With
1496    long_output_names we prepend the processed name of the input file
1497    to each output name (except when the current source file is the
1498    input file, so you don't get a double concatenation). The two
1499    components are separated by '##'. Also '.' filename components are
1500    removed and '..'  components are renamed to '^'.  */
1501
1502 static char *
1503 make_gcov_file_name (const char *input_name, const char *src_name)
1504 {
1505   const char *cptr;
1506   char *name;
1507
1508   if (flag_long_names && input_name && strcmp (src_name, input_name))
1509     {
1510       name = XNEWVEC (char, strlen (src_name) + strlen (input_name) + 10);
1511       name[0] = 0;
1512       /* Generate the input filename part.  */
1513       cptr = flag_preserve_paths ? NULL : lbasename (input_name);
1514       strcat (name, cptr ? cptr : input_name);
1515       strcat (name, "##");
1516     }
1517   else
1518     {
1519       name = XNEWVEC (char, strlen (src_name) + 10);
1520       name[0] = 0;
1521     }
1522
1523   /* Generate the source filename part.  */
1524
1525   cptr = flag_preserve_paths ? NULL : lbasename (src_name);
1526   strcat (name, cptr ? cptr : src_name);
1527
1528   if (flag_preserve_paths)
1529     {
1530       /* Convert '/' and '\' to '#', remove '/./', convert '/../' to '#^#',
1531          convert ':' to '~' on DOS based file system.  */
1532       char *pnew = name, *pold = name;
1533
1534       /* First check for leading drive separator.  */
1535
1536       while (*pold != '\0')
1537         {
1538 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
1539           if (*pold == ':')
1540             {
1541               *pnew++ = '~';
1542               pold++;
1543             }
1544           else
1545 #endif
1546           if ((*pold == '/'
1547                     && (strstr (pold, "/./") == pold
1548                         || strstr (pold, "/.\\") == pold))
1549                    || (*pold == '\\'
1550                        && (strstr (pold, "\\.\\") == pold
1551                            || strstr (pold, "\\./") == pold)))
1552               pold += 3;
1553           else if (*pold == '/'
1554                    && (strstr (pold, "/../") == pold
1555                        || strstr (pold, "/..\\") == pold))
1556             {
1557               strcpy (pnew, "#^#");
1558               pnew += 3;
1559               pold += 4;
1560             }
1561           else if (*pold == '\\'
1562                    && (strstr (pold, "\\..\\") == pold
1563                        || strstr (pold, "\\../") == pold))
1564             {
1565               strcpy (pnew, "#^#");
1566               pnew += 3;
1567               pold += 4;
1568             }
1569           else if (*pold == '/' || *pold == '\\')
1570             {
1571               *pnew++ = '#';
1572               pold++;
1573             }
1574           else
1575             *pnew++ = *pold++;
1576         }
1577
1578       *pnew = '\0';
1579     }
1580
1581   strcat (name, ".gcov");
1582   return name;
1583 }
1584
1585 /* Scan through the bb_data for each line in the block, increment
1586    the line number execution count indicated by the execution count of
1587    the appropriate basic block.  */
1588
1589 static void
1590 add_line_counts (coverage_t *coverage, function_t *fn)
1591 {
1592   unsigned ix;
1593   line_t *line = NULL; /* This is propagated from one iteration to the
1594                           next.  */
1595
1596   /* Scan each basic block.  */
1597   for (ix = 0; ix != fn->num_blocks; ix++)
1598     {
1599       block_t *block = &fn->blocks[ix];
1600       unsigned *encoding;
1601       const source_t *src = NULL;
1602       unsigned jx;
1603
1604       if (block->count && ix && ix + 1 != fn->num_blocks)
1605         fn->blocks_executed++;
1606       for (jx = 0, encoding = block->u.line.encoding;
1607            jx != block->u.line.num; jx++, encoding++)
1608         if (!*encoding)
1609           {
1610             unsigned src_n = *++encoding;
1611
1612             for (src = sources; src->index != src_n; src = src->next)
1613               continue;
1614             jx++;
1615           }
1616         else
1617           {
1618             line = &src->lines[*encoding];
1619
1620             if (coverage)
1621               {
1622                 if (!line->exists)
1623                   coverage->lines++;
1624                 if (!line->count && block->count)
1625                   coverage->lines_executed++;
1626               }
1627             line->exists = 1;
1628             line->count += block->count;
1629           }
1630       free (block->u.line.encoding);
1631       block->u.cycle.arc = NULL;
1632       block->u.cycle.ident = ~0U;
1633
1634       if (!ix || ix + 1 == fn->num_blocks)
1635         /* Entry or exit block */;
1636       else if (flag_all_blocks)
1637         {
1638           line_t *block_line = line ? line : &fn->src->lines[fn->line];
1639
1640           block->chain = block_line->u.blocks;
1641           block_line->u.blocks = block;
1642         }
1643       else if (flag_branches)
1644         {
1645           arc_t *arc;
1646
1647           for (arc = block->succ; arc; arc = arc->succ_next)
1648             {
1649               arc->line_next = line->u.branches;
1650               line->u.branches = arc;
1651               if (coverage && !arc->is_unconditional)
1652                 add_branch_counts (coverage, arc);
1653             }
1654         }
1655     }
1656   if (!line)
1657     fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name, fn->name);
1658 }
1659
1660 /* Accumulate the line counts of a file.  */
1661
1662 static void
1663 accumulate_line_counts (source_t *src)
1664 {
1665   line_t *line;
1666   function_t *fn, *fn_p, *fn_n;
1667   unsigned ix;
1668
1669   /* Reverse the function order.  */
1670   for (fn = src->functions, fn_p = NULL; fn;
1671        fn_p = fn, fn = fn_n)
1672     {
1673       fn_n = fn->line_next;
1674       fn->line_next = fn_p;
1675     }
1676   src->functions = fn_p;
1677
1678   for (ix = src->num_lines, line = src->lines; ix--; line++)
1679     {
1680       if (!flag_all_blocks)
1681         {
1682           arc_t *arc, *arc_p, *arc_n;
1683
1684           /* Total and reverse the branch information.  */
1685           for (arc = line->u.branches, arc_p = NULL; arc;
1686                arc_p = arc, arc = arc_n)
1687             {
1688               arc_n = arc->line_next;
1689               arc->line_next = arc_p;
1690
1691               add_branch_counts (&src->coverage, arc);
1692             }
1693           line->u.branches = arc_p;
1694         }
1695       else if (line->u.blocks)
1696         {
1697           /* The user expects the line count to be the number of times
1698              a line has been executed. Simply summing the block count
1699              will give an artificially high number.  The Right Thing
1700              is to sum the entry counts to the graph of blocks on this
1701              line, then find the elementary cycles of the local graph
1702              and add the transition counts of those cycles.  */
1703           block_t *block, *block_p, *block_n;
1704           gcov_type count = 0;
1705
1706           /* Reverse the block information.  */
1707           for (block = line->u.blocks, block_p = NULL; block;
1708                block_p = block, block = block_n)
1709             {
1710               block_n = block->chain;
1711               block->chain = block_p;
1712               block->u.cycle.ident = ix;
1713             }
1714           line->u.blocks = block_p;
1715
1716           /* Sum the entry arcs.  */
1717           for (block = line->u.blocks; block; block = block->chain)
1718             {
1719               arc_t *arc;
1720
1721               for (arc = block->pred; arc; arc = arc->pred_next)
1722                 {
1723                   if (arc->src->u.cycle.ident != ix)
1724                     count += arc->count;
1725                   if (flag_branches)
1726                     add_branch_counts (&src->coverage, arc);
1727                 }
1728
1729               /* Initialize the cs_count.  */
1730               for (arc = block->succ; arc; arc = arc->succ_next)
1731                 arc->cs_count = arc->count;
1732             }
1733
1734           /* Find the loops. This uses the algorithm described in
1735              Tiernan 'An Efficient Search Algorithm to Find the
1736              Elementary Circuits of a Graph', CACM Dec 1970. We hold
1737              the P array by having each block point to the arc that
1738              connects to the previous block. The H array is implicitly
1739              held because of the arc ordering, and the block's
1740              previous arc pointer.
1741
1742              Although the algorithm is O(N^3) for highly connected
1743              graphs, at worst we'll have O(N^2), as most blocks have
1744              only one or two exits. Most graphs will be small.
1745
1746              For each loop we find, locate the arc with the smallest
1747              transition count, and add that to the cumulative
1748              count.  Decrease flow over the cycle and remove the arc
1749              from consideration.  */
1750           for (block = line->u.blocks; block; block = block->chain)
1751             {
1752               block_t *head = block;
1753               arc_t *arc;
1754
1755             next_vertex:;
1756               arc = head->succ;
1757             current_vertex:;
1758               while (arc)
1759                 {
1760                   block_t *dst = arc->dst;
1761                   if (/* Already used that arc.  */
1762                       arc->cycle
1763                       /* Not to same graph, or before first vertex.  */
1764                       || dst->u.cycle.ident != ix
1765                       /* Already in path.  */
1766                       || dst->u.cycle.arc)
1767                     {
1768                       arc = arc->succ_next;
1769                       continue;
1770                     }
1771
1772                   if (dst == block)
1773                     {
1774                       /* Found a closing arc.  */
1775                       gcov_type cycle_count = arc->cs_count;
1776                       arc_t *cycle_arc = arc;
1777                       arc_t *probe_arc;
1778
1779                       /* Locate the smallest arc count of the loop.  */
1780                       for (dst = head; (probe_arc = dst->u.cycle.arc);
1781                            dst = probe_arc->src)
1782                         if (cycle_count > probe_arc->cs_count)
1783                           {
1784                             cycle_count = probe_arc->cs_count;
1785                             cycle_arc = probe_arc;
1786                           }
1787
1788                       count += cycle_count;
1789                       cycle_arc->cycle = 1;
1790
1791                       /* Remove the flow from the cycle.  */
1792                       arc->cs_count -= cycle_count;
1793                       for (dst = head; (probe_arc = dst->u.cycle.arc);
1794                            dst = probe_arc->src)
1795                         probe_arc->cs_count -= cycle_count;
1796
1797                       /* Unwind to the cyclic arc.  */
1798                       while (head != cycle_arc->src)
1799                         {
1800                           arc = head->u.cycle.arc;
1801                           head->u.cycle.arc = NULL;
1802                           head = arc->src;
1803                         }
1804                       /* Move on.  */
1805                       arc = arc->succ_next;
1806                       continue;
1807                     }
1808
1809                   /* Add new block to chain.  */
1810                   dst->u.cycle.arc = arc;
1811                   head = dst;
1812                   goto next_vertex;
1813                 }
1814               /* We could not add another vertex to the path. Remove
1815                  the last vertex from the list.  */
1816               arc = head->u.cycle.arc;
1817               if (arc)
1818                 {
1819                   /* It was not the first vertex. Move onto next arc.  */
1820                   head->u.cycle.arc = NULL;
1821                   head = arc->src;
1822                   arc = arc->succ_next;
1823                   goto current_vertex;
1824                 }
1825               /* Mark this block as unusable.  */
1826               block->u.cycle.ident = ~0U;
1827             }
1828
1829           line->count = count;
1830         }
1831
1832       if (line->exists)
1833         {
1834           src->coverage.lines++;
1835           if (line->count)
1836             src->coverage.lines_executed++;
1837         }
1838     }
1839 }
1840
1841 /* Output information about ARC number IX.  Returns nonzero if
1842    anything is output.  */
1843
1844 static int
1845 output_branch_count (FILE *gcov_file, int ix, const arc_t *arc)
1846 {
1847
1848   if (arc->is_call_non_return)
1849     {
1850       if (arc->src->count)
1851         {
1852           fnotice (gcov_file, "call   %2d returned %s\n", ix,
1853                    format_gcov (arc->src->count - arc->count,
1854                                 arc->src->count, -flag_counts));
1855         }
1856       else
1857         fnotice (gcov_file, "call   %2d never executed\n", ix);
1858     }
1859   else if (!arc->is_unconditional)
1860     {
1861       if (arc->src->count)
1862         fnotice (gcov_file, "branch %2d taken %s%s\n", ix,
1863                  format_gcov (arc->count, arc->src->count, -flag_counts),
1864                  arc->fall_through ? " (fallthrough)" : "");
1865       else
1866         fnotice (gcov_file, "branch %2d never executed\n", ix);
1867     }
1868   else if (flag_unconditional && !arc->dst->is_call_return)
1869     {
1870       if (arc->src->count)
1871         fnotice (gcov_file, "unconditional %2d taken %s\n", ix,
1872                  format_gcov (arc->count, arc->src->count, -flag_counts));
1873       else
1874         fnotice (gcov_file, "unconditional %2d never executed\n", ix);
1875     }
1876   else
1877     return 0;
1878   return 1;
1879
1880 }
1881
1882 /* Read in the source file one line at a time, and output that line to
1883    the gcov file preceded by its execution count and other
1884    information.  */
1885
1886 static void
1887 output_lines (FILE *gcov_file, const source_t *src)
1888 {
1889   FILE *source_file;
1890   unsigned line_num;    /* current line number.  */
1891   const line_t *line;           /* current line info ptr.  */
1892   char string[STRING_SIZE];     /* line buffer.  */
1893   char const *retval = "";      /* status of source file reading.  */
1894   function_t *fn = NULL;
1895
1896   fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->name);
1897   if (!multiple_files)
1898     {
1899       fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name);
1900       fprintf (gcov_file, "%9s:%5d:Data:%s\n", "-", 0,
1901                no_data_file ? "-" : da_file_name);
1902       fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0,
1903                object_summary.ctrs[GCOV_COUNTER_ARCS].runs);
1904     }
1905   fprintf (gcov_file, "%9s:%5d:Programs:%u\n", "-", 0, program_count);
1906
1907   source_file = fopen (src->name, "r");
1908   if (!source_file)
1909     {
1910       fnotice (stderr, "%s:cannot open source file\n", src->name);
1911       retval = NULL;
1912     }
1913   else if (src->file_time == 0)
1914     fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n", "-", 0);
1915
1916   if (flag_branches)
1917     fn = src->functions;
1918
1919   for (line_num = 1, line = &src->lines[line_num];
1920        line_num < src->num_lines; line_num++, line++)
1921     {
1922       for (; fn && fn->line == line_num; fn = fn->line_next)
1923         {
1924           arc_t *arc = fn->blocks[fn->num_blocks - 1].pred;
1925           gcov_type return_count = fn->blocks[fn->num_blocks - 1].count;
1926
1927           for (; arc; arc = arc->pred_next)
1928             if (arc->fake)
1929               return_count -= arc->count;
1930
1931           fprintf (gcov_file, "function %s", fn->name);
1932           fprintf (gcov_file, " called %s",
1933                    format_gcov (fn->blocks[0].count, 0, -1));
1934           fprintf (gcov_file, " returned %s",
1935                    format_gcov (return_count, fn->blocks[0].count, 0));
1936           fprintf (gcov_file, " blocks executed %s",
1937                    format_gcov (fn->blocks_executed, fn->num_blocks - 2, 0));
1938           fprintf (gcov_file, "\n");
1939         }
1940
1941       /* For lines which don't exist in the .bb file, print '-' before
1942          the source line.  For lines which exist but were never
1943          executed, print '#####' before the source line.  Otherwise,
1944          print the execution count before the source line.  There are
1945          16 spaces of indentation added before the source line so that
1946          tabs won't be messed up.  */
1947       fprintf (gcov_file, "%9s:%5u:",
1948                !line->exists ? "-" : !line->count ? "#####"
1949                : format_gcov (line->count, 0, -1), line_num);
1950
1951       if (retval)
1952         {
1953           /* Copy source line.  */
1954           do
1955             {
1956               retval = fgets (string, STRING_SIZE, source_file);
1957               if (!retval)
1958                 break;
1959               fputs (retval, gcov_file);
1960             }
1961           while (!retval[0] || retval[strlen (retval) - 1] != '\n');
1962         }
1963       if (!retval)
1964         fputs ("/*EOF*/\n", gcov_file);
1965
1966       if (flag_all_blocks)
1967         {
1968           block_t *block;
1969           arc_t *arc;
1970           int ix, jx;
1971
1972           for (ix = jx = 0, block = line->u.blocks; block;
1973                block = block->chain)
1974             {
1975               if (!block->is_call_return)
1976                 fprintf (gcov_file, "%9s:%5u-block %2d\n",
1977                          !line->exists ? "-" : !block->count ? "$$$$$"
1978                          : format_gcov (block->count, 0, -1),
1979                          line_num, ix++);
1980               if (flag_branches)
1981                 for (arc = block->succ; arc; arc = arc->succ_next)
1982                   jx += output_branch_count (gcov_file, jx, arc);
1983             }
1984         }
1985       else if (flag_branches)
1986         {
1987           int ix;
1988           arc_t *arc;
1989
1990           for (ix = 0, arc = line->u.branches; arc; arc = arc->line_next)
1991             ix += output_branch_count (gcov_file, ix, arc);
1992         }
1993     }
1994
1995   /* Handle all remaining source lines.  There may be lines after the
1996      last line of code.  */
1997   if (retval)
1998     {
1999       for (; (retval = fgets (string, STRING_SIZE, source_file)); line_num++)
2000         {
2001           fprintf (gcov_file, "%9s:%5u:%s", "-", line_num, retval);
2002
2003           while (!retval[0] || retval[strlen (retval) - 1] != '\n')
2004             {
2005               retval = fgets (string, STRING_SIZE, source_file);
2006               if (!retval)
2007                 break;
2008               fputs (retval, gcov_file);
2009             }
2010         }
2011     }
2012
2013   if (source_file)
2014     fclose (source_file);
2015 }