OSDN Git Service

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