OSDN Git Service

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