OSDN Git Service

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