OSDN Git Service

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