Commit 8733892f by Nathan Sidwell Committed by Nathan Sidwell

libgcc2.c (L_bb): Remove unneeded #includes.

	* libgcc2.c (L_bb): Remove unneeded #includes.
	(__global_counters, __gthreads_active): Remove unused globals.
	(__bb_exit_func): Merge counts into files rather than appending.
	* Makefile.in (INTERNAL_CFLAGS): Move COVERAGE_FLAGS from here ...
	(ALL_CFLAGS): ... to here.

From-SVN: r56250
parent f4769721
2002-08-13 Nathan Sidwell <nathan@codesourcery.com>
* libgcc2.c (L_bb): Remove unneeded #includes.
(__global_counters, __gthreads_active): Remove unused globals.
(__bb_exit_func): Merge counts into files rather than appending.
* Makefile.in (INTERNAL_CFLAGS): Move COVERAGE_FLAGS from here ...
(ALL_CFLAGS): ... to here.
2002-08-13 Denis Chertykov <denisc@overta.ru> 2002-08-13 Denis Chertykov <denisc@overta.ru>
* config/ip2k/ip2k.c (commands_in_file): Variable removed. * config/ip2k/ip2k.c (commands_in_file): Variable removed.
......
...@@ -594,13 +594,13 @@ all.indirect: $(ALL) ...@@ -594,13 +594,13 @@ all.indirect: $(ALL)
# IN_GCC distinguishes between code compiled into GCC itself and other # IN_GCC distinguishes between code compiled into GCC itself and other
# programs built during a bootstrap. # programs built during a bootstrap.
# autoconf inserts -DCROSS_COMPILE if we are building a cross compiler. # autoconf inserts -DCROSS_COMPILE if we are building a cross compiler.
INTERNAL_CFLAGS = -DIN_GCC @CROSS@ $(COVERAGE_FLAGS) INTERNAL_CFLAGS = -DIN_GCC @CROSS@
# This is the variable actually used when we compile. # This is the variable actually used when we compile.
# If you change this line, you probably also need to change the definition # If you change this line, you probably also need to change the definition
# of HOST_CFLAGS in build-make to match. # of HOST_CFLAGS in build-make to match.
ALL_CFLAGS = $(X_CFLAGS) $(T_CFLAGS) \ ALL_CFLAGS = $(X_CFLAGS) $(T_CFLAGS) \
$(CFLAGS) $(INTERNAL_CFLAGS) $(WARN_CFLAGS) $(XCFLAGS) @DEFS@ $(CFLAGS) $(INTERNAL_CFLAGS) $(COVERAGE_FLAGS) $(WARN_CFLAGS) $(XCFLAGS) @DEFS@
# Likewise. # Likewise.
ALL_CPPFLAGS = $(CPPFLAGS) $(X_CPPFLAGS) $(T_CPPFLAGS) ALL_CPPFLAGS = $(CPPFLAGS) $(X_CPPFLAGS) $(T_CPPFLAGS)
......
/* More subroutines needed by GCC output code on some machines. */ /* More subroutines needed by GCC output code on some machines. */
/* Compile this one with gcc. */ /* Compile this one with gcc. */
/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, /* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001 Free Software Foundation, Inc. 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -1243,7 +1243,7 @@ struct bb_function_info { ...@@ -1243,7 +1243,7 @@ struct bb_function_info {
const char *name; const char *name;
}; };
/* Structure emitted by -a */ /* Structure emitted by --profile-arcs */
struct bb struct bb
{ {
long zero_word; long zero_word;
...@@ -1259,14 +1259,11 @@ struct bb ...@@ -1259,14 +1259,11 @@ struct bb
#ifndef inhibit_libc #ifndef inhibit_libc
/* Simple minded basic block profiling output dumper for /* Arc profile dumper. Requires atexit and stdio. */
systems that don't provide tcov support. At present,
it requires atexit and stdio. */
#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
#include <stdio.h> #include <stdio.h>
#include "gbl-ctors.h"
#include "gcov-io.h" #include "gcov-io.h"
#include <string.h> #include <string.h>
#ifdef TARGET_HAS_F_SETLKW #ifdef TARGET_HAS_F_SETLKW
...@@ -1274,189 +1271,268 @@ struct bb ...@@ -1274,189 +1271,268 @@ struct bb
#include <errno.h> #include <errno.h>
#endif #endif
#include <gthr.h> /* Chain of per-object file bb structures. */
static struct bb *bb_head; static struct bb *bb_head;
int __global_counters = 0, __gthreads_active = 0; /* Dump the coverage counts. We merge with existing counts when
possible, to avoid growing the .da files ad infinitum. */
void void
__bb_exit_func (void) __bb_exit_func (void)
{ {
FILE *da_file;
struct bb *ptr; struct bb *ptr;
long n_counters_p = 0; int i;
gcov_type max_counter_p = 0; gcov_type program_sum = 0;
gcov_type sum_counters_p = 0; gcov_type program_max = 0;
long program_arcs = 0;
gcov_type merged_sum = 0;
gcov_type merged_max = 0;
long merged_arcs = 0;
if (bb_head == 0) #if defined (TARGET_HAS_F_SETLKW)
return; struct flock s_flock;
/* Calculate overall "statistics". */ s_flock.l_type = F_WRLCK;
s_flock.l_whence = SEEK_SET;
s_flock.l_start = 0;
s_flock.l_len = 0; /* Until EOF. */
s_flock.l_pid = getpid ();
#endif
for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next) /* Non-merged stats for this program. */
for (ptr = bb_head; ptr; ptr = ptr->next)
{ {
int i;
n_counters_p += ptr->ncounts;
for (i = 0; i < ptr->ncounts; i++) for (i = 0; i < ptr->ncounts; i++)
{ {
sum_counters_p += ptr->counts[i]; program_sum += ptr->counts[i];
if (ptr->counts[i] > max_counter_p) if (ptr->counts[i] > program_max)
max_counter_p = ptr->counts[i]; program_max = ptr->counts[i];
} }
program_arcs += ptr->ncounts;
} }
for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next) for (ptr = bb_head; ptr; ptr = ptr->next)
{ {
gcov_type max_counter_o = 0; FILE *da_file;
gcov_type sum_counters_o = 0; gcov_type object_max = 0;
int i; gcov_type object_sum = 0;
long object_functions = 0;
int merging = 0;
int error = 0;
struct bb_function_info *fn_info;
gcov_type *count_ptr;
/* Calculate the per-object statistics. */ /* Open for modification */
da_file = fopen (ptr->filename, "r+b");
for (i = 0; i < ptr->ncounts; i++) if (da_file)
merging = 1;
else
{ {
sum_counters_o += ptr->counts[i]; /* Try for appending */
if (ptr->counts[i] > max_counter_o)
max_counter_o = ptr->counts[i];
}
/* open the file for appending, creating it if necessary. */
da_file = fopen (ptr->filename, "ab"); da_file = fopen (ptr->filename, "ab");
/* Some old systems might not allow the 'b' mode modifier. /* Some old systems might not allow the 'b' mode modifier.
Therefore, try to open without it. This can lead to a race Therefore, try to open without it. This can lead to a
condition so that when you delete and re-create the file, the race condition so that when you delete and re-create the
file might be opened in text mode, but then, you shouldn't file, the file might be opened in text mode, but then,
delete the file in the first place. */ you shouldn't delete the file in the first place. */
if (da_file == 0) if (!da_file)
da_file = fopen (ptr->filename, "a"); da_file = fopen (ptr->filename, "a");
if (da_file == 0) }
if (!da_file)
{ {
fprintf (stderr, "arc profiling: Can't open output file %s.\n", fprintf (stderr, "arc profiling: Can't open output file %s.\n",
ptr->filename); ptr->filename);
ptr->filename = 0;
continue; continue;
} }
#if defined (TARGET_HAS_F_SETLKW)
/* After a fork, another process might try to read and/or write /* After a fork, another process might try to read and/or write
the same file simultanously. So if we can, lock the file to the same file simultanously. So if we can, lock the file to
avoid race conditions. */ avoid race conditions. */
#if defined (TARGET_HAS_F_SETLKW)
{
struct flock s_flock;
s_flock.l_type = F_WRLCK;
s_flock.l_whence = SEEK_SET;
s_flock.l_start = 0;
s_flock.l_len = 1;
s_flock.l_pid = getpid ();
while (fcntl (fileno (da_file), F_SETLKW, &s_flock) while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
&& errno == EINTR); && errno == EINTR)
} continue;
#endif #endif
for (fn_info = ptr->function_infos; fn_info->arc_count != -1; fn_info++)
object_functions++;
if (__write_long (-123, da_file, 4) != 0) /* magic */ if (merging)
{ {
fprintf (stderr, "arc profiling: Error writing output file %s.\n", /* Merge data from file. */
long tmp_long;
gcov_type tmp_gcov;
if (/* magic */
(__read_long (&tmp_long, da_file, 4) || tmp_long != -123l)
/* functions in object file. */
|| (__read_long (&tmp_long, da_file, 4)
|| tmp_long != object_functions)
/* extension block, skipped */
|| (__read_long (&tmp_long, da_file, 4)
|| fseek (da_file, tmp_long, SEEK_CUR)))
{
read_error:;
fprintf (stderr, "arc profiling: Error merging output file %s.\n",
ptr->filename); ptr->filename);
clearerr (da_file);
} }
else else
{ {
/* Merge execution counts for each function. */
struct bb_function_info *fn_info; count_ptr = ptr->counts;
gcov_type *count_ptr = ptr->counts;
int i;
int count_functions = 0;
for (fn_info = ptr->function_infos; fn_info->arc_count != -1; for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
fn_info++) fn_info++)
count_functions++; {
if (/* function name delim */
(__read_long (&tmp_long, da_file, 4)
|| tmp_long != -1)
/* function name length */
|| (__read_long (&tmp_long, da_file, 4)
|| tmp_long != (long) strlen (fn_info->name))
/* skip string */
|| fseek (da_file, ((tmp_long + 1) + 3) & ~3, SEEK_CUR)
/* function name delim */
|| (__read_long (&tmp_long, da_file, 4)
|| tmp_long != -1))
goto read_error;
if (/* function checksum */
(__read_long (&tmp_long, da_file, 4)
|| tmp_long != fn_info->checksum)
/* arc count */
|| (__read_long (&tmp_long, da_file, 4)
|| tmp_long != fn_info->arc_count))
goto read_error;
/* number of functions in this block. */ for (i = fn_info->arc_count; i > 0; i--, count_ptr++)
__write_long (count_functions, da_file, 4); if (__read_gcov_type (&tmp_gcov, da_file, 8))
goto read_error;
else
*count_ptr += tmp_gcov;
}
}
fseek (da_file, 0, SEEK_SET);
}
/* Calculate the per-object statistics. */
for (i = 0; i < ptr->ncounts; i++)
{
object_sum += ptr->counts[i];
if (ptr->counts[i] > object_max)
object_max = ptr->counts[i];
}
merged_sum += object_sum;
if (merged_max < object_max)
merged_max = object_max;
merged_arcs += ptr->ncounts;
/* Write out the data. */
if (/* magic */
__write_long (-123, da_file, 4)
/* number of functions in object file. */
|| __write_long (object_functions, da_file, 4)
/* length of extra data in bytes. */ /* length of extra data in bytes. */
__write_long ((4 + 8 + 8) + (4 + 8 + 8), da_file, 4); || __write_long ((4 + 8 + 8) + (4 + 8 + 8), da_file, 4)
/* overall statistics. */ /* whole program statistics. If merging write per-object
/* number of counters. */ now, rewrite later */
__write_long (n_counters_p, da_file, 4); /* number of instrumented arcs. */
|| __write_long (merging ? ptr->ncounts : program_arcs, da_file, 4)
/* sum of counters. */ /* sum of counters. */
__write_gcov_type (sum_counters_p, da_file, 8); || __write_gcov_type (merging ? object_sum : program_sum, da_file, 8)
/* maximal counter. */ /* maximal counter. */
__write_gcov_type (max_counter_p, da_file, 8); || __write_gcov_type (merging ? object_max : program_max, da_file, 8)
/* per-object statistics. */ /* per-object statistics. */
/* number of counters. */ /* number of counters. */
__write_long (ptr->ncounts, da_file, 4); || __write_long (ptr->ncounts, da_file, 4)
/* sum of counters. */ /* sum of counters. */
__write_gcov_type (sum_counters_o, da_file, 8); || __write_gcov_type (object_sum, da_file, 8)
/* maximal counter. */ /* maximal counter. */
__write_gcov_type (max_counter_o, da_file, 8); || __write_gcov_type (object_max, da_file, 8))
/* write execution counts for each function. */
for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
fn_info++)
{
/* new function. */
if (__write_gcov_string
(fn_info->name, strlen (fn_info->name), da_file, -1) != 0)
{ {
fprintf (stderr, write_error:;
"arc profiling: Error writing output file %s.\n", fprintf (stderr, "arc profiling: Error writing output file %s.\n",
ptr->filename); ptr->filename);
break; error = 1;
} }
else
{
/* Write execution counts for each function. */
count_ptr = ptr->counts;
if (__write_long (fn_info->checksum, da_file, 4) != 0) for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
fn_info++)
{ {
fprintf (stderr, if (__write_gcov_string (fn_info->name,
"arc profiling: Error writing output file %s.\n", strlen (fn_info->name), da_file, -1)
ptr->filename); || __write_long (fn_info->checksum, da_file, 4)
break; || __write_long (fn_info->arc_count, da_file, 4))
goto write_error;
for (i = fn_info->arc_count; i > 0; i--, count_ptr++)
if (__write_gcov_type (*count_ptr, da_file, 8))
goto write_error; /* RIP Edsger Dijkstra */
}
} }
if (__write_long (fn_info->arc_count, da_file, 4) != 0) if (fclose (da_file))
{ {
fprintf (stderr, fprintf (stderr, "arc profiling: Error closing output file %s.\n",
"arc profiling: Error writing output file %s.\n",
ptr->filename); ptr->filename);
break; error = 1;
}
if (error || !merging)
ptr->filename = 0;
} }
for (i = fn_info->arc_count; i > 0; i--, count_ptr++) /* Upate whole program statistics. */
for (ptr = bb_head; ptr; ptr = ptr->next)
if (ptr->filename)
{ {
if (__write_gcov_type (*count_ptr, da_file, 8) != 0) FILE *da_file;
break;
}
if (i) /* there was an error */ da_file = fopen (ptr->filename, "r+b");
if (!da_file)
{ {
fprintf (stderr, fprintf (stderr, "arc profiling: Cannot reopen %s.\n",
"arc profiling: Error writing output file %s.\n",
ptr->filename); ptr->filename);
break; continue;
}
}
} }
if (fclose (da_file) != 0) #if defined (TARGET_HAS_F_SETLKW)
fprintf (stderr, "arc profiling: Error closing output file %s.\n", while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
&& errno == EINTR)
continue;
#endif
if (fseek (da_file, 4 * 3, SEEK_SET)
/* number of instrumented arcs. */
|| __write_long (program_arcs, da_file, 4)
/* sum of counters. */
|| __write_gcov_type (program_sum, da_file, 8)
/* maximal counter. */
|| __write_gcov_type (program_max, da_file, 8))
fprintf (stderr, "arc profiling: Error updating program header %s.\n",
ptr->filename);
if (fclose (da_file))
fprintf (stderr, "arc profiling: Error reclosing %s\n",
ptr->filename); ptr->filename);
} }
} }
/* Add a new object file onto the bb chain. Invoked automatically
when running an object file's global ctors. */
void void
__bb_init_func (struct bb *blocks) __bb_init_func (struct bb *blocks)
{ {
/* User is supposed to check whether the first word is non-0,
but just in case.... */
if (blocks->zero_word) if (blocks->zero_word)
return; return;
...@@ -1473,6 +1549,7 @@ __bb_init_func (struct bb *blocks) ...@@ -1473,6 +1549,7 @@ __bb_init_func (struct bb *blocks)
/* Called before fork or exec - write out profile information gathered so /* Called before fork or exec - write out profile information gathered so
far and reset it to zero. This avoids duplication or loss of the far and reset it to zero. This avoids duplication or loss of the
profile information gathered so far. */ profile information gathered so far. */
void void
__bb_fork_func (void) __bb_fork_func (void)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment