OSDN Git Service

* config/xtensa/xtensa.md: Remove unused type attributes.
[pf3gnuchains/gcc-fork.git] / gcc / gcov.c
index 86107ac..3bb2ce1 100644 (file)
@@ -1,9 +1,9 @@
 /* Gcov.c: prepend line execution counts and branch probabilities to a
    source file.
-   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997 Free Software
-   Foundation, Inc.
+   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Contributed by James E. Wilson of Cygnus Support.
-   Mongled by Bob Manson of Cygnus Support.
+   Mangled by Bob Manson of Cygnus Support.
 
 Gcov is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -17,7 +17,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with Gcov; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 /* ??? The code in final.c that produces the struct bb assumes that there is
    no padding between the fields.  This is not necessary true.  The current
@@ -42,17 +43,16 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
    is no way to get the total execution counts for the included file, can
    only get execution counts for one or the other of the including files.  */
 
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-/* The only need for this is so that we get macro definitions for rindex
-   if necessary.  */
 #include "config.h"
+#include "system.h"
+#include "intl.h"
+#include "version.h"
+#undef abort
 
-#include "gcov-io.h"
+#include <getopt.h>
 
-extern char * rindex ();
+typedef HOST_WIDEST_INT gcov_type;
+#include "gcov-io.h"
 
 /* The .bb file format consists of several lists of 4-byte integers
    which are the line numbers of each basic block in the file.  Each
@@ -82,8 +82,6 @@ extern char * rindex ();
 /* The functions in this file for creating and solution program flow graphs
    are very similar to functions in the gcc source file profile.c.  */
 
-char gcov_version_string[] = "GNU gcov version 1.5\n";
-
 /* This is the size of the buffer used to read in source file lines.  */
 
 #define STRING_SIZE 200
@@ -108,7 +106,7 @@ struct sourcefile *sources;
 struct adj_list {
   int source;
   int target;
-  int arc_count;
+  gcov_type arc_count;
   unsigned int count_valid : 1;
   unsigned int on_tree : 1;
   unsigned int fake : 1;
@@ -127,9 +125,9 @@ struct adj_list {
 struct bb_info {
   struct adj_list *succ;
   struct adj_list *pred;
-  int succ_count;
-  int pred_count;
-  int exec_count;
+  gcov_type succ_count;
+  gcov_type pred_count;
+  gcov_type exec_count;
   unsigned int count_valid : 1;
   unsigned int on_tree : 1;
 #if 0
@@ -143,7 +141,8 @@ struct bb_info {
 
 struct arcdata
 {
-  int prob;
+  gcov_type hits;
+  gcov_type total;
   int call_insn;
   struct arcdata *next;
 };
@@ -218,19 +217,36 @@ static int output_function_summary = 0;
 
 static char *object_directory = 0;
 
+/* Output the number of times a branch was taken as opposed to the percentage
+   of times it was taken.  Turned on by the -c option */
+
+static int output_branch_counts = 0;
+
 /* Forward declarations.  */
-static void process_args ();
-static void open_files ();
-static void read_files ();
-static void scan_for_source_files ();
-static void output_data ();
-char * xmalloc ();
+static void process_args PARAMS ((int, char **));
+static void open_files PARAMS ((void));
+static void read_files PARAMS ((void));
+static void scan_for_source_files PARAMS ((void));
+static void output_data PARAMS ((void));
+static void print_usage PARAMS ((int)) ATTRIBUTE_NORETURN;
+static void print_version PARAMS ((void)) ATTRIBUTE_NORETURN;
+static void init_arc PARAMS ((struct adj_list *, int, int, struct bb_info *));
+static struct adj_list *reverse_arcs PARAMS ((struct adj_list *));
+static void create_program_flow_graph PARAMS ((struct bb_info_list *));
+static void solve_program_flow_graph PARAMS ((struct bb_info_list *));
+static void calculate_branch_probs PARAMS ((struct bb_info_list *, int,
+                                           struct arcdata **, int));
+static void function_summary PARAMS ((void));
+
+extern int main PARAMS ((int, char **));
 
 int
 main (argc, argv)
      int argc;
      char **argv;
 {
+  gcc_init_libintl ();
+
   process_args (argc, argv);
 
   open_files ();
@@ -244,38 +260,80 @@ main (argc, argv)
   return 0;
 }
 
-char *
-xmalloc (size)
-     unsigned size;
+static void fnotice PARAMS ((FILE *, const char *, ...)) ATTRIBUTE_PRINTF_2;
+static void
+fnotice VPARAMS ((FILE *file, const char *msgid, ...))
 {
-  register char *value = (char *) malloc (size);
-  if (value == 0)
-    {
-      fprintf (stderr, "error: virtual memory exhausted");
-      exit (1);
-    }
-  return value;
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, FILE *, file);
+  VA_FIXEDARG (ap, const char *, msgid);
+
+  vfprintf (file, _(msgid), ap);
+  VA_CLOSE (ap);
 }
 
 /* More 'friendly' abort that prints the line and file.
    config.h can #define abort fancy_abort if you like that sort of thing.  */
+extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
 
 void
 fancy_abort ()
 {
-  fprintf (stderr, "Internal gcc abort.\n");
+  fnotice (stderr, "Internal gcov abort.\n");
   exit (FATAL_EXIT_CODE);
 }
 \f
-/* Print a usage message and exit.  */
+/* Print a usage message and exit.  If ERROR_P is nonzero, this is an error,
+   otherwise the output of --help.  */
 
 static void
-print_usage ()
+print_usage (error_p)
+     int error_p;
 {
-  fprintf (stderr, "gcov [-b] [-v] [-n] [-l] [-f] [-o OBJDIR] file\n");
-  exit (FATAL_EXIT_CODE);
+  FILE *file = error_p ? stderr : stdout;
+  int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
+  fnotice (file, "Usage: gcov [OPTION]... SOURCEFILE\n\n");
+  fnotice (file, "Print code coverage information.\n\n");
+  fnotice (file, "  -h, --help                      Print this help, then exit\n");
+  fnotice (file, "  -v, --version                   Print version number, then exit\n");
+  fnotice (file, "  -b, --branch-probabilities      Include branch probabilities in output\n");
+  fnotice (file, "  -c, --branch-counts             Given counts of branches taken\n\
+                                    rather than percentages\n");
+  fnotice (file, "  -n, --no-output                 Do not create an output file\n");
+  fnotice (file, "  -l, --long-file-names           Use long output file names for included\n\
+                                    source files\n");
+  fnotice (file, "  -f, --function-summaries        Output summaries for each function\n");
+  fnotice (file, "  -o, --object-directory OBJDIR   Search for object files in OBJDIR\n");
+  fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
+          GCCBUGURL);
+  exit (status);
 }
 
+/* Print version information and exit.  */
+
+static void
+print_version ()
+{
+  fnotice (stdout, "gcov (GCC) %s\n", version_string);
+  fnotice (stdout, "Copyright (C) 2001 Free Software Foundation, Inc.\n");
+  fnotice (stdout,
+          "This is free software; see the source for copying conditions.  There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
+  exit (SUCCESS_EXIT_CODE);
+}
+
+static const struct option options[] =
+{
+  { "help",                 no_argument,       NULL, 'h' },
+  { "version",              no_argument,       NULL, 'v' },
+  { "branch-probabilities", no_argument,       NULL, 'b' },
+  { "branch-counts",        no_argument,       NULL, 'c' },
+  { "no-output",            no_argument,       NULL, 'n' },
+  { "long-file-names",      no_argument,       NULL, 'l' },
+  { "function-summaries",   no_argument,       NULL, 'f' },
+  { "object-directory",     required_argument, NULL, 'o' }
+};
+
 /* Parse the command line.  */
 
 static void
@@ -283,35 +341,46 @@ process_args (argc, argv)
      int argc;
      char **argv;
 {
-  int i;
+  int opt;
 
-  for (i = 1; i < argc; i++)
+  while ((opt = getopt_long (argc, argv, "hvbclnfo:", options, NULL)) != -1)
     {
-      if (argv[i][0] == '-')
+      switch (opt)
        {
-         if (argv[i][1] == 'b')
-           output_branch_probs = 1;
-         else if (argv[i][1] == 'v')
-           fputs (gcov_version_string, stderr);
-         else if (argv[i][1] == 'n')
-           output_gcov_file = 0;
-         else if (argv[i][1] == 'l')
-           output_long_names = 1;
-         else if (argv[i][1] == 'f')
-           output_function_summary = 1;
-         else if (argv[i][1] == 'o' && argv[i][2] == '\0')
-           object_directory = argv[++i];
-         else
-           print_usage ();
+       case 'h':
+         print_usage (false);
+         /* print_usage will exit.  */
+       case 'v':
+         print_version ();
+         /* print_version will exit.  */
+       case 'b':
+         output_branch_probs = 1;
+         break;
+       case 'c':
+         output_branch_counts = 1;
+         break;
+       case 'n':
+         output_gcov_file = 0;
+         break;
+       case 'l':
+         output_long_names = 1;
+         break;
+       case 'f':
+         output_function_summary = 1;
+         break;
+       case 'o':
+         object_directory = optarg;
+         break;
+       default:
+         print_usage (true);
+         /* print_usage will exit.  */
        }
-      else if (! input_file_name)
-       input_file_name = argv[i];
-      else
-       print_usage ();
     }
 
-  if (! input_file_name)
-    print_usage ();
+  if (optind != argc - 1)
+    print_usage (true);
+
+  input_file_name = argv[optind];
 }
 
 
@@ -348,7 +417,7 @@ open_files ()
          strcat (bbg_file_name, "/");
        }
 
-      cptr = rindex (input_file_name, '/');
+      cptr = strrchr (input_file_name, '/');
       if (cptr)
        {
          strcat (da_file_name, cptr + 1);
@@ -369,44 +438,44 @@ open_files ()
       strcpy (bbg_file_name, input_file_name);
     }
 
-  cptr = rindex (bb_file_name, '.');
+  cptr = strrchr (bb_file_name, '.');
   if (cptr)
     strcpy (cptr, ".bb");
   else
     strcat (bb_file_name, ".bb");
 
-  cptr = rindex (da_file_name, '.');
+  cptr = strrchr (da_file_name, '.');
   if (cptr)
     strcpy (cptr, ".da");
   else
     strcat (da_file_name, ".da");
 
-  cptr = rindex (bbg_file_name, '.');
+  cptr = strrchr (bbg_file_name, '.');
   if (cptr)
     strcpy (cptr, ".bbg");
   else
     strcat (bbg_file_name, ".bbg");
 
-  bb_file = fopen (bb_file_name, "r");
+  bb_file = fopen (bb_file_name, "rb");
   if (bb_file == NULL)
     {
-      fprintf (stderr, "Could not open basic block file %s.\n", bb_file_name);
+      fnotice (stderr, "Could not open basic block file %s.\n", bb_file_name);
       exit (FATAL_EXIT_CODE);
     }
 
   /* If none of the functions in the file were executed, then there won't
      be a .da file.  Just assume that all counts are zero in this case.  */
-  da_file = fopen (da_file_name, "r");
+  da_file = fopen (da_file_name, "rb");
   if (da_file == NULL)
     {
-      fprintf (stderr, "Could not open data file %s.\n", da_file_name);
-      fprintf (stderr, "Assuming that all execution counts are zero.\n");
+      fnotice (stderr, "Could not open data file %s.\n", da_file_name);
+      fnotice (stderr, "Assuming that all execution counts are zero.\n");
     }
-    
-  bbg_file = fopen (bbg_file_name, "r");
+
+  bbg_file = fopen (bbg_file_name, "rb");
   if (bbg_file == NULL)
     {
-      fprintf (stderr, "Could not open program flow graph file %s.\n",
+      fnotice (stderr, "Could not open program flow graph file %s.\n",
               bbg_file_name);
       exit (FATAL_EXIT_CODE);
     }
@@ -417,7 +486,7 @@ open_files ()
   ungetc (getc (bbg_file), bbg_file);
   if (feof (bbg_file))
     {
-      fprintf (stderr, "No executable code associated with file %s.\n",
+      fnotice (stderr, "No executable code associated with file %s.\n",
               input_file_name);
       exit (FATAL_EXIT_CODE);
     }
@@ -450,7 +519,7 @@ init_arc (arcptr, source, target, bb_graph)
 }
 
 
-/* Reverse the arcs on a arc list.  */
+/* Reverse the arcs on an arc list.  */
 
 static struct adj_list *
 reverse_arcs (arcptr)
@@ -485,10 +554,8 @@ create_program_flow_graph (bptr)
   /* Read the number of blocks.  */
   __read_long (&num_blocks, bbg_file, 4);
 
-  /* Create an array of size bb number of bb_info structs.  Bzero it.  */
-  bb_graph = (struct bb_info *) xmalloc (num_blocks
-                                        * sizeof (struct bb_info));
-  bzero ((char *) bb_graph, sizeof (struct bb_info) * num_blocks);
+  /* Create an array of size bb number of bb_info structs.  */
+  bb_graph = (struct bb_info *) xcalloc (num_blocks, sizeof (struct bb_info));
 
   bptr->bb_graph = bb_graph;
   bptr->num_blocks = num_blocks;
@@ -546,9 +613,9 @@ create_program_flow_graph (bptr)
     for (arcptr = bb_graph[i].succ; arcptr; arcptr = arcptr->succ_next)
       if (! arcptr->on_tree)
        {
-         long tmp_count = 0;;
-         if (da_file && __read_long (&tmp_count, da_file, 8))
-           abort();
+         gcov_type tmp_count = 0;
+         if (da_file && __read_gcov_type (&tmp_count, da_file, 8))
+           abort ();
 
          arcptr->arc_count = tmp_count;
          arcptr->count_valid = 1;
@@ -556,12 +623,13 @@ create_program_flow_graph (bptr)
          bb_graph[arcptr->target].pred_count--;
        }
 }
-  
+
 static void
 solve_program_flow_graph (bptr)
      struct bb_info_list *bptr;
 {
-  int passes, changes, total;
+  int passes, changes;
+  gcov_type total;
   int i;
   struct adj_list *arcptr;
   struct bb_info *bb_graph;
@@ -672,7 +740,7 @@ solve_program_flow_graph (bptr)
            }
        }
     }
-             
+
   /* If the graph has been correctly solved, every block will have a
      succ and pred count of zero.  */
   for (i = 0; i < num_blocks; i++)
@@ -687,12 +755,12 @@ read_files ()
   struct stat buf;
   struct bb_info_list *list_end = 0;
   struct bb_info_list *b_ptr;
-  long total, first_time;
+  long total;
 
   /* Read and ignore the first word of the .da file, which is the count of
      how many numbers follow.  */
   if (da_file && __read_long (&total, da_file, 8))
-    abort();
+    abort ();
 
   while (! feof (bbg_file))
     {
@@ -707,7 +775,7 @@ read_files ()
 
       /* Read in the data in the .bbg file and reconstruct the program flow
         graph for one function.  */
-      create_program_flow_graph (b_ptr, first_time);
+      create_program_flow_graph (b_ptr);
 
       /* Set the EOF condition if at the end of file.  */
       ungetc (getc (bbg_file), bbg_file);
@@ -718,10 +786,10 @@ read_files ()
   if (da_file)
     {
       if (feof (da_file))
-       fprintf (stderr, ".da file contents exhausted too early\n");
+       fnotice (stderr, ".da file contents exhausted too early\n");
       /* Should be at end of file now.  */
       if (__read_long (&total, da_file, 8) == 0)
-       fprintf (stderr, ".da file contents not exhausted\n");
+       fnotice (stderr, ".da file contents not exhausted\n");
     }
 
   /* Calculate all of the basic block execution counts and branch
@@ -735,9 +803,9 @@ read_files ()
   stat (bb_file_name, &buf);
   bb_data_size = buf.st_size / 4;
 
-  bb_data = (char *) xmalloc (buf.st_size);
+  bb_data = (char *) xmalloc ((unsigned) buf.st_size);
   fread (bb_data, sizeof (char), buf.st_size, bb_file);
-  
+
   fclose (bb_file);
   if (da_file)
     fclose (da_file);
@@ -751,9 +819,9 @@ read_files ()
 static void
 scan_for_source_files ()
 {
-  struct sourcefile *s_ptr;
+  struct sourcefile *s_ptr = NULL;
   char *ptr;
-  int count;
+  long count;
   long line_num;
 
   /* Search the bb_data to find:
@@ -779,8 +847,7 @@ scan_for_source_files ()
              /* No sourcefile structure for this file name exists, create
                 a new one, and append it to the front of the sources list.  */
              s_ptr = (struct sourcefile *) xmalloc (sizeof(struct sourcefile));
-             s_ptr->name = xmalloc (strlen ((char *) ptr) + 1);
-             strcpy (s_ptr->name, (char *) ptr);
+             s_ptr->name = xstrdup (ptr);
              s_ptr->maxlineno = 0;
              s_ptr->next = sources;
              sources = s_ptr;
@@ -817,8 +884,8 @@ scan_for_source_files ()
        }
       else if (line_num < 0)
        {
-         /* Don't know what this is, but it's garbage. */
-         abort();
+         /* Don't know what this is, but it's garbage.  */
+         abort ();
        }
     }
 }
@@ -844,7 +911,7 @@ calculate_branch_probs (current_graph, block_num, branch_probs, last_line_num)
      struct arcdata **branch_probs;
      int last_line_num;
 {
-  int total;
+  gcov_type total;
   struct adj_list *arcptr;
   struct arcdata *end_ptr, *a_ptr;
 
@@ -856,12 +923,13 @@ calculate_branch_probs (current_graph, block_num, branch_probs, last_line_num)
 
       if (arcptr->fall_through)
        continue;
-                     
+
       a_ptr = (struct arcdata *) xmalloc (sizeof (struct arcdata));
+      a_ptr->total = total;
       if (total == 0)
-       a_ptr->prob = -1;
+          a_ptr->hits = 0;
       else
-       a_ptr->prob = ((arcptr->arc_count * 100) + (total >> 1)) / total;
+          a_ptr->hits = arcptr->arc_count;
       a_ptr->call_insn = arcptr->fake;
 
       if (output_function_summary)
@@ -869,15 +937,15 @@ calculate_branch_probs (current_graph, block_num, branch_probs, last_line_num)
          if (a_ptr->call_insn)
            {
              function_calls++;
-             if (a_ptr->prob != -1)
+             if (a_ptr->total != 0)
                function_calls_executed++;
            }
          else
            {
              function_branches++;
-             if (a_ptr->prob != -1)
+             if (a_ptr->total != 0)
                function_branches_executed++;
-             if (a_ptr->prob > 0)
+             if (a_ptr->hits > 0)
                function_branches_taken++;
            }
        }
@@ -902,33 +970,33 @@ static void
 function_summary ()
 {
   if (function_source_lines)
-    fprintf (stdout, "%6.2lf%% of %d source lines executed in function %s\n",
+    fnotice (stdout, "%6.2f%% of %d source lines executed in function %s\n",
             (((double) function_source_lines_executed / function_source_lines)
              * 100), function_source_lines, function_name);
   else
-    fprintf (stdout, "No executable source lines in function %s\n",
+    fnotice (stdout, "No executable source lines in function %s\n",
             function_name);
 
   if (output_branch_probs)
     {
       if (function_branches)
        {
-         fprintf (stdout, "%6.2lf%% of %d branches executed in funcion %s\n",
+         fnotice (stdout, "%6.2f%% of %d branches executed in function %s\n",
                   (((double) function_branches_executed / function_branches)
                    * 100), function_branches, function_name);
-         fprintf (stdout,
-               "%6.2lf%% of %d branches taken at least once in function %s\n",
+         fnotice (stdout,
+               "%6.2f%% of %d branches taken at least once in function %s\n",
                   (((double) function_branches_taken / function_branches)
                    * 100), function_branches, function_name);
        }
       else
-       fprintf (stdout, "No branches in function %s\n", function_name);
+       fnotice (stdout, "No branches in function %s\n", function_name);
       if (function_calls)
-       fprintf (stdout, "%6.2lf%% of %d calls executed in function %s\n",
+       fnotice (stdout, "%6.2f%% of %d calls executed in function %s\n",
                 (((double) function_calls_executed / function_calls)
                  * 100), function_calls, function_name);
       else
-       fprintf (stdout, "No calls in function %s\n", function_name);
+       fnotice (stdout, "No calls in function %s\n", function_name);
     }
 }
 
@@ -942,7 +1010,7 @@ output_data ()
   int this_file;
   /* An array indexed by line number which indicates how many times that line
      was executed.  */
-  long *line_counts;
+  gcov_type *line_counts;
   /* An array indexed by line number which indicates whether the line was
      present in the bb file (i.e. whether it had code associate with it).
      Lines never executed are those which both exist, and have zero execution
@@ -950,16 +1018,16 @@ output_data ()
   char *line_exists;
   /* An array indexed by line number, which contains a list of branch
      probabilities, one for each branch on that line.  */
-  struct arcdata **branch_probs;
+  struct arcdata **branch_probs = NULL;
   struct sourcefile *s_ptr;
   char *source_file_name;
   FILE *source_file;
   struct bb_info_list *current_graph;
-  int count;
+  long count;
   char *cptr;
   long block_num;
   long line_num;
-  long last_line_num;
+  long last_line_num = 0;
   int i;
   struct arcdata *a_ptr;
   /* Buffer used for reading in lines from the source file.  */
@@ -983,7 +1051,8 @@ output_data ()
     {
       /* If this is a relative file name, and an object directory has been
         specified, then make it relative to the object directory name.  */
-      if (*s_ptr->name != '/' && object_directory != 0
+      if (! IS_ABSOLUTE_PATHNAME (s_ptr->name)
+         && object_directory != 0
          && *object_directory != '\0')
        {
          int objdir_count = strlen (object_directory);
@@ -996,18 +1065,12 @@ output_data ()
       else
        source_file_name = s_ptr->name;
 
-      line_counts = (long *) xmalloc (sizeof (long) * s_ptr->maxlineno);
-      bzero ((char *) line_counts, sizeof (long) * s_ptr->maxlineno);
-      line_exists = xmalloc (s_ptr->maxlineno);
-      bzero (line_exists, s_ptr->maxlineno);
+      line_counts = (gcov_type *) xcalloc (sizeof (gcov_type), s_ptr->maxlineno);
+      line_exists = xcalloc (1, s_ptr->maxlineno);
       if (output_branch_probs)
-       {
-         branch_probs = (struct arcdata **) xmalloc (sizeof (struct arcdata **)
-                                                     * s_ptr->maxlineno);
-         bzero ((char *) branch_probs, 
-                sizeof (struct arcdata **) * s_ptr->maxlineno);
-       }
-      
+       branch_probs = (struct arcdata **)
+         xcalloc (sizeof (struct arcdata *), s_ptr->maxlineno);
+
       /* There will be a zero at the beginning of the bb info, before the
         first list of line numbers, so must initialize block_num to 0.  */
       block_num = 0;
@@ -1031,7 +1094,7 @@ output_data ()
                  this_file = 0;
                else
                  this_file = 1;
-             
+
                /* Scan past the file name.  */
                do {
                  count++;
@@ -1059,10 +1122,10 @@ output_data ()
                      }
                    else
                      {
-                       fprintf (stderr,
+                       fnotice (stderr,
                                 "didn't use all bb entries of graph, function %s\n",
                                 function_name);
-                       fprintf (stderr, "block_num = %d, num_blocks = %d\n",
+                       fnotice (stderr, "block_num = %ld, num_blocks = %d\n",
                                 block_num, current_graph->num_blocks);
                      }
 
@@ -1100,11 +1163,11 @@ output_data ()
 
                if (block_num >= current_graph->num_blocks)
                  {
-                   fprintf (stderr, "ERROR: too many basic blocks in .bb file %s\n",
+                   fnotice (stderr, "ERROR: too many basic blocks in .bb file %s\n",
                             function_name);
                    abort ();
                  }
-                 
+
                if (output_branch_probs && this_file)
                  calculate_branch_probs (current_graph, block_num,
                                          branch_probs, last_line_num);
@@ -1160,15 +1223,15 @@ output_data ()
                  if (a_ptr->call_insn)
                    {
                      total_calls++;
-                     if (a_ptr->prob != -1)
+                     if (a_ptr->total != 0)
                        total_calls_executed++;
                    }
                  else
                    {
                      total_branches++;
-                     if (a_ptr->prob != -1)
+                     if (a_ptr->total != 0)
                        total_branches_executed++;
-                     if (a_ptr->prob > 0)
+                     if (a_ptr->hits > 0)
                        total_branches_taken++;
                    }
                }
@@ -1176,46 +1239,46 @@ output_data ()
        }
 
       if (total_source_lines)
-       fprintf (stdout,
-                "%6.2lf%% of %d source lines executed in file %s\n",
+       fnotice (stdout,
+                "%6.2f%% of %d source lines executed in file %s\n",
                 (((double) total_source_lines_executed / total_source_lines)
                  * 100), total_source_lines, source_file_name);
       else
-       fprintf (stdout, "No executable source lines in file %s\n",
+       fnotice (stdout, "No executable source lines in file %s\n",
                 source_file_name);
 
       if (output_branch_probs)
        {
          if (total_branches)
            {
-             fprintf (stdout, "%6.2lf%% of %d branches executed in file %s\n",
+             fnotice (stdout, "%6.2f%% of %d branches executed in file %s\n",
                       (((double) total_branches_executed / total_branches)
                        * 100), total_branches, source_file_name);
-             fprintf (stdout,
-                   "%6.2lf%% of %d branches taken at least once in file %s\n",
+             fnotice (stdout,
+                   "%6.2f%% of %d branches taken at least once in file %s\n",
                       (((double) total_branches_taken / total_branches)
                        * 100), total_branches, source_file_name);
            }
          else
-           fprintf (stdout, "No branches in file %s\n", source_file_name);
+           fnotice (stdout, "No branches in file %s\n", source_file_name);
          if (total_calls)
-           fprintf (stdout, "%6.2lf%% of %d calls executed in file %s\n",
+           fnotice (stdout, "%6.2f%% of %d calls executed in file %s\n",
                     (((double) total_calls_executed / total_calls)
                      * 100), total_calls, source_file_name);
          else
-           fprintf (stdout, "No calls in file %s\n", source_file_name);
+           fnotice (stdout, "No calls in file %s\n", source_file_name);
        }
 
       if (output_gcov_file)
        {
          /* Now the statistics are ready.  Read in the source file one line
-            at a time, and output that line to the gcov file preceeded by
+            at a time, and output that line to the gcov file preceded by
             its execution count if non zero.  */
-      
+
          source_file = fopen (source_file_name, "r");
          if (source_file == NULL)
            {
-             fprintf (stderr, "Could not open source file %s.\n",
+             fnotice (stderr, "Could not open source file %s.\n",
                       source_file_name);
              free (line_counts);
              free (line_exists);
@@ -1223,7 +1286,7 @@ output_data ()
            }
 
          count = strlen (source_file_name);
-         cptr = rindex (s_ptr->name, '/');
+         cptr = strrchr (s_ptr->name, '/');
          if (cptr)
            cptr = cptr + 1;
          else
@@ -1231,8 +1294,8 @@ output_data ()
          if (output_long_names && strcmp (cptr, input_file_name))
            {
              gcov_file_name = xmalloc (count + 7 + strlen (input_file_name));
-             
-             cptr = rindex (input_file_name, '/');
+
+             cptr = strrchr (input_file_name, '/');
              if (cptr)
                strcpy (gcov_file_name, cptr + 1);
              else
@@ -1240,7 +1303,7 @@ output_data ()
 
              strcat (gcov_file_name, ".");
 
-             cptr = rindex (source_file_name, '/');
+             cptr = strrchr (source_file_name, '/');
              if (cptr)
                strcat (gcov_file_name, cptr + 1);
              else
@@ -1249,7 +1312,7 @@ output_data ()
          else
            {
              gcov_file_name = xmalloc (count + 6);
-             cptr = rindex (source_file_name, '/');
+             cptr = strrchr (source_file_name, '/');
              if (cptr)
                strcpy (gcov_file_name, cptr + 1);
              else
@@ -1265,7 +1328,7 @@ output_data ()
 
          if (gcov_file == NULL)
            {
-             fprintf (stderr, "Could not open output file %s.\n",
+             fnotice (stderr, "Could not open output file %s.\n",
                       gcov_file_name);
              fclose (source_file);
              free (line_counts);
@@ -1273,7 +1336,7 @@ output_data ()
              continue;
            }
 
-         fprintf (stdout, "Creating %s.\n", gcov_file_name);
+         fnotice (stdout, "Creating %s.\n", gcov_file_name);
 
          for (count = 1; count < s_ptr->maxlineno; count++)
            {
@@ -1286,13 +1349,17 @@ output_data ()
                 before the source line.  For lines which exist but were never
                 executed, print ###### before the source line.  Otherwise,
                 print the execution count before the source line.  */
-             /* There are 16 spaces of identation added before the source line
-                so that tabs won't be messed up.  */
+             /* There are 16 spaces of indentation added before the source
+                line so that tabs won't be messed up.  */
              if (line_exists[count])
                {
                  if (line_counts[count])
-                   fprintf (gcov_file, "%12d    %s", line_counts[count],
-                            string);
+                   {
+                     char c[20];
+                     sprintf (c, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT)line_counts[count]);
+                     fprintf (gcov_file, "%12s    %s", c,
+                              string);
+                   }
                  else
                    fprintf (gcov_file, "      ######    %s", string);
                }
@@ -1300,10 +1367,10 @@ output_data ()
                fprintf (gcov_file, "\t\t%s", string);
 
              /* In case the source file line is larger than our buffer, keep
-                reading and outputing lines until we get a newline.  */
+                reading and outputting lines until we get a newline.  */
              len = strlen (string);
-             while ((len == 0 || string[strlen (string) - 1] != '\n') &&
-                    retval != NULL)
+             while ((len == 0 || string[strlen (string) - 1] != '\n')
+                    && retval != NULL)
                {
                  retval = fgets (string, STRING_SIZE, source_file);
                  fputs (string, gcov_file);
@@ -1316,29 +1383,64 @@ output_data ()
                    {
                      if (a_ptr->call_insn)
                        {
-                         if (a_ptr->prob == -1)
-                           fprintf (gcov_file, "call %d never executed\n", i);
-                         else
-                           fprintf (gcov_file,
-                                    "call %d returns = %d%%\n",
-                                    i, 100 - a_ptr->prob);
+                         if (a_ptr->total == 0)
+                           fnotice (gcov_file, "call %d never executed\n", i);
+                           else
+                             {
+                               if (output_branch_counts)
+                                 {
+                                   char c[20];
+                                   sprintf (c, HOST_WIDEST_INT_PRINT_DEC,
+                                            a_ptr->total - a_ptr->hits);
+                                   fnotice (gcov_file,
+                                            "call %d returns = %s\n", i, c);
+                                 }
+                               else
+                                 {
+                                   char c[20];
+                                   sprintf (c, HOST_WIDEST_INT_PRINT_DEC,
+                                            100 - ((a_ptr->hits * 100)
+                                                   + (a_ptr->total >> 1))
+                                            / a_ptr->total);
+                                   fnotice (gcov_file,
+                                            "call %d returns = %s%%\n", i, c);
+                                 }
+                             }
                        }
                      else
                        {
-                         if (a_ptr->prob == -1)
-                           fprintf (gcov_file, "branch %d never executed\n",
+                         if (a_ptr->total == 0)
+                           fnotice (gcov_file, "branch %d never executed\n",
                                     i);
                          else
-                           fprintf (gcov_file, "branch %d taken = %d%%\n", i,
-                                    a_ptr->prob);
+                           {
+                             if (output_branch_counts)
+                               {
+                                 char c[20];
+                                 sprintf (c, HOST_WIDEST_INT_PRINT_DEC,
+                                          a_ptr->hits);
+                                 fnotice (gcov_file,
+                                          "branch %d taken = %s\n", i, c);
+                               }
+                             else
+                               {
+                                 char c[20];
+                                 sprintf (c, HOST_WIDEST_INT_PRINT_DEC,
+                                          ((a_ptr->hits * 100)
+                                           + (a_ptr->total >> 1))
+                                          / a_ptr->total);
+                                fnotice (gcov_file,
+                                         "branch %d taken = %s%%\n", i, c);
+                               }
+                           }
                        }
-                   }
-               }
+                  }
+             }
 
              /* Gracefully handle errors while reading the source file.  */
              if (retval == NULL)
                {
-                 fprintf (stderr,
+                 fnotice (stderr,
                           "Unexpected EOF while reading source file %s.\n",
                           source_file_name);
                  break;
@@ -1357,10 +1459,10 @@ output_data ()
                fprintf (gcov_file, "\t\t%s", string);
 
                /* In case the source file line is larger than our buffer, keep
-                  reading and outputing lines until we get a newline.  */
+                  reading and outputting lines until we get a newline.  */
                len = strlen (string);
-               while ((len == 0 || string[strlen (string) - 1] != '\n') &&
-                      retval != NULL)
+               while ((len == 0 || string[strlen (string) - 1] != '\n')
+                      && retval != NULL)
                  {
                    retval = fgets (string, STRING_SIZE, source_file);
                    fputs (string, gcov_file);