OSDN Git Service

2010-09-24 Tobias Burnus <burnus@net-b.de>
[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
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 2010 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 (!strcmp (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 (*pold == '/' || *pold == '\\')
1539             {
1540               *pnew++ = '#';
1541               pold++;
1542             }
1543 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
1544           else if (*pold == ':')
1545             {
1546               *pnew++ = '~';
1547               pold++;
1548             }
1549 #endif
1550           else if ((*pold == '/' && strstr (pold, "/./") == pold)
1551                    || (*pold == '\\' && strstr (pold, "\\.\\") == pold))
1552               pold += 3;
1553           else if (*pold == '/' && strstr (pold, "/../") == pold)
1554             {
1555               strcpy (pnew, "/^/");
1556               pnew += 3;
1557               pold += 4;
1558             }
1559           else if (*pold == '\\' && strstr (pold, "\\..\\") == pold)
1560             {
1561               strcpy (pnew, "\\^\\");
1562               pnew += 3;
1563               pold += 4;
1564             }
1565           else
1566             *pnew++ = *pold++;
1567         }
1568
1569       *pnew = '\0';
1570     }
1571
1572   strcat (name, ".gcov");
1573   return name;
1574 }
1575
1576 /* Scan through the bb_data for each line in the block, increment
1577    the line number execution count indicated by the execution count of
1578    the appropriate basic block.  */
1579
1580 static void
1581 add_line_counts (coverage_t *coverage, function_t *fn)
1582 {
1583   unsigned ix;
1584   line_t *line = NULL; /* This is propagated from one iteration to the
1585                           next.  */
1586
1587   /* Scan each basic block.  */
1588   for (ix = 0; ix != fn->num_blocks; ix++)
1589     {
1590       block_t *block = &fn->blocks[ix];
1591       unsigned *encoding;
1592       const source_t *src = NULL;
1593       unsigned jx;
1594
1595       if (block->count && ix && ix + 1 != fn->num_blocks)
1596         fn->blocks_executed++;
1597       for (jx = 0, encoding = block->u.line.encoding;
1598            jx != block->u.line.num; jx++, encoding++)
1599         if (!*encoding)
1600           {
1601             unsigned src_n = *++encoding;
1602
1603             for (src = sources; src->index != src_n; src = src->next)
1604               continue;
1605             jx++;
1606           }
1607         else
1608           {
1609             line = &src->lines[*encoding];
1610
1611             if (coverage)
1612               {
1613                 if (!line->exists)
1614                   coverage->lines++;
1615                 if (!line->count && block->count)
1616                   coverage->lines_executed++;
1617               }
1618             line->exists = 1;
1619             line->count += block->count;
1620           }
1621       free (block->u.line.encoding);
1622       block->u.cycle.arc = NULL;
1623       block->u.cycle.ident = ~0U;
1624
1625       if (!ix || ix + 1 == fn->num_blocks)
1626         /* Entry or exit block */;
1627       else if (flag_all_blocks)
1628         {
1629           line_t *block_line = line ? line : &fn->src->lines[fn->line];
1630
1631           block->chain = block_line->u.blocks;
1632           block_line->u.blocks = block;
1633         }
1634       else if (flag_branches)
1635         {
1636           arc_t *arc;
1637
1638           for (arc = block->succ; arc; arc = arc->succ_next)
1639             {
1640               arc->line_next = line->u.branches;
1641               line->u.branches = arc;
1642               if (coverage && !arc->is_unconditional)
1643                 add_branch_counts (coverage, arc);
1644             }
1645         }
1646     }
1647   if (!line)
1648     fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name, fn->name);
1649 }
1650
1651 /* Accumulate the line counts of a file.  */
1652
1653 static void
1654 accumulate_line_counts (source_t *src)
1655 {
1656   line_t *line;
1657   function_t *fn, *fn_p, *fn_n;
1658   unsigned ix;
1659
1660   /* Reverse the function order.  */
1661   for (fn = src->functions, fn_p = NULL; fn;
1662        fn_p = fn, fn = fn_n)
1663     {
1664       fn_n = fn->line_next;
1665       fn->line_next = fn_p;
1666     }
1667   src->functions = fn_p;
1668
1669   for (ix = src->num_lines, line = src->lines; ix--; line++)
1670     {
1671       if (!flag_all_blocks)
1672         {
1673           arc_t *arc, *arc_p, *arc_n;
1674
1675           /* Total and reverse the branch information.  */
1676           for (arc = line->u.branches, arc_p = NULL; arc;
1677                arc_p = arc, arc = arc_n)
1678             {
1679               arc_n = arc->line_next;
1680               arc->line_next = arc_p;
1681
1682               add_branch_counts (&src->coverage, arc);
1683             }
1684           line->u.branches = arc_p;
1685         }
1686       else if (line->u.blocks)
1687         {
1688           /* The user expects the line count to be the number of times
1689              a line has been executed. Simply summing the block count
1690              will give an artificially high number.  The Right Thing
1691              is to sum the entry counts to the graph of blocks on this
1692              line, then find the elementary cycles of the local graph
1693              and add the transition counts of those cycles.  */
1694           block_t *block, *block_p, *block_n;
1695           gcov_type count = 0;
1696
1697           /* Reverse the block information.  */
1698           for (block = line->u.blocks, block_p = NULL; block;
1699                block_p = block, block = block_n)
1700             {
1701               block_n = block->chain;
1702               block->chain = block_p;
1703               block->u.cycle.ident = ix;
1704             }
1705           line->u.blocks = block_p;
1706
1707           /* Sum the entry arcs.  */
1708           for (block = line->u.blocks; block; block = block->chain)
1709             {
1710               arc_t *arc;
1711
1712               for (arc = block->pred; arc; arc = arc->pred_next)
1713                 {
1714                   if (arc->src->u.cycle.ident != ix)
1715                     count += arc->count;
1716                   if (flag_branches)
1717                     add_branch_counts (&src->coverage, arc);
1718                 }
1719
1720               /* Initialize the cs_count.  */
1721               for (arc = block->succ; arc; arc = arc->succ_next)
1722                 arc->cs_count = arc->count;
1723             }
1724
1725           /* Find the loops. This uses the algorithm described in
1726              Tiernan 'An Efficient Search Algorithm to Find the
1727              Elementary Circuits of a Graph', CACM Dec 1970. We hold
1728              the P array by having each block point to the arc that
1729              connects to the previous block. The H array is implicitly
1730              held because of the arc ordering, and the block's
1731              previous arc pointer.
1732
1733              Although the algorithm is O(N^3) for highly connected
1734              graphs, at worst we'll have O(N^2), as most blocks have
1735              only one or two exits. Most graphs will be small.
1736
1737              For each loop we find, locate the arc with the smallest
1738              transition count, and add that to the cumulative
1739              count.  Decrease flow over the cycle and remove the arc
1740              from consideration.  */
1741           for (block = line->u.blocks; block; block = block->chain)
1742             {
1743               block_t *head = block;
1744               arc_t *arc;
1745
1746             next_vertex:;
1747               arc = head->succ;
1748             current_vertex:;
1749               while (arc)
1750                 {
1751                   block_t *dst = arc->dst;
1752                   if (/* Already used that arc.  */
1753                       arc->cycle
1754                       /* Not to same graph, or before first vertex.  */
1755                       || dst->u.cycle.ident != ix
1756                       /* Already in path.  */
1757                       || dst->u.cycle.arc)
1758                     {
1759                       arc = arc->succ_next;
1760                       continue;
1761                     }
1762
1763                   if (dst == block)
1764                     {
1765                       /* Found a closing arc.  */
1766                       gcov_type cycle_count = arc->cs_count;
1767                       arc_t *cycle_arc = arc;
1768                       arc_t *probe_arc;
1769
1770                       /* Locate the smallest arc count of the loop.  */
1771                       for (dst = head; (probe_arc = dst->u.cycle.arc);
1772                            dst = probe_arc->src)
1773                         if (cycle_count > probe_arc->cs_count)
1774                           {
1775                             cycle_count = probe_arc->cs_count;
1776                             cycle_arc = probe_arc;
1777                           }
1778
1779                       count += cycle_count;
1780                       cycle_arc->cycle = 1;
1781
1782                       /* Remove the flow from the cycle.  */
1783                       arc->cs_count -= cycle_count;
1784                       for (dst = head; (probe_arc = dst->u.cycle.arc);
1785                            dst = probe_arc->src)
1786                         probe_arc->cs_count -= cycle_count;
1787
1788                       /* Unwind to the cyclic arc.  */
1789                       while (head != cycle_arc->src)
1790                         {
1791                           arc = head->u.cycle.arc;
1792                           head->u.cycle.arc = NULL;
1793                           head = arc->src;
1794                         }
1795                       /* Move on.  */
1796                       arc = arc->succ_next;
1797                       continue;
1798                     }
1799
1800                   /* Add new block to chain.  */
1801                   dst->u.cycle.arc = arc;
1802                   head = dst;
1803                   goto next_vertex;
1804                 }
1805               /* We could not add another vertex to the path. Remove
1806                  the last vertex from the list.  */
1807               arc = head->u.cycle.arc;
1808               if (arc)
1809                 {
1810                   /* It was not the first vertex. Move onto next arc.  */
1811                   head->u.cycle.arc = NULL;
1812                   head = arc->src;
1813                   arc = arc->succ_next;
1814                   goto current_vertex;
1815                 }
1816               /* Mark this block as unusable.  */
1817               block->u.cycle.ident = ~0U;
1818             }
1819
1820           line->count = count;
1821         }
1822
1823       if (line->exists)
1824         {
1825           src->coverage.lines++;
1826           if (line->count)
1827             src->coverage.lines_executed++;
1828         }
1829     }
1830 }
1831
1832 /* Output information about ARC number IX.  Returns nonzero if
1833    anything is output.  */
1834
1835 static int
1836 output_branch_count (FILE *gcov_file, int ix, const arc_t *arc)
1837 {
1838
1839   if (arc->is_call_non_return)
1840     {
1841       if (arc->src->count)
1842         {
1843           fnotice (gcov_file, "call   %2d returned %s\n", ix,
1844                    format_gcov (arc->src->count - arc->count,
1845                                 arc->src->count, -flag_counts));
1846         }
1847       else
1848         fnotice (gcov_file, "call   %2d never executed\n", ix);
1849     }
1850   else if (!arc->is_unconditional)
1851     {
1852       if (arc->src->count)
1853         fnotice (gcov_file, "branch %2d taken %s%s\n", ix,
1854                  format_gcov (arc->count, arc->src->count, -flag_counts),
1855                  arc->fall_through ? " (fallthrough)" : "");
1856       else
1857         fnotice (gcov_file, "branch %2d never executed\n", ix);
1858     }
1859   else if (flag_unconditional && !arc->dst->is_call_return)
1860     {
1861       if (arc->src->count)
1862         fnotice (gcov_file, "unconditional %2d taken %s\n", ix,
1863                  format_gcov (arc->count, arc->src->count, -flag_counts));
1864       else
1865         fnotice (gcov_file, "unconditional %2d never executed\n", ix);
1866     }
1867   else
1868     return 0;
1869   return 1;
1870
1871 }
1872
1873 /* Read in the source file one line at a time, and output that line to
1874    the gcov file preceded by its execution count and other
1875    information.  */
1876
1877 static void
1878 output_lines (FILE *gcov_file, const source_t *src)
1879 {
1880   FILE *source_file;
1881   unsigned line_num;    /* current line number.  */
1882   const line_t *line;           /* current line info ptr.  */
1883   char string[STRING_SIZE];     /* line buffer.  */
1884   char const *retval = "";      /* status of source file reading.  */
1885   function_t *fn = NULL;
1886
1887   fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->name);
1888   if (!multiple_files)
1889     {
1890       fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name);
1891       fprintf (gcov_file, "%9s:%5d:Data:%s\n", "-", 0,
1892                no_data_file ? "-" : da_file_name);
1893       fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0,
1894                object_summary.ctrs[GCOV_COUNTER_ARCS].runs);
1895     }
1896   fprintf (gcov_file, "%9s:%5d:Programs:%u\n", "-", 0, program_count);
1897
1898   source_file = fopen (src->name, "r");
1899   if (!source_file)
1900     {
1901       fnotice (stderr, "%s:cannot open source file\n", src->name);
1902       retval = NULL;
1903     }
1904   else if (src->file_time == 0)
1905     fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n", "-", 0);
1906
1907   if (flag_branches)
1908     fn = src->functions;
1909
1910   for (line_num = 1, line = &src->lines[line_num];
1911        line_num < src->num_lines; line_num++, line++)
1912     {
1913       for (; fn && fn->line == line_num; fn = fn->line_next)
1914         {
1915           arc_t *arc = fn->blocks[fn->num_blocks - 1].pred;
1916           gcov_type return_count = fn->blocks[fn->num_blocks - 1].count;
1917
1918           for (; arc; arc = arc->pred_next)
1919             if (arc->fake)
1920               return_count -= arc->count;
1921
1922           fprintf (gcov_file, "function %s", fn->name);
1923           fprintf (gcov_file, " called %s",
1924                    format_gcov (fn->blocks[0].count, 0, -1));
1925           fprintf (gcov_file, " returned %s",
1926                    format_gcov (return_count, fn->blocks[0].count, 0));
1927           fprintf (gcov_file, " blocks executed %s",
1928                    format_gcov (fn->blocks_executed, fn->num_blocks - 2, 0));
1929           fprintf (gcov_file, "\n");
1930         }
1931
1932       /* For lines which don't exist in the .bb file, print '-' before
1933          the source line.  For lines which exist but were never
1934          executed, print '#####' before the source line.  Otherwise,
1935          print the execution count before the source line.  There are
1936          16 spaces of indentation added before the source line so that
1937          tabs won't be messed up.  */
1938       fprintf (gcov_file, "%9s:%5u:",
1939                !line->exists ? "-" : !line->count ? "#####"
1940                : format_gcov (line->count, 0, -1), line_num);
1941
1942       if (retval)
1943         {
1944           /* Copy source line.  */
1945           do
1946             {
1947               retval = fgets (string, STRING_SIZE, source_file);
1948               if (!retval)
1949                 break;
1950               fputs (retval, gcov_file);
1951             }
1952           while (!retval[0] || retval[strlen (retval) - 1] != '\n');
1953         }
1954       if (!retval)
1955         fputs ("/*EOF*/\n", gcov_file);
1956
1957       if (flag_all_blocks)
1958         {
1959           block_t *block;
1960           arc_t *arc;
1961           int ix, jx;
1962
1963           for (ix = jx = 0, block = line->u.blocks; block;
1964                block = block->chain)
1965             {
1966               if (!block->is_call_return)
1967                 fprintf (gcov_file, "%9s:%5u-block %2d\n",
1968                          !line->exists ? "-" : !block->count ? "$$$$$"
1969                          : format_gcov (block->count, 0, -1),
1970                          line_num, ix++);
1971               if (flag_branches)
1972                 for (arc = block->succ; arc; arc = arc->succ_next)
1973                   jx += output_branch_count (gcov_file, jx, arc);
1974             }
1975         }
1976       else if (flag_branches)
1977         {
1978           int ix;
1979           arc_t *arc;
1980
1981           for (ix = 0, arc = line->u.branches; arc; arc = arc->line_next)
1982             ix += output_branch_count (gcov_file, ix, arc);
1983         }
1984     }
1985
1986   /* Handle all remaining source lines.  There may be lines after the
1987      last line of code.  */
1988   if (retval)
1989     {
1990       for (; (retval = fgets (string, STRING_SIZE, source_file)); line_num++)
1991         {
1992           fprintf (gcov_file, "%9s:%5u:%s", "-", line_num, retval);
1993
1994           while (!retval[0] || retval[strlen (retval) - 1] != '\n')
1995             {
1996               retval = fgets (string, STRING_SIZE, source_file);
1997               if (!retval)
1998                 break;
1999               fputs (retval, gcov_file);
2000             }
2001         }
2002     }
2003
2004   if (source_file)
2005     fclose (source_file);
2006 }