Do not do src->dest copy if register would not be allocated a normal register
[official-gcc.git] / gcc / gcov.c
blobc546bdce7b733dcdffe9b4244f43c64a37ae12b0
1 /* Gcov.c: prepend line execution counts and branch probabilities to a
2 source file.
3 Copyright (C) 1990, 91, 92, 93, 94, 96, 1997 Free Software Foundation, Inc.
4 Contributed by James E. Wilson of Cygnus Support.
5 Mangled by Bob Manson of Cygnus Support.
7 Gcov is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 Gcov is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Gcov; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* ??? The code in final.c that produces the struct bb assumes that there is
22 no padding between the fields. This is not necessary true. The current
23 code can only be trusted if longs and pointers are the same size. */
25 /* ??? No need to print an execution count on every line, could just print
26 it on the first line of each block, and only print it on a subsequent
27 line in the same block if the count changes. */
29 /* ??? Print a list of the ten blocks with the highest execution counts,
30 and list the line numbers corresponding to those blocks. Also, perhaps
31 list the line numbers with the highest execution counts, only printing
32 the first if there are several which are all listed in the same block. */
34 /* ??? Should have an option to print the number of basic blocks, and the
35 percent of them that are covered. */
37 /* ??? Does not correctly handle the case where two .bb files refer to the
38 same included source file. For example, if one has a short file containing
39 only inline functions, which is then included in two other files, then
40 there will be two .bb files which refer to the include file, but there
41 is no way to get the total execution counts for the included file, can
42 only get execution counts for one or the other of the including files. */
44 #include "config.h"
45 #include "system.h"
46 #include <sys/stat.h>
47 #include "gansidecl.h"
49 #include "gcov-io.h"
51 /* The .bb file format consists of several lists of 4-byte integers
52 which are the line numbers of each basic block in the file. Each
53 list is terminated by a zero. These lists correspond to the basic
54 blocks in the reconstructed program flow graph.
56 A line number of -1 indicates that a source file name (padded to a
57 long boundary) follows. The padded file name is followed by
58 another -1 to make it easy to scan past file names. A -2 indicates
59 that a function name (padded to a long boundary) follows; the name
60 is followed by another -2 to make it easy to scan past the function
61 name.
63 The .bbg file contains enough info to enable gcov to reconstruct the
64 program flow graph. The first word is the number of basic blocks,
65 the second word is the number of arcs, followed by the list of arcs
66 (source bb, dest bb pairs), then a -1, then the number of instrumented
67 arcs followed by the instrumented arcs, followed by another -1. This
68 is repeated for each function.
70 The .da file contains the execution count for each instrumented branch.
72 The .bb and .bbg files are created by giving GCC the -ftest-coverage option,
73 and the .da files are created when an executable compiled with
74 -fprofile-arcs is run. */
76 /* The functions in this file for creating and solution program flow graphs
77 are very similar to functions in the gcc source file profile.c. */
79 char gcov_version_string[] = "GNU gcov version 1.5\n";
81 /* This is the size of the buffer used to read in source file lines. */
83 #define STRING_SIZE 200
85 /* One copy of this structure is created for each source file mentioned in the
86 .bb file. */
88 struct sourcefile
90 char *name;
91 int maxlineno;
92 struct sourcefile *next;
95 /* This points to the head of the sourcefile structure list. */
97 struct sourcefile *sources;
99 /* One of these is dynamically created whenever we identify an arc in the
100 function. */
102 struct adj_list {
103 int source;
104 int target;
105 int arc_count;
106 unsigned int count_valid : 1;
107 unsigned int on_tree : 1;
108 unsigned int fake : 1;
109 unsigned int fall_through : 1;
110 #if 0
111 /* Not needed for gcov, but defined in profile.c. */
112 rtx branch_insn;
113 #endif
114 struct adj_list *pred_next;
115 struct adj_list *succ_next;
118 /* Count the number of basic blocks, and create an array of these structures,
119 one for each bb in the function. */
121 struct bb_info {
122 struct adj_list *succ;
123 struct adj_list *pred;
124 int succ_count;
125 int pred_count;
126 int exec_count;
127 unsigned int count_valid : 1;
128 unsigned int on_tree : 1;
129 #if 0
130 /* Not needed for gcov, but defined in profile.c. */
131 rtx first_insn;
132 #endif
135 /* When outputting branch probabilities, one of these structures is created
136 for each branch/call. */
138 struct arcdata
140 int prob;
141 int call_insn;
142 struct arcdata *next;
145 /* Used to save the list of bb_graphs, one per function. */
147 struct bb_info_list {
148 /* Indexed by block number, holds the basic block graph for one function. */
149 struct bb_info *bb_graph;
150 int num_blocks;
151 struct bb_info_list *next;
154 /* Holds a list of function basic block graphs. */
156 static struct bb_info_list *bb_graph_list = 0;
158 /* Name and file pointer of the input file for the basic block graph. */
160 static char *bbg_file_name;
161 static FILE *bbg_file;
163 /* Name and file pointer of the input file for the arc count data. */
165 static char *da_file_name;
166 static FILE *da_file;
168 /* Name and file pointer of the input file for the basic block line counts. */
170 static char *bb_file_name;
171 static FILE *bb_file;
173 /* Holds the entire contents of the bb_file read into memory. */
175 static char *bb_data;
177 /* Size of bb_data array in longs. */
179 static long bb_data_size;
181 /* Name and file pointer of the output file. */
183 static char *gcov_file_name;
184 static FILE *gcov_file;
186 /* Name of the file mentioned on the command line. */
188 static char *input_file_name = 0;
190 /* Output branch probabilities if true. */
192 static int output_branch_probs = 0;
194 /* Output a gcov file if this is true. This is on by default, and can
195 be turned off by the -n option. */
197 static int output_gcov_file = 1;
199 /* For included files, make the gcov output file name include the name of
200 the input source file. For example, if x.h is included in a.c, then the
201 output file name is a.c.x.h.gcov instead of x.h.gcov. This works only
202 when a single source file is specified. */
204 static int output_long_names = 0;
206 /* Output summary info for each function. */
208 static int output_function_summary = 0;
210 /* Object directory file prefix. This is the directory where .bb and .bbg
211 files are looked for, if non-zero. */
213 static char *object_directory = 0;
215 /* Forward declarations. */
216 static void process_args PROTO ((int, char **));
217 static void open_files PROTO ((void));
218 static void read_files PROTO ((void));
219 static void scan_for_source_files PROTO ((void));
220 static void output_data PROTO ((void));
221 char * xmalloc ();
224 main (argc, argv)
225 int argc;
226 char **argv;
228 process_args (argc, argv);
230 open_files ();
232 read_files ();
234 scan_for_source_files ();
236 output_data ();
238 return 0;
241 char *
242 xmalloc (size)
243 unsigned size;
245 register char *value = (char *) malloc (size);
246 if (value == 0)
248 fprintf (stderr, "error: virtual memory exhausted");
249 exit (FATAL_EXIT_CODE);
251 return value;
254 /* More 'friendly' abort that prints the line and file.
255 config.h can #define abort fancy_abort if you like that sort of thing. */
257 void
258 fancy_abort ()
260 fprintf (stderr, "Internal gcc abort.\n");
261 exit (FATAL_EXIT_CODE);
264 /* Print a usage message and exit. */
266 static void
267 print_usage ()
269 fprintf (stderr, "gcov [-b] [-v] [-n] [-l] [-f] [-o OBJDIR] file\n");
270 exit (FATAL_EXIT_CODE);
273 /* Parse the command line. */
275 static void
276 process_args (argc, argv)
277 int argc;
278 char **argv;
280 int i;
282 for (i = 1; i < argc; i++)
284 if (argv[i][0] == '-')
286 if (argv[i][1] == 'b')
287 output_branch_probs = 1;
288 else if (argv[i][1] == 'v')
289 fputs (gcov_version_string, stderr);
290 else if (argv[i][1] == 'n')
291 output_gcov_file = 0;
292 else if (argv[i][1] == 'l')
293 output_long_names = 1;
294 else if (argv[i][1] == 'f')
295 output_function_summary = 1;
296 else if (argv[i][1] == 'o' && argv[i][2] == '\0')
297 object_directory = argv[++i];
298 else
299 print_usage ();
301 else if (! input_file_name)
302 input_file_name = argv[i];
303 else
304 print_usage ();
307 if (! input_file_name)
308 print_usage ();
312 /* Find and open the .bb, .da, and .bbg files. */
314 static void
315 open_files ()
317 int count, objdir_count;
318 char *cptr;
320 /* Determine the names of the .bb, .bbg, and .da files. Strip off the
321 extension, if any, and append the new extensions. */
322 count = strlen (input_file_name);
323 if (object_directory)
324 objdir_count = strlen (object_directory);
325 else
326 objdir_count = 0;
328 da_file_name = xmalloc (count + objdir_count + 4);
329 bb_file_name = xmalloc (count + objdir_count + 4);
330 bbg_file_name = xmalloc (count + objdir_count + 5);
332 if (object_directory)
334 strcpy (da_file_name, object_directory);
335 strcpy (bb_file_name, object_directory);
336 strcpy (bbg_file_name, object_directory);
338 if (object_directory[objdir_count - 1] != '/')
340 strcat (da_file_name, "/");
341 strcat (bb_file_name, "/");
342 strcat (bbg_file_name, "/");
345 cptr = rindex (input_file_name, '/');
346 if (cptr)
348 strcat (da_file_name, cptr + 1);
349 strcat (bb_file_name, cptr + 1);
350 strcat (bbg_file_name, cptr + 1);
352 else
354 strcat (da_file_name, input_file_name);
355 strcat (bb_file_name, input_file_name);
356 strcat (bbg_file_name, input_file_name);
359 else
361 strcpy (da_file_name, input_file_name);
362 strcpy (bb_file_name, input_file_name);
363 strcpy (bbg_file_name, input_file_name);
366 cptr = rindex (bb_file_name, '.');
367 if (cptr)
368 strcpy (cptr, ".bb");
369 else
370 strcat (bb_file_name, ".bb");
372 cptr = rindex (da_file_name, '.');
373 if (cptr)
374 strcpy (cptr, ".da");
375 else
376 strcat (da_file_name, ".da");
378 cptr = rindex (bbg_file_name, '.');
379 if (cptr)
380 strcpy (cptr, ".bbg");
381 else
382 strcat (bbg_file_name, ".bbg");
384 bb_file = fopen (bb_file_name, "r");
385 if (bb_file == NULL)
387 fprintf (stderr, "Could not open basic block file %s.\n", bb_file_name);
388 exit (FATAL_EXIT_CODE);
391 /* If none of the functions in the file were executed, then there won't
392 be a .da file. Just assume that all counts are zero in this case. */
393 da_file = fopen (da_file_name, "r");
394 if (da_file == NULL)
396 fprintf (stderr, "Could not open data file %s.\n", da_file_name);
397 fprintf (stderr, "Assuming that all execution counts are zero.\n");
400 bbg_file = fopen (bbg_file_name, "r");
401 if (bbg_file == NULL)
403 fprintf (stderr, "Could not open program flow graph file %s.\n",
404 bbg_file_name);
405 exit (FATAL_EXIT_CODE);
408 /* Check for empty .bbg file. This indicates that there is no executable
409 code in this source file. */
410 /* Set the EOF condition if at the end of file. */
411 ungetc (getc (bbg_file), bbg_file);
412 if (feof (bbg_file))
414 fprintf (stderr, "No executable code associated with file %s.\n",
415 input_file_name);
416 exit (FATAL_EXIT_CODE);
420 /* Initialize a new arc. */
422 static void
423 init_arc (arcptr, source, target, bb_graph)
424 struct adj_list *arcptr;
425 int source, target;
426 struct bb_info *bb_graph;
428 arcptr->target = target;
429 arcptr->source = source;
431 arcptr->arc_count = 0;
432 arcptr->count_valid = 0;
433 arcptr->on_tree = 0;
434 arcptr->fake = 0;
435 arcptr->fall_through = 0;
437 arcptr->succ_next = bb_graph[source].succ;
438 bb_graph[source].succ = arcptr;
439 bb_graph[source].succ_count++;
441 arcptr->pred_next = bb_graph[target].pred;
442 bb_graph[target].pred = arcptr;
443 bb_graph[target].pred_count++;
447 /* Reverse the arcs on a arc list. */
449 static struct adj_list *
450 reverse_arcs (arcptr)
451 struct adj_list *arcptr;
453 struct adj_list *prev = 0;
454 struct adj_list *next;
456 for ( ; arcptr; arcptr = next)
458 next = arcptr->succ_next;
459 arcptr->succ_next = prev;
460 prev = arcptr;
463 return prev;
467 /* Construct the program flow graph from the .bbg file, and read in the data
468 in the .da file. */
470 static void
471 create_program_flow_graph (bptr)
472 struct bb_info_list *bptr;
474 long num_blocks, number_arcs, src, dest, flag_bits, num_arcs_per_block;
475 int i;
476 struct adj_list *arcptr;
477 struct bb_info *bb_graph;
479 /* Read the number of blocks. */
480 __read_long (&num_blocks, bbg_file, 4);
482 /* Create an array of size bb number of bb_info structs. Bzero it. */
483 bb_graph = (struct bb_info *) xmalloc (num_blocks
484 * sizeof (struct bb_info));
485 bzero ((char *) bb_graph, sizeof (struct bb_info) * num_blocks);
487 bptr->bb_graph = bb_graph;
488 bptr->num_blocks = num_blocks;
490 /* Read and create each arc from the .bbg file. */
491 __read_long (&number_arcs, bbg_file, 4);
492 for (i = 0; i < num_blocks; i++)
494 int j;
496 __read_long (&num_arcs_per_block, bbg_file, 4);
497 for (j = 0; j < num_arcs_per_block; j++)
499 if (number_arcs-- < 0)
500 abort ();
502 src = i;
503 __read_long (&dest, bbg_file, 4);
505 arcptr = (struct adj_list *) xmalloc (sizeof (struct adj_list));
506 init_arc (arcptr, src, dest, bb_graph);
508 __read_long (&flag_bits, bbg_file, 4);
509 arcptr->on_tree = flag_bits & 0x1;
510 arcptr->fake = !! (flag_bits & 0x2);
511 arcptr->fall_through = !! (flag_bits & 0x4);
515 if (number_arcs)
516 abort ();
518 /* Read and ignore the -1 separating the arc list from the arc list of the
519 next function. */
520 __read_long (&src, bbg_file, 4);
521 if (src != -1)
522 abort ();
524 /* Must reverse the order of all succ arcs, to ensure that they match
525 the order of the data in the .da file. */
527 for (i = 0; i < num_blocks; i++)
528 if (bb_graph[i].succ)
529 bb_graph[i].succ = reverse_arcs (bb_graph[i].succ);
531 /* For each arc not on the spanning tree, set its execution count from
532 the .da file. */
534 /* The first count in the .da file is the number of times that the function
535 was entered. This is the exec_count for block zero. */
537 /* This duplicates code in branch_prob in profile.c. */
539 for (i = 0; i < num_blocks; i++)
540 for (arcptr = bb_graph[i].succ; arcptr; arcptr = arcptr->succ_next)
541 if (! arcptr->on_tree)
543 long tmp_count = 0;;
544 if (da_file && __read_long (&tmp_count, da_file, 8))
545 abort();
547 arcptr->arc_count = tmp_count;
548 arcptr->count_valid = 1;
549 bb_graph[i].succ_count--;
550 bb_graph[arcptr->target].pred_count--;
554 static void
555 solve_program_flow_graph (bptr)
556 struct bb_info_list *bptr;
558 int passes, changes, total;
559 int i;
560 struct adj_list *arcptr;
561 struct bb_info *bb_graph;
562 int num_blocks;
564 num_blocks = bptr->num_blocks;
565 bb_graph = bptr->bb_graph;
567 /* For every block in the file,
568 - if every exit/entrance arc has a known count, then set the block count
569 - if the block count is known, and every exit/entrance arc but one has
570 a known execution count, then set the count of the remaining arc
572 As arc counts are set, decrement the succ/pred count, but don't delete
573 the arc, that way we can easily tell when all arcs are known, or only
574 one arc is unknown. */
576 /* The order that the basic blocks are iterated through is important.
577 Since the code that finds spanning trees starts with block 0, low numbered
578 arcs are put on the spanning tree in preference to high numbered arcs.
579 Hence, most instrumented arcs are at the end. Graph solving works much
580 faster if we propagate numbers from the end to the start.
582 This takes an average of slightly more than 3 passes. */
584 changes = 1;
585 passes = 0;
586 while (changes)
588 passes++;
589 changes = 0;
591 for (i = num_blocks - 1; i >= 0; i--)
593 if (! bb_graph[i].count_valid)
595 if (bb_graph[i].succ_count == 0)
597 total = 0;
598 for (arcptr = bb_graph[i].succ; arcptr;
599 arcptr = arcptr->succ_next)
600 total += arcptr->arc_count;
601 bb_graph[i].exec_count = total;
602 bb_graph[i].count_valid = 1;
603 changes = 1;
605 else if (bb_graph[i].pred_count == 0)
607 total = 0;
608 for (arcptr = bb_graph[i].pred; arcptr;
609 arcptr = arcptr->pred_next)
610 total += arcptr->arc_count;
611 bb_graph[i].exec_count = total;
612 bb_graph[i].count_valid = 1;
613 changes = 1;
616 if (bb_graph[i].count_valid)
618 if (bb_graph[i].succ_count == 1)
620 total = 0;
621 /* One of the counts will be invalid, but it is zero,
622 so adding it in also doesn't hurt. */
623 for (arcptr = bb_graph[i].succ; arcptr;
624 arcptr = arcptr->succ_next)
625 total += arcptr->arc_count;
626 /* Calculate count for remaining arc by conservation. */
627 total = bb_graph[i].exec_count - total;
628 /* Search for the invalid arc, and set its count. */
629 for (arcptr = bb_graph[i].succ; arcptr;
630 arcptr = arcptr->succ_next)
631 if (! arcptr->count_valid)
632 break;
633 if (! arcptr)
634 abort ();
635 arcptr->count_valid = 1;
636 arcptr->arc_count = total;
637 bb_graph[i].succ_count--;
639 bb_graph[arcptr->target].pred_count--;
640 changes = 1;
642 if (bb_graph[i].pred_count == 1)
644 total = 0;
645 /* One of the counts will be invalid, but it is zero,
646 so adding it in also doesn't hurt. */
647 for (arcptr = bb_graph[i].pred; arcptr;
648 arcptr = arcptr->pred_next)
649 total += arcptr->arc_count;
650 /* Calculate count for remaining arc by conservation. */
651 total = bb_graph[i].exec_count - total;
652 /* Search for the invalid arc, and set its count. */
653 for (arcptr = bb_graph[i].pred; arcptr;
654 arcptr = arcptr->pred_next)
655 if (! arcptr->count_valid)
656 break;
657 if (! arcptr)
658 abort ();
659 arcptr->count_valid = 1;
660 arcptr->arc_count = total;
661 bb_graph[i].pred_count--;
663 bb_graph[arcptr->source].succ_count--;
664 changes = 1;
670 /* If the graph has been correctly solved, every block will have a
671 succ and pred count of zero. */
672 for (i = 0; i < num_blocks; i++)
673 if (bb_graph[i].succ_count || bb_graph[i].pred_count)
674 abort ();
678 static void
679 read_files ()
681 struct stat buf;
682 struct bb_info_list *list_end = 0;
683 struct bb_info_list *b_ptr;
684 long total;
686 /* Read and ignore the first word of the .da file, which is the count of
687 how many numbers follow. */
688 if (da_file && __read_long (&total, da_file, 8))
689 abort();
691 while (! feof (bbg_file))
693 b_ptr = (struct bb_info_list *) xmalloc (sizeof (struct bb_info_list));
695 b_ptr->next = 0;
696 if (list_end)
697 list_end->next = b_ptr;
698 else
699 bb_graph_list = b_ptr;
700 list_end = b_ptr;
702 /* Read in the data in the .bbg file and reconstruct the program flow
703 graph for one function. */
704 create_program_flow_graph (b_ptr);
706 /* Set the EOF condition if at the end of file. */
707 ungetc (getc (bbg_file), bbg_file);
710 /* Check to make sure the .da file data is valid. */
712 if (da_file)
714 if (feof (da_file))
715 fprintf (stderr, ".da file contents exhausted too early\n");
716 /* Should be at end of file now. */
717 if (__read_long (&total, da_file, 8) == 0)
718 fprintf (stderr, ".da file contents not exhausted\n");
721 /* Calculate all of the basic block execution counts and branch
722 taken probabilities. */
724 for (b_ptr = bb_graph_list; b_ptr; b_ptr = b_ptr->next)
725 solve_program_flow_graph (b_ptr);
727 /* Read in all of the data from the .bb file. This info will be accessed
728 sequentially twice. */
729 stat (bb_file_name, &buf);
730 bb_data_size = buf.st_size / 4;
732 bb_data = (char *) xmalloc ((unsigned) buf.st_size);
733 fread (bb_data, sizeof (char), buf.st_size, bb_file);
735 fclose (bb_file);
736 if (da_file)
737 fclose (da_file);
738 fclose (bbg_file);
742 /* Scan the data in the .bb file to find all source files referenced,
743 and the largest line number mentioned in each one. */
745 static void
746 scan_for_source_files ()
748 struct sourcefile *s_ptr = NULL;
749 char *ptr;
750 int count;
751 long line_num;
753 /* Search the bb_data to find:
754 1) The number of sources files contained herein, and
755 2) The largest line number for each source file. */
757 ptr = bb_data;
758 sources = 0;
759 for (count = 0; count < bb_data_size; count++)
761 __fetch_long (&line_num, ptr, 4);
762 ptr += 4;
763 if (line_num == -1)
765 /* A source file name follows. Check to see if we already have
766 a sourcefile structure for this file. */
767 s_ptr = sources;
768 while (s_ptr && strcmp (s_ptr->name, ptr))
769 s_ptr = s_ptr->next;
771 if (s_ptr == 0)
773 /* No sourcefile structure for this file name exists, create
774 a new one, and append it to the front of the sources list. */
775 s_ptr = (struct sourcefile *) xmalloc (sizeof(struct sourcefile));
776 s_ptr->name = xmalloc (strlen ((char *) ptr) + 1);
777 strcpy (s_ptr->name, (char *) ptr);
778 s_ptr->maxlineno = 0;
779 s_ptr->next = sources;
780 sources = s_ptr;
783 /* Scan past the file name. */
785 long delim;
786 do {
787 count++;
788 __fetch_long (&delim, ptr, 4);
789 ptr += 4;
790 } while (delim != line_num);
793 else if (line_num == -2)
795 long delim;
797 /* A function name follows. Ignore it. */
798 do {
799 count++;
800 __fetch_long (&delim, ptr, 4);
801 ptr += 4;
802 } while (delim != line_num);
804 /* There will be a zero before the first file name, in which case s_ptr
805 will still be uninitialized. So, only try to set the maxlineno
806 field if line_num is non-zero. */
807 else if (line_num > 0)
809 if (s_ptr->maxlineno <= line_num)
810 s_ptr->maxlineno = line_num + 1;
812 else if (line_num < 0)
814 /* Don't know what this is, but it's garbage. */
815 abort();
820 /* For calculating coverage at the function level. */
822 static int function_source_lines;
823 static int function_source_lines_executed;
824 static int function_branches;
825 static int function_branches_executed;
826 static int function_branches_taken;
827 static int function_calls;
828 static int function_calls_executed;
829 static char *function_name;
831 /* Calculate the branch taken probabilities for all arcs branches at the
832 end of this block. */
834 static void
835 calculate_branch_probs (current_graph, block_num, branch_probs, last_line_num)
836 struct bb_info_list *current_graph;
837 int block_num;
838 struct arcdata **branch_probs;
839 int last_line_num;
841 int total;
842 struct adj_list *arcptr;
843 struct arcdata *end_ptr, *a_ptr;
845 total = current_graph->bb_graph[block_num].exec_count;
846 for (arcptr = current_graph->bb_graph[block_num].succ; arcptr;
847 arcptr = arcptr->succ_next)
849 /* Ignore fall through arcs as they aren't really branches. */
851 if (arcptr->fall_through)
852 continue;
854 a_ptr = (struct arcdata *) xmalloc (sizeof (struct arcdata));
855 if (total == 0)
856 a_ptr->prob = -1;
857 else
858 a_ptr->prob = ((arcptr->arc_count * 100) + (total >> 1)) / total;
859 a_ptr->call_insn = arcptr->fake;
861 if (output_function_summary)
863 if (a_ptr->call_insn)
865 function_calls++;
866 if (a_ptr->prob != -1)
867 function_calls_executed++;
869 else
871 function_branches++;
872 if (a_ptr->prob != -1)
873 function_branches_executed++;
874 if (a_ptr->prob > 0)
875 function_branches_taken++;
879 /* Append the new branch to the end of the list. */
880 a_ptr->next = 0;
881 if (! branch_probs[last_line_num])
882 branch_probs[last_line_num] = a_ptr;
883 else
885 end_ptr = branch_probs[last_line_num];
886 while (end_ptr->next != 0)
887 end_ptr = end_ptr->next;
888 end_ptr->next = a_ptr;
893 /* Output summary info for a function. */
895 static void
896 function_summary ()
898 if (function_source_lines)
899 fprintf (stdout, "%6.2f%% of %d source lines executed in function %s\n",
900 (((double) function_source_lines_executed / function_source_lines)
901 * 100), function_source_lines, function_name);
902 else
903 fprintf (stdout, "No executable source lines in function %s\n",
904 function_name);
906 if (output_branch_probs)
908 if (function_branches)
910 fprintf (stdout, "%6.2f%% of %d branches executed in function %s\n",
911 (((double) function_branches_executed / function_branches)
912 * 100), function_branches, function_name);
913 fprintf (stdout,
914 "%6.2f%% of %d branches taken at least once in function %s\n",
915 (((double) function_branches_taken / function_branches)
916 * 100), function_branches, function_name);
918 else
919 fprintf (stdout, "No branches in function %s\n", function_name);
920 if (function_calls)
921 fprintf (stdout, "%6.2f%% of %d calls executed in function %s\n",
922 (((double) function_calls_executed / function_calls)
923 * 100), function_calls, function_name);
924 else
925 fprintf (stdout, "No calls in function %s\n", function_name);
929 /* Calculate line execution counts, and output the data to a .tcov file. */
931 static void
932 output_data ()
934 /* When scanning data, this is true only if the data applies to the
935 current source file. */
936 int this_file;
937 /* An array indexed by line number which indicates how many times that line
938 was executed. */
939 long *line_counts;
940 /* An array indexed by line number which indicates whether the line was
941 present in the bb file (i.e. whether it had code associate with it).
942 Lines never executed are those which both exist, and have zero execution
943 counts. */
944 char *line_exists;
945 /* An array indexed by line number, which contains a list of branch
946 probabilities, one for each branch on that line. */
947 struct arcdata **branch_probs = NULL;
948 struct sourcefile *s_ptr;
949 char *source_file_name;
950 FILE *source_file;
951 struct bb_info_list *current_graph;
952 int count;
953 char *cptr;
954 long block_num;
955 long line_num;
956 long last_line_num = 0;
957 int i;
958 struct arcdata *a_ptr;
959 /* Buffer used for reading in lines from the source file. */
960 char string[STRING_SIZE];
961 /* For calculating coverage at the file level. */
962 int total_source_lines;
963 int total_source_lines_executed;
964 int total_branches;
965 int total_branches_executed;
966 int total_branches_taken;
967 int total_calls;
968 int total_calls_executed;
970 /* Now, for each source file, allocate an array big enough to hold a count
971 for each line. Scan through the bb_data, and when the file name matches
972 the current file name, then for each following line number, increment
973 the line number execution count indicated by the execution count of
974 the appropriate basic block. */
976 for (s_ptr = sources; s_ptr; s_ptr = s_ptr->next)
978 /* If this is a relative file name, and an object directory has been
979 specified, then make it relative to the object directory name. */
980 if (*s_ptr->name != '/' && object_directory != 0
981 && *object_directory != '\0')
983 int objdir_count = strlen (object_directory);
984 source_file_name = xmalloc (objdir_count + strlen (s_ptr->name) + 2);
985 strcpy (source_file_name, object_directory);
986 if (object_directory[objdir_count - 1] != '/')
987 source_file_name[objdir_count++] = '/';
988 strcpy (source_file_name + objdir_count, s_ptr->name);
990 else
991 source_file_name = s_ptr->name;
993 line_counts = (long *) xmalloc (sizeof (long) * s_ptr->maxlineno);
994 bzero ((char *) line_counts, sizeof (long) * s_ptr->maxlineno);
995 line_exists = xmalloc (s_ptr->maxlineno);
996 bzero (line_exists, s_ptr->maxlineno);
997 if (output_branch_probs)
999 branch_probs = (struct arcdata **) xmalloc (sizeof (struct arcdata **)
1000 * s_ptr->maxlineno);
1001 bzero ((char *) branch_probs,
1002 sizeof (struct arcdata **) * s_ptr->maxlineno);
1005 /* There will be a zero at the beginning of the bb info, before the
1006 first list of line numbers, so must initialize block_num to 0. */
1007 block_num = 0;
1008 this_file = 0;
1009 current_graph = 0;
1011 /* Pointer into the bb_data, incremented while scanning the data. */
1012 char *ptr = bb_data;
1013 for (count = 0; count < bb_data_size; count++)
1015 long delim;
1017 __fetch_long (&line_num, ptr, 4);
1018 ptr += 4;
1019 if (line_num == -1)
1021 /* Marks the beginning of a file name. Check to see whether
1022 this is the filename we are currently collecting data for. */
1024 if (strcmp (s_ptr->name, ptr))
1025 this_file = 0;
1026 else
1027 this_file = 1;
1029 /* Scan past the file name. */
1030 do {
1031 count++;
1032 __fetch_long (&delim, ptr, 4);
1033 ptr += 4;
1034 } while (delim != line_num);
1036 else if (line_num == -2)
1038 /* Marks the start of a new function. Advance to the next
1039 program flow graph. */
1041 if (! current_graph)
1042 current_graph = bb_graph_list;
1043 else
1045 if (block_num == current_graph->num_blocks - 1)
1046 /* Last block falls through to exit. */
1048 else if (block_num == current_graph->num_blocks - 2)
1050 if (output_branch_probs && this_file)
1051 calculate_branch_probs (current_graph, block_num,
1052 branch_probs, last_line_num);
1054 else
1056 fprintf (stderr,
1057 "didn't use all bb entries of graph, function %s\n",
1058 function_name);
1059 fprintf (stderr, "block_num = %ld, num_blocks = %d\n",
1060 block_num, current_graph->num_blocks);
1063 current_graph = current_graph->next;
1064 block_num = 0;
1066 if (output_function_summary && this_file)
1067 function_summary ();
1070 if (output_function_summary)
1072 function_source_lines = 0;
1073 function_source_lines_executed = 0;
1074 function_branches = 0;
1075 function_branches_executed = 0;
1076 function_branches_taken = 0;
1077 function_calls = 0;
1078 function_calls_executed = 0;
1081 /* Save the function name for later use. */
1082 function_name = ptr;
1084 /* Scan past the file name. */
1085 do {
1086 count++;
1087 __fetch_long (&delim, ptr, 4);
1088 ptr += 4;
1089 } while (delim != line_num);
1091 else if (line_num == 0)
1093 /* Marks the end of a block. */
1095 if (block_num >= current_graph->num_blocks)
1097 fprintf (stderr, "ERROR: too many basic blocks in .bb file %s\n",
1098 function_name);
1099 abort ();
1102 if (output_branch_probs && this_file)
1103 calculate_branch_probs (current_graph, block_num,
1104 branch_probs, last_line_num);
1106 block_num++;
1108 else if (this_file)
1110 if (output_function_summary)
1112 if (line_exists[line_num] == 0)
1113 function_source_lines++;
1114 if (line_counts[line_num] == 0
1115 && current_graph->bb_graph[block_num].exec_count != 0)
1116 function_source_lines_executed++;
1119 /* Accumulate execution data for this line number. */
1121 line_counts[line_num]
1122 += current_graph->bb_graph[block_num].exec_count;
1123 line_exists[line_num] = 1;
1124 last_line_num = line_num;
1129 if (output_function_summary && this_file)
1130 function_summary ();
1132 /* Calculate summary test coverage statistics. */
1134 total_source_lines = 0;
1135 total_source_lines_executed = 0;
1136 total_branches = 0;
1137 total_branches_executed = 0;
1138 total_branches_taken = 0;
1139 total_calls = 0;
1140 total_calls_executed = 0;
1142 for (count = 1; count < s_ptr->maxlineno; count++)
1144 if (line_exists[count])
1146 total_source_lines++;
1147 if (line_counts[count])
1148 total_source_lines_executed++;
1150 if (output_branch_probs)
1152 for (a_ptr = branch_probs[count]; a_ptr; a_ptr = a_ptr->next)
1154 if (a_ptr->call_insn)
1156 total_calls++;
1157 if (a_ptr->prob != -1)
1158 total_calls_executed++;
1160 else
1162 total_branches++;
1163 if (a_ptr->prob != -1)
1164 total_branches_executed++;
1165 if (a_ptr->prob > 0)
1166 total_branches_taken++;
1172 if (total_source_lines)
1173 fprintf (stdout,
1174 "%6.2f%% of %d source lines executed in file %s\n",
1175 (((double) total_source_lines_executed / total_source_lines)
1176 * 100), total_source_lines, source_file_name);
1177 else
1178 fprintf (stdout, "No executable source lines in file %s\n",
1179 source_file_name);
1181 if (output_branch_probs)
1183 if (total_branches)
1185 fprintf (stdout, "%6.2f%% of %d branches executed in file %s\n",
1186 (((double) total_branches_executed / total_branches)
1187 * 100), total_branches, source_file_name);
1188 fprintf (stdout,
1189 "%6.2f%% of %d branches taken at least once in file %s\n",
1190 (((double) total_branches_taken / total_branches)
1191 * 100), total_branches, source_file_name);
1193 else
1194 fprintf (stdout, "No branches in file %s\n", source_file_name);
1195 if (total_calls)
1196 fprintf (stdout, "%6.2f%% of %d calls executed in file %s\n",
1197 (((double) total_calls_executed / total_calls)
1198 * 100), total_calls, source_file_name);
1199 else
1200 fprintf (stdout, "No calls in file %s\n", source_file_name);
1203 if (output_gcov_file)
1205 /* Now the statistics are ready. Read in the source file one line
1206 at a time, and output that line to the gcov file preceded by
1207 its execution count if non zero. */
1209 source_file = fopen (source_file_name, "r");
1210 if (source_file == NULL)
1212 fprintf (stderr, "Could not open source file %s.\n",
1213 source_file_name);
1214 free (line_counts);
1215 free (line_exists);
1216 continue;
1219 count = strlen (source_file_name);
1220 cptr = rindex (s_ptr->name, '/');
1221 if (cptr)
1222 cptr = cptr + 1;
1223 else
1224 cptr = s_ptr->name;
1225 if (output_long_names && strcmp (cptr, input_file_name))
1227 gcov_file_name = xmalloc (count + 7 + strlen (input_file_name));
1229 cptr = rindex (input_file_name, '/');
1230 if (cptr)
1231 strcpy (gcov_file_name, cptr + 1);
1232 else
1233 strcpy (gcov_file_name, input_file_name);
1235 strcat (gcov_file_name, ".");
1237 cptr = rindex (source_file_name, '/');
1238 if (cptr)
1239 strcat (gcov_file_name, cptr + 1);
1240 else
1241 strcat (gcov_file_name, source_file_name);
1243 else
1245 gcov_file_name = xmalloc (count + 6);
1246 cptr = rindex (source_file_name, '/');
1247 if (cptr)
1248 strcpy (gcov_file_name, cptr + 1);
1249 else
1250 strcpy (gcov_file_name, source_file_name);
1253 /* Don't strip off the ending for compatibility with tcov, since
1254 this results in confusion if there is more than one file with
1255 the same basename, e.g. tmp.c and tmp.h. */
1256 strcat (gcov_file_name, ".gcov");
1258 gcov_file = fopen (gcov_file_name, "w");
1260 if (gcov_file == NULL)
1262 fprintf (stderr, "Could not open output file %s.\n",
1263 gcov_file_name);
1264 fclose (source_file);
1265 free (line_counts);
1266 free (line_exists);
1267 continue;
1270 fprintf (stdout, "Creating %s.\n", gcov_file_name);
1272 for (count = 1; count < s_ptr->maxlineno; count++)
1274 char *retval;
1275 int len;
1277 retval = fgets (string, STRING_SIZE, source_file);
1279 /* For lines which don't exist in the .bb file, print nothing
1280 before the source line. For lines which exist but were never
1281 executed, print ###### before the source line. Otherwise,
1282 print the execution count before the source line. */
1283 /* There are 16 spaces of indentation added before the source
1284 line so that tabs won't be messed up. */
1285 if (line_exists[count])
1287 if (line_counts[count])
1288 fprintf (gcov_file, "%12ld %s", line_counts[count],
1289 string);
1290 else
1291 fprintf (gcov_file, " ###### %s", string);
1293 else
1294 fprintf (gcov_file, "\t\t%s", string);
1296 /* In case the source file line is larger than our buffer, keep
1297 reading and outputting lines until we get a newline. */
1298 len = strlen (string);
1299 while ((len == 0 || string[strlen (string) - 1] != '\n')
1300 && retval != NULL)
1302 retval = fgets (string, STRING_SIZE, source_file);
1303 fputs (string, gcov_file);
1306 if (output_branch_probs)
1308 for (i = 0, a_ptr = branch_probs[count]; a_ptr;
1309 a_ptr = a_ptr->next, i++)
1311 if (a_ptr->call_insn)
1313 if (a_ptr->prob == -1)
1314 fprintf (gcov_file, "call %d never executed\n", i);
1315 else
1316 fprintf (gcov_file,
1317 "call %d returns = %d%%\n",
1318 i, 100 - a_ptr->prob);
1320 else
1322 if (a_ptr->prob == -1)
1323 fprintf (gcov_file, "branch %d never executed\n",
1325 else
1326 fprintf (gcov_file, "branch %d taken = %d%%\n", i,
1327 a_ptr->prob);
1332 /* Gracefully handle errors while reading the source file. */
1333 if (retval == NULL)
1335 fprintf (stderr,
1336 "Unexpected EOF while reading source file %s.\n",
1337 source_file_name);
1338 break;
1342 /* Handle all remaining source lines. There may be lines
1343 after the last line of code. */
1346 char *retval = fgets (string, STRING_SIZE, source_file);
1347 while (retval != NULL)
1349 int len;
1351 fprintf (gcov_file, "\t\t%s", string);
1353 /* In case the source file line is larger than our buffer, keep
1354 reading and outputting lines until we get a newline. */
1355 len = strlen (string);
1356 while ((len == 0 || string[strlen (string) - 1] != '\n')
1357 && retval != NULL)
1359 retval = fgets (string, STRING_SIZE, source_file);
1360 fputs (string, gcov_file);
1363 retval = fgets (string, STRING_SIZE, source_file);
1367 fclose (source_file);
1368 fclose (gcov_file);
1371 free (line_counts);
1372 free (line_exists);