gcc/gcc/libgcov.c

470 lines
13 KiB
C
Raw Normal View History

/* Routines required for instrumenting a program. */
/* Compile this one with gcc. */
/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#if defined(inhibit_libc)
/* If libc and its header files are not available, provide dummy functions. */
void __gcov_init (void *p);
void __gcov_flush (void);
void __gcov_init (void *p) { }
void __gcov_flush (void) { }
#else
/* It is incorrect to include config.h here, because this file is being
compiled for the target, and hence definitions concerning only the host
do not apply. */
#include "tconfig.h"
#include "tsystem.h"
#include "coretypes.h"
#include "tm.h"
#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
#include <stdio.h>
#include <string.h>
#if defined (TARGET_HAS_F_SETLKW)
#include <fcntl.h>
#include <errno.h>
#endif
Change gcov file interface to single file at a time. * gcov-io.h: Replace IN_LIBGCC1 with IN_LIBGCOV. Use IN_GCOV. Convert to C89 prototypes. (gcov_file, gcov_length, gcov_position, gcov_buffer, gcov_alloc, gcov_error, gcov_modified): New static variables. (gcov_open, gcov_close, gcov_read_bytes, gcov_write_bytes): New functions. (gcov_write_unsigned, gcov_write_counter, gcov_write_string, gcov_read_unsigned, gcov_read_counter, gcov_read_string): Adjust. (gcov_read_summary, gcov_write_summary): Adjust. (gcov_save_position, gcov_reserve_length, gcov_write_length): Adjust. (gcov_resync, gcov_skip, gcov_skip_string): Adjust. (da_file_open, da_file_close, da_file_eof, da_file_error): Remove. (da_file_position, da_file_seek, da_file_write, da_file_read): Remove. (gcov_error, gcov_eof, gcov_ok, gcov_time): New functions. * gcov.c (gcov_type): Don't typedef here. (IN_GCOV): #define (read_graph_file, read_count_file): Adjust. * gcov-dump.c (gcov_type): Don't typedef here. (IN_GCOV): #define. (tag_function, tag_blocks, tag_arcs, tag_lines, tag_arc_counts): Remove FILE parameter, adjust. (struct tag_format): Adjust proc member. (dump_file): Adjust. * libgcov.c (IN_LIBGCOV): #define. (gcov_exit): Adjust. * loop-init.c: Don't #include gcov-io.h * profile.c (struct counts_entry): New structure to hold counter values. (struct section_reference, struct da_index_entry): Remove. (bbg_file, da_file): Remove. (htab_counts_index_hash, htab_counts_index_eq, htab_counts_index_del): Replace with ... (htab_counts_entry_hash, htab_counts_entry_eq, htab_counts_entry_del): ... these. (cleanup_counts_index, index_counts_file): Remove. (read_counts_file): New function. (get_exec_counts): Adjust. (compute_branch_probabilities): Don't free the exec counts here. (branch_prob): Adjust. (init_branch_prob): Adjust. (end_branch_prob): Adjust. From-SVN: r65338
2003-04-07 21:37:12 +02:00
#define IN_LIBGCOV 1
#include "gcov-io.h"
/* Chain of per-object gcov structures. */
static struct gcov_info *gcov_list;
/* A program checksum allows us to distinguish program data for an
object file included in multiple programs. */
static unsigned gcov_crc32;
static void
gcov_version_mismatch (struct gcov_info *ptr, unsigned version)
{
unsigned expected = GCOV_VERSION;
unsigned ix;
char e[4], v[4];
for (ix = 4; ix--; expected >>= 8, version >>= 8)
{
e[ix] = expected;
v[ix] = version;
}
fprintf (stderr,
"profiling:%s:Version mismatch - expected %.4s got %.4s\n",
ptr->filename, e, v);
}
/* Dump the coverage counts. We merge with existing counts when
possible, to avoid growing the .da files ad infinitum. We use this
program's checksum to make sure we only accumulate whole program
statistics to the correct summary. An object file might be embedded
in two separate programs, and we must keep the two program
summaries separate. */
static void
gcov_exit (void)
{
struct gcov_info *ptr;
unsigned ix, jx;
struct gcov_summary program;
gcov_type program_max_one = 0;
gcov_type program_max_sum = 0;
gcov_type program_sum = 0;
unsigned program_arcs = 0;
memset (&program, 0, sizeof (program));
program.checksum = gcov_crc32;
for (ptr = gcov_list; ptr; ptr = ptr->next)
{
struct gcov_summary object;
struct gcov_summary local_prg;
int error;
Change gcov file interface to single file at a time. * gcov-io.h: Replace IN_LIBGCC1 with IN_LIBGCOV. Use IN_GCOV. Convert to C89 prototypes. (gcov_file, gcov_length, gcov_position, gcov_buffer, gcov_alloc, gcov_error, gcov_modified): New static variables. (gcov_open, gcov_close, gcov_read_bytes, gcov_write_bytes): New functions. (gcov_write_unsigned, gcov_write_counter, gcov_write_string, gcov_read_unsigned, gcov_read_counter, gcov_read_string): Adjust. (gcov_read_summary, gcov_write_summary): Adjust. (gcov_save_position, gcov_reserve_length, gcov_write_length): Adjust. (gcov_resync, gcov_skip, gcov_skip_string): Adjust. (da_file_open, da_file_close, da_file_eof, da_file_error): Remove. (da_file_position, da_file_seek, da_file_write, da_file_read): Remove. (gcov_error, gcov_eof, gcov_ok, gcov_time): New functions. * gcov.c (gcov_type): Don't typedef here. (IN_GCOV): #define (read_graph_file, read_count_file): Adjust. * gcov-dump.c (gcov_type): Don't typedef here. (IN_GCOV): #define. (tag_function, tag_blocks, tag_arcs, tag_lines, tag_arc_counts): Remove FILE parameter, adjust. (struct tag_format): Adjust proc member. (dump_file): Adjust. * libgcov.c (IN_LIBGCOV): #define. (gcov_exit): Adjust. * loop-init.c: Don't #include gcov-io.h * profile.c (struct counts_entry): New structure to hold counter values. (struct section_reference, struct da_index_entry): Remove. (bbg_file, da_file): Remove. (htab_counts_index_hash, htab_counts_index_eq, htab_counts_index_del): Replace with ... (htab_counts_entry_hash, htab_counts_entry_eq, htab_counts_entry_del): ... these. (cleanup_counts_index, index_counts_file): Remove. (read_counts_file): New function. (get_exec_counts): Adjust. (compute_branch_probabilities): Don't free the exec counts here. (branch_prob): Adjust. (init_branch_prob): Adjust. (end_branch_prob): Adjust. From-SVN: r65338
2003-04-07 21:37:12 +02:00
int merging;
unsigned long base;
const struct function_info *fn_info;
gcov_type **counters;
gcov_type *count_ptr;
gcov_type object_max_one = 0;
unsigned tag, length;
unsigned arc_data_index, f_sect_index, sect_index;
ptr->wkspc = 0;
if (!ptr->filename)
continue;
counters = malloc (sizeof (gcov_type *) * ptr->n_counter_sections);
for (ix = 0; ix < ptr->n_counter_sections; ix++)
counters[ix] = ptr->counter_sections[ix].counters;
for (arc_data_index = 0;
arc_data_index < ptr->n_counter_sections
&& ptr->counter_sections[arc_data_index].tag != GCOV_TAG_ARC_COUNTS;
arc_data_index++)
continue;
if (arc_data_index == ptr->n_counter_sections)
{
/* For now; later we may want to just measure other profiles,
but now I am lazy to check for all consequences. */
abort ();
}
for (ix = ptr->counter_sections[arc_data_index].n_counters,
count_ptr = ptr->counter_sections[arc_data_index].counters; ix--;)
{
gcov_type count = *count_ptr++;
if (count > object_max_one)
object_max_one = count;
}
if (object_max_one > program_max_one)
program_max_one = object_max_one;
memset (&local_prg, 0, sizeof (local_prg));
memset (&object, 0, sizeof (object));
/* Open for modification */
Change gcov file interface to single file at a time. * gcov-io.h: Replace IN_LIBGCC1 with IN_LIBGCOV. Use IN_GCOV. Convert to C89 prototypes. (gcov_file, gcov_length, gcov_position, gcov_buffer, gcov_alloc, gcov_error, gcov_modified): New static variables. (gcov_open, gcov_close, gcov_read_bytes, gcov_write_bytes): New functions. (gcov_write_unsigned, gcov_write_counter, gcov_write_string, gcov_read_unsigned, gcov_read_counter, gcov_read_string): Adjust. (gcov_read_summary, gcov_write_summary): Adjust. (gcov_save_position, gcov_reserve_length, gcov_write_length): Adjust. (gcov_resync, gcov_skip, gcov_skip_string): Adjust. (da_file_open, da_file_close, da_file_eof, da_file_error): Remove. (da_file_position, da_file_seek, da_file_write, da_file_read): Remove. (gcov_error, gcov_eof, gcov_ok, gcov_time): New functions. * gcov.c (gcov_type): Don't typedef here. (IN_GCOV): #define (read_graph_file, read_count_file): Adjust. * gcov-dump.c (gcov_type): Don't typedef here. (IN_GCOV): #define. (tag_function, tag_blocks, tag_arcs, tag_lines, tag_arc_counts): Remove FILE parameter, adjust. (struct tag_format): Adjust proc member. (dump_file): Adjust. * libgcov.c (IN_LIBGCOV): #define. (gcov_exit): Adjust. * loop-init.c: Don't #include gcov-io.h * profile.c (struct counts_entry): New structure to hold counter values. (struct section_reference, struct da_index_entry): Remove. (bbg_file, da_file): Remove. (htab_counts_index_hash, htab_counts_index_eq, htab_counts_index_del): Replace with ... (htab_counts_entry_hash, htab_counts_entry_eq, htab_counts_entry_del): ... these. (cleanup_counts_index, index_counts_file): Remove. (read_counts_file): New function. (get_exec_counts): Adjust. (compute_branch_probabilities): Don't free the exec counts here. (branch_prob): Adjust. (init_branch_prob): Adjust. (end_branch_prob): Adjust. From-SVN: r65338
2003-04-07 21:37:12 +02:00
merging = gcov_open (ptr->filename, 0);
if (!merging)
{
fprintf (stderr, "profiling:%s:Cannot open\n", ptr->filename);
ptr->filename = 0;
continue;
}
Change gcov file interface to single file at a time. * gcov-io.h: Replace IN_LIBGCC1 with IN_LIBGCOV. Use IN_GCOV. Convert to C89 prototypes. (gcov_file, gcov_length, gcov_position, gcov_buffer, gcov_alloc, gcov_error, gcov_modified): New static variables. (gcov_open, gcov_close, gcov_read_bytes, gcov_write_bytes): New functions. (gcov_write_unsigned, gcov_write_counter, gcov_write_string, gcov_read_unsigned, gcov_read_counter, gcov_read_string): Adjust. (gcov_read_summary, gcov_write_summary): Adjust. (gcov_save_position, gcov_reserve_length, gcov_write_length): Adjust. (gcov_resync, gcov_skip, gcov_skip_string): Adjust. (da_file_open, da_file_close, da_file_eof, da_file_error): Remove. (da_file_position, da_file_seek, da_file_write, da_file_read): Remove. (gcov_error, gcov_eof, gcov_ok, gcov_time): New functions. * gcov.c (gcov_type): Don't typedef here. (IN_GCOV): #define (read_graph_file, read_count_file): Adjust. * gcov-dump.c (gcov_type): Don't typedef here. (IN_GCOV): #define. (tag_function, tag_blocks, tag_arcs, tag_lines, tag_arc_counts): Remove FILE parameter, adjust. (struct tag_format): Adjust proc member. (dump_file): Adjust. * libgcov.c (IN_LIBGCOV): #define. (gcov_exit): Adjust. * loop-init.c: Don't #include gcov-io.h * profile.c (struct counts_entry): New structure to hold counter values. (struct section_reference, struct da_index_entry): Remove. (bbg_file, da_file): Remove. (htab_counts_index_hash, htab_counts_index_eq, htab_counts_index_del): Replace with ... (htab_counts_entry_hash, htab_counts_entry_eq, htab_counts_entry_del): ... these. (cleanup_counts_index, index_counts_file): Remove. (read_counts_file): New function. (get_exec_counts): Adjust. (compute_branch_probabilities): Don't free the exec counts here. (branch_prob): Adjust. (init_branch_prob): Adjust. (end_branch_prob): Adjust. From-SVN: r65338
2003-04-07 21:37:12 +02:00
if (merging > 0)
{
/* Merge data from file. */
if (gcov_read_unsigned () != GCOV_DATA_MAGIC)
{
fprintf (stderr, "profiling:%s:Not a gcov data file\n",
ptr->filename);
read_fatal:;
Change gcov file interface to single file at a time. * gcov-io.h: Replace IN_LIBGCC1 with IN_LIBGCOV. Use IN_GCOV. Convert to C89 prototypes. (gcov_file, gcov_length, gcov_position, gcov_buffer, gcov_alloc, gcov_error, gcov_modified): New static variables. (gcov_open, gcov_close, gcov_read_bytes, gcov_write_bytes): New functions. (gcov_write_unsigned, gcov_write_counter, gcov_write_string, gcov_read_unsigned, gcov_read_counter, gcov_read_string): Adjust. (gcov_read_summary, gcov_write_summary): Adjust. (gcov_save_position, gcov_reserve_length, gcov_write_length): Adjust. (gcov_resync, gcov_skip, gcov_skip_string): Adjust. (da_file_open, da_file_close, da_file_eof, da_file_error): Remove. (da_file_position, da_file_seek, da_file_write, da_file_read): Remove. (gcov_error, gcov_eof, gcov_ok, gcov_time): New functions. * gcov.c (gcov_type): Don't typedef here. (IN_GCOV): #define (read_graph_file, read_count_file): Adjust. * gcov-dump.c (gcov_type): Don't typedef here. (IN_GCOV): #define. (tag_function, tag_blocks, tag_arcs, tag_lines, tag_arc_counts): Remove FILE parameter, adjust. (struct tag_format): Adjust proc member. (dump_file): Adjust. * libgcov.c (IN_LIBGCOV): #define. (gcov_exit): Adjust. * loop-init.c: Don't #include gcov-io.h * profile.c (struct counts_entry): New structure to hold counter values. (struct section_reference, struct da_index_entry): Remove. (bbg_file, da_file): Remove. (htab_counts_index_hash, htab_counts_index_eq, htab_counts_index_del): Replace with ... (htab_counts_entry_hash, htab_counts_entry_eq, htab_counts_entry_del): ... these. (cleanup_counts_index, index_counts_file): Remove. (read_counts_file): New function. (get_exec_counts): Adjust. (compute_branch_probabilities): Don't free the exec counts here. (branch_prob): Adjust. (init_branch_prob): Adjust. (end_branch_prob): Adjust. From-SVN: r65338
2003-04-07 21:37:12 +02:00
gcov_close ();
ptr->filename = 0;
continue;
}
length = gcov_read_unsigned ();
if (length != GCOV_VERSION)
{
gcov_version_mismatch (ptr, length);
goto read_fatal;
}
/* Merge execution counts for each function. */
for (ix = ptr->n_functions, fn_info = ptr->functions;
ix--; fn_info++)
{
tag = gcov_read_unsigned ();
length = gcov_read_unsigned ();
/* Check function */
if (tag != GCOV_TAG_FUNCTION)
{
read_mismatch:;
fprintf (stderr, "profiling:%s:Merge mismatch at %s\n",
ptr->filename, fn_info->name);
goto read_fatal;
}
if (strcmp (gcov_read_string (), fn_info->name)
|| gcov_read_unsigned () != fn_info->checksum)
goto read_mismatch;
/* Counters. */
for (f_sect_index = 0;
f_sect_index < fn_info->n_counter_sections;
f_sect_index++)
{
unsigned n_counters;
tag = gcov_read_unsigned ();
length = gcov_read_unsigned ();
for (sect_index = 0;
sect_index < ptr->n_counter_sections;
sect_index++)
if (ptr->counter_sections[sect_index].tag == tag)
break;
if (sect_index == ptr->n_counter_sections
|| fn_info->counter_sections[f_sect_index].tag != tag)
goto read_mismatch;
n_counters = fn_info->counter_sections[f_sect_index].n_counters;
if (n_counters != length / 8)
goto read_mismatch;
for (jx = 0; jx < n_counters; jx++)
counters[sect_index][jx] += gcov_read_counter ();
counters[sect_index] += n_counters;
}
if ((error = gcov_is_error ()))
goto read_error;
}
/* Check object summary */
if (gcov_read_unsigned () != GCOV_TAG_OBJECT_SUMMARY)
goto read_mismatch;
gcov_read_unsigned ();
gcov_read_summary (&object);
/* Check program summary */
while (!gcov_is_eof ())
{
unsigned long base = gcov_position ();
tag = gcov_read_unsigned ();
gcov_read_unsigned ();
if (tag != GCOV_TAG_PROGRAM_SUMMARY
&& tag != GCOV_TAG_PLACEHOLDER_SUMMARY
&& tag != GCOV_TAG_INCORRECT_SUMMARY)
goto read_mismatch;
gcov_read_summary (&local_prg);
if ((error = gcov_is_error ()))
{
read_error:;
fprintf (stderr, error < 0 ?
"profiling:%s:Overflow merging\n" :
"profiling:%s:Error merging\n",
ptr->filename);
goto read_fatal;
}
if (local_prg.checksum != program.checksum)
continue;
if (tag == GCOV_TAG_PLACEHOLDER_SUMMARY)
{
fprintf (stderr,
"profiling:%s:Concurrent race detected\n",
ptr->filename);
goto read_fatal;
}
Change gcov file interface to single file at a time. * gcov-io.h: Replace IN_LIBGCC1 with IN_LIBGCOV. Use IN_GCOV. Convert to C89 prototypes. (gcov_file, gcov_length, gcov_position, gcov_buffer, gcov_alloc, gcov_error, gcov_modified): New static variables. (gcov_open, gcov_close, gcov_read_bytes, gcov_write_bytes): New functions. (gcov_write_unsigned, gcov_write_counter, gcov_write_string, gcov_read_unsigned, gcov_read_counter, gcov_read_string): Adjust. (gcov_read_summary, gcov_write_summary): Adjust. (gcov_save_position, gcov_reserve_length, gcov_write_length): Adjust. (gcov_resync, gcov_skip, gcov_skip_string): Adjust. (da_file_open, da_file_close, da_file_eof, da_file_error): Remove. (da_file_position, da_file_seek, da_file_write, da_file_read): Remove. (gcov_error, gcov_eof, gcov_ok, gcov_time): New functions. * gcov.c (gcov_type): Don't typedef here. (IN_GCOV): #define (read_graph_file, read_count_file): Adjust. * gcov-dump.c (gcov_type): Don't typedef here. (IN_GCOV): #define. (tag_function, tag_blocks, tag_arcs, tag_lines, tag_arc_counts): Remove FILE parameter, adjust. (struct tag_format): Adjust proc member. (dump_file): Adjust. * libgcov.c (IN_LIBGCOV): #define. (gcov_exit): Adjust. * loop-init.c: Don't #include gcov-io.h * profile.c (struct counts_entry): New structure to hold counter values. (struct section_reference, struct da_index_entry): Remove. (bbg_file, da_file): Remove. (htab_counts_index_hash, htab_counts_index_eq, htab_counts_index_del): Replace with ... (htab_counts_entry_hash, htab_counts_entry_eq, htab_counts_entry_del): ... these. (cleanup_counts_index, index_counts_file): Remove. (read_counts_file): New function. (get_exec_counts): Adjust. (compute_branch_probabilities): Don't free the exec counts here. (branch_prob): Adjust. (init_branch_prob): Adjust. (end_branch_prob): Adjust. From-SVN: r65338
2003-04-07 21:37:12 +02:00
merging = 0;
if (tag != GCOV_TAG_PROGRAM_SUMMARY)
break;
if (program.runs
&& memcmp (&program, &local_prg, sizeof (program)))
{
fprintf (stderr, "profiling:%s:Invocation mismatch\n",
ptr->filename);
local_prg.runs = 0;
}
else
memcpy (&program, &local_prg, sizeof (program));
ptr->wkspc = base;
break;
}
gcov_seek (0, 0);
}
object.runs++;
object.arcs = ptr->counter_sections[arc_data_index].n_counters;
object.arc_sum = 0;
if (object.arc_max_one < object_max_one)
object.arc_max_one = object_max_one;
object.arc_sum_max += object_max_one;
/* Write out the data. */
gcov_write_unsigned (GCOV_DATA_MAGIC);
gcov_write_unsigned (GCOV_VERSION);
/* Write execution counts for each function. */
for (ix = 0; ix < ptr->n_counter_sections; ix++)
counters[ix] = ptr->counter_sections[ix].counters;
for (ix = ptr->n_functions, fn_info = ptr->functions; ix--; fn_info++)
{
/* Announce function. */
base = gcov_write_tag (GCOV_TAG_FUNCTION);
gcov_write_string (fn_info->name);
gcov_write_unsigned (fn_info->checksum);
gcov_write_length (base);
/* counters. */
for (f_sect_index = 0;
f_sect_index < fn_info->n_counter_sections;
f_sect_index++)
{
tag = fn_info->counter_sections[f_sect_index].tag;
for (sect_index = 0;
sect_index < ptr->n_counter_sections;
sect_index++)
if (ptr->counter_sections[sect_index].tag == tag)
break;
if (sect_index == ptr->n_counter_sections)
abort ();
base = gcov_write_tag (tag);
for (jx = fn_info->counter_sections[f_sect_index].n_counters; jx--;)
{
gcov_type count = *counters[sect_index]++;
if (tag == GCOV_TAG_ARC_COUNTS)
{
object.arc_sum += count;
if (object.arc_max_sum < count)
object.arc_max_sum = count;
}
gcov_write_counter (count);
}
gcov_write_length (base);
}
}
/* Object file summary. */
gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, &object);
Change gcov file interface to single file at a time. * gcov-io.h: Replace IN_LIBGCC1 with IN_LIBGCOV. Use IN_GCOV. Convert to C89 prototypes. (gcov_file, gcov_length, gcov_position, gcov_buffer, gcov_alloc, gcov_error, gcov_modified): New static variables. (gcov_open, gcov_close, gcov_read_bytes, gcov_write_bytes): New functions. (gcov_write_unsigned, gcov_write_counter, gcov_write_string, gcov_read_unsigned, gcov_read_counter, gcov_read_string): Adjust. (gcov_read_summary, gcov_write_summary): Adjust. (gcov_save_position, gcov_reserve_length, gcov_write_length): Adjust. (gcov_resync, gcov_skip, gcov_skip_string): Adjust. (da_file_open, da_file_close, da_file_eof, da_file_error): Remove. (da_file_position, da_file_seek, da_file_write, da_file_read): Remove. (gcov_error, gcov_eof, gcov_ok, gcov_time): New functions. * gcov.c (gcov_type): Don't typedef here. (IN_GCOV): #define (read_graph_file, read_count_file): Adjust. * gcov-dump.c (gcov_type): Don't typedef here. (IN_GCOV): #define. (tag_function, tag_blocks, tag_arcs, tag_lines, tag_arc_counts): Remove FILE parameter, adjust. (struct tag_format): Adjust proc member. (dump_file): Adjust. * libgcov.c (IN_LIBGCOV): #define. (gcov_exit): Adjust. * loop-init.c: Don't #include gcov-io.h * profile.c (struct counts_entry): New structure to hold counter values. (struct section_reference, struct da_index_entry): Remove. (bbg_file, da_file): Remove. (htab_counts_index_hash, htab_counts_index_eq, htab_counts_index_del): Replace with ... (htab_counts_entry_hash, htab_counts_entry_eq, htab_counts_entry_del): ... these. (cleanup_counts_index, index_counts_file): Remove. (read_counts_file): New function. (get_exec_counts): Adjust. (compute_branch_probabilities): Don't free the exec counts here. (branch_prob): Adjust. (init_branch_prob): Adjust. (end_branch_prob): Adjust. From-SVN: r65338
2003-04-07 21:37:12 +02:00
if (merging)
{
Change gcov file interface to single file at a time. * gcov-io.h: Replace IN_LIBGCC1 with IN_LIBGCOV. Use IN_GCOV. Convert to C89 prototypes. (gcov_file, gcov_length, gcov_position, gcov_buffer, gcov_alloc, gcov_error, gcov_modified): New static variables. (gcov_open, gcov_close, gcov_read_bytes, gcov_write_bytes): New functions. (gcov_write_unsigned, gcov_write_counter, gcov_write_string, gcov_read_unsigned, gcov_read_counter, gcov_read_string): Adjust. (gcov_read_summary, gcov_write_summary): Adjust. (gcov_save_position, gcov_reserve_length, gcov_write_length): Adjust. (gcov_resync, gcov_skip, gcov_skip_string): Adjust. (da_file_open, da_file_close, da_file_eof, da_file_error): Remove. (da_file_position, da_file_seek, da_file_write, da_file_read): Remove. (gcov_error, gcov_eof, gcov_ok, gcov_time): New functions. * gcov.c (gcov_type): Don't typedef here. (IN_GCOV): #define (read_graph_file, read_count_file): Adjust. * gcov-dump.c (gcov_type): Don't typedef here. (IN_GCOV): #define. (tag_function, tag_blocks, tag_arcs, tag_lines, tag_arc_counts): Remove FILE parameter, adjust. (struct tag_format): Adjust proc member. (dump_file): Adjust. * libgcov.c (IN_LIBGCOV): #define. (gcov_exit): Adjust. * loop-init.c: Don't #include gcov-io.h * profile.c (struct counts_entry): New structure to hold counter values. (struct section_reference, struct da_index_entry): Remove. (bbg_file, da_file): Remove. (htab_counts_index_hash, htab_counts_index_eq, htab_counts_index_del): Replace with ... (htab_counts_entry_hash, htab_counts_entry_eq, htab_counts_entry_del): ... these. (cleanup_counts_index, index_counts_file): Remove. (read_counts_file): New function. (get_exec_counts): Adjust. (compute_branch_probabilities): Don't free the exec counts here. (branch_prob): Adjust. (init_branch_prob): Adjust. (end_branch_prob): Adjust. From-SVN: r65338
2003-04-07 21:37:12 +02:00
ptr->wkspc = gcov_seek_end ();
gcov_write_summary (GCOV_TAG_PLACEHOLDER_SUMMARY, &program);
}
else if (ptr->wkspc)
{
/* Zap trailing program summary */
gcov_seek (ptr->wkspc, 0);
if (!local_prg.runs)
ptr->wkspc = 0;
gcov_write_unsigned (local_prg.runs
? GCOV_TAG_PLACEHOLDER_SUMMARY
: GCOV_TAG_INCORRECT_SUMMARY);
}
Change gcov file interface to single file at a time. * gcov-io.h: Replace IN_LIBGCC1 with IN_LIBGCOV. Use IN_GCOV. Convert to C89 prototypes. (gcov_file, gcov_length, gcov_position, gcov_buffer, gcov_alloc, gcov_error, gcov_modified): New static variables. (gcov_open, gcov_close, gcov_read_bytes, gcov_write_bytes): New functions. (gcov_write_unsigned, gcov_write_counter, gcov_write_string, gcov_read_unsigned, gcov_read_counter, gcov_read_string): Adjust. (gcov_read_summary, gcov_write_summary): Adjust. (gcov_save_position, gcov_reserve_length, gcov_write_length): Adjust. (gcov_resync, gcov_skip, gcov_skip_string): Adjust. (da_file_open, da_file_close, da_file_eof, da_file_error): Remove. (da_file_position, da_file_seek, da_file_write, da_file_read): Remove. (gcov_error, gcov_eof, gcov_ok, gcov_time): New functions. * gcov.c (gcov_type): Don't typedef here. (IN_GCOV): #define (read_graph_file, read_count_file): Adjust. * gcov-dump.c (gcov_type): Don't typedef here. (IN_GCOV): #define. (tag_function, tag_blocks, tag_arcs, tag_lines, tag_arc_counts): Remove FILE parameter, adjust. (struct tag_format): Adjust proc member. (dump_file): Adjust. * libgcov.c (IN_LIBGCOV): #define. (gcov_exit): Adjust. * loop-init.c: Don't #include gcov-io.h * profile.c (struct counts_entry): New structure to hold counter values. (struct section_reference, struct da_index_entry): Remove. (bbg_file, da_file): Remove. (htab_counts_index_hash, htab_counts_index_eq, htab_counts_index_del): Replace with ... (htab_counts_entry_hash, htab_counts_entry_eq, htab_counts_entry_del): ... these. (cleanup_counts_index, index_counts_file): Remove. (read_counts_file): New function. (get_exec_counts): Adjust. (compute_branch_probabilities): Don't free the exec counts here. (branch_prob): Adjust. (init_branch_prob): Adjust. (end_branch_prob): Adjust. From-SVN: r65338
2003-04-07 21:37:12 +02:00
if (gcov_close ())
{
fprintf (stderr, "profiling:%s:Error writing\n", ptr->filename);
ptr->filename = 0;
}
else
{
program_arcs += ptr->counter_sections[arc_data_index].n_counters;
program_sum += object.arc_sum;
if (program_max_sum < object.arc_max_sum)
program_max_sum = object.arc_max_sum;
}
free(counters);
}
/* Generate whole program statistics. */
program.runs++;
program.arcs = program_arcs;
program.arc_sum = program_sum;
if (program.arc_max_one < program_max_one)
program.arc_max_one = program_max_one;
if (program.arc_max_sum < program_max_sum)
program.arc_max_sum = program_max_sum;
program.arc_sum_max += program_max_one;
/* Upate whole program statistics. */
for (ptr = gcov_list; ptr; ptr = ptr->next)
if (ptr->filename && ptr->wkspc)
{
Change gcov file interface to single file at a time. * gcov-io.h: Replace IN_LIBGCC1 with IN_LIBGCOV. Use IN_GCOV. Convert to C89 prototypes. (gcov_file, gcov_length, gcov_position, gcov_buffer, gcov_alloc, gcov_error, gcov_modified): New static variables. (gcov_open, gcov_close, gcov_read_bytes, gcov_write_bytes): New functions. (gcov_write_unsigned, gcov_write_counter, gcov_write_string, gcov_read_unsigned, gcov_read_counter, gcov_read_string): Adjust. (gcov_read_summary, gcov_write_summary): Adjust. (gcov_save_position, gcov_reserve_length, gcov_write_length): Adjust. (gcov_resync, gcov_skip, gcov_skip_string): Adjust. (da_file_open, da_file_close, da_file_eof, da_file_error): Remove. (da_file_position, da_file_seek, da_file_write, da_file_read): Remove. (gcov_error, gcov_eof, gcov_ok, gcov_time): New functions. * gcov.c (gcov_type): Don't typedef here. (IN_GCOV): #define (read_graph_file, read_count_file): Adjust. * gcov-dump.c (gcov_type): Don't typedef here. (IN_GCOV): #define. (tag_function, tag_blocks, tag_arcs, tag_lines, tag_arc_counts): Remove FILE parameter, adjust. (struct tag_format): Adjust proc member. (dump_file): Adjust. * libgcov.c (IN_LIBGCOV): #define. (gcov_exit): Adjust. * loop-init.c: Don't #include gcov-io.h * profile.c (struct counts_entry): New structure to hold counter values. (struct section_reference, struct da_index_entry): Remove. (bbg_file, da_file): Remove. (htab_counts_index_hash, htab_counts_index_eq, htab_counts_index_del): Replace with ... (htab_counts_entry_hash, htab_counts_entry_eq, htab_counts_entry_del): ... these. (cleanup_counts_index, index_counts_file): Remove. (read_counts_file): New function. (get_exec_counts): Adjust. (compute_branch_probabilities): Don't free the exec counts here. (branch_prob): Adjust. (init_branch_prob): Adjust. (end_branch_prob): Adjust. From-SVN: r65338
2003-04-07 21:37:12 +02:00
if (!gcov_open (ptr->filename, 1))
{
fprintf (stderr, "profiling:%s:Cannot open\n", ptr->filename);
continue;
}
gcov_seek (ptr->wkspc, 0);
gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &program);
Change gcov file interface to single file at a time. * gcov-io.h: Replace IN_LIBGCC1 with IN_LIBGCOV. Use IN_GCOV. Convert to C89 prototypes. (gcov_file, gcov_length, gcov_position, gcov_buffer, gcov_alloc, gcov_error, gcov_modified): New static variables. (gcov_open, gcov_close, gcov_read_bytes, gcov_write_bytes): New functions. (gcov_write_unsigned, gcov_write_counter, gcov_write_string, gcov_read_unsigned, gcov_read_counter, gcov_read_string): Adjust. (gcov_read_summary, gcov_write_summary): Adjust. (gcov_save_position, gcov_reserve_length, gcov_write_length): Adjust. (gcov_resync, gcov_skip, gcov_skip_string): Adjust. (da_file_open, da_file_close, da_file_eof, da_file_error): Remove. (da_file_position, da_file_seek, da_file_write, da_file_read): Remove. (gcov_error, gcov_eof, gcov_ok, gcov_time): New functions. * gcov.c (gcov_type): Don't typedef here. (IN_GCOV): #define (read_graph_file, read_count_file): Adjust. * gcov-dump.c (gcov_type): Don't typedef here. (IN_GCOV): #define. (tag_function, tag_blocks, tag_arcs, tag_lines, tag_arc_counts): Remove FILE parameter, adjust. (struct tag_format): Adjust proc member. (dump_file): Adjust. * libgcov.c (IN_LIBGCOV): #define. (gcov_exit): Adjust. * loop-init.c: Don't #include gcov-io.h * profile.c (struct counts_entry): New structure to hold counter values. (struct section_reference, struct da_index_entry): Remove. (bbg_file, da_file): Remove. (htab_counts_index_hash, htab_counts_index_eq, htab_counts_index_del): Replace with ... (htab_counts_entry_hash, htab_counts_entry_eq, htab_counts_entry_del): ... these. (cleanup_counts_index, index_counts_file): Remove. (read_counts_file): New function. (get_exec_counts): Adjust. (compute_branch_probabilities): Don't free the exec counts here. (branch_prob): Adjust. (init_branch_prob): Adjust. (end_branch_prob): Adjust. From-SVN: r65338
2003-04-07 21:37:12 +02:00
if (gcov_close ())
fprintf (stderr, "profiling:%s:Error writing\n", ptr->filename);
}
}
/* Add a new object file onto the bb chain. Invoked automatically
when running an object file's global ctors. */
void
__gcov_init (struct gcov_info *info)
{
if (!info->version)
return;
if (info->version != GCOV_VERSION)
gcov_version_mismatch (info, info->version);
else
{
const char *ptr = info->filename;
unsigned crc32 = gcov_crc32;
do
{
unsigned ix;
unsigned value = *ptr << 24;
for (ix = 8; ix--; value <<= 1)
{
unsigned feedback;
feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
crc32 <<= 1;
crc32 ^= feedback;
}
}
while (*ptr++);
gcov_crc32 = crc32;
if (!gcov_list)
atexit (gcov_exit);
info->next = gcov_list;
gcov_list = info;
}
info->version = 0;
}
/* Called before fork or exec - write out profile information gathered so
far and reset it to zero. This avoids duplication or loss of the
profile information gathered so far. */
void
__gcov_flush (void)
{
struct gcov_info *ptr;
gcov_exit ();
for (ptr = gcov_list; ptr; ptr = ptr->next)
{
unsigned i, j;
for (j = 0; j < ptr->n_counter_sections; j++)
for (i = ptr->counter_sections[j].n_counters; i--;)
ptr->counter_sections[j].counters[i] = 0;
}
}
#endif /* inhibit_libc */