OSDN Git Service

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