Commit 4303c581 by Nathan Sidwell Committed by Nathan Sidwell

Makefile.in (LIBGCOV_INTERFACE): Move _gcov_dump ...

	* Makefile.in (LIBGCOV_INTERFACE): Move _gcov_dump ...
	(LIBGCOV_DRIVER): ... to here.
	* libgcov.h (gcov_do_dump): New #define.
	(struct gcov_root): New.
	(__gcov_root): New declaration.
	(__gcov_dump_one): Declare.
	* libgcov-driver.c (gcov_list, gcov_dump_complete,
	run_accounted): Delete.
	(gcov_compute_histogram): Add LIST argument, adjust.
	(compute_summary): Adjust gcov_compute_histogram call.
	(gcov_do_dump): Not hidden, static in libgcov.
	(gcov_clear): Move  to interface.c.
	(__gcov_dump_one): New, broken out of ...
	(gcov_exit): ... here.  Make static.
	(__gcov_root): New.
	(__gcov_init): Adjust.
	* libgcov-interface.c (gcov_clear, gcov_exit): Remove
	declarations.
	(__gcov_flush): Use __gcov_dump_one and __gcov_reset.
	(gcov_clear): Moved from driver.c.   Add LIST argument.
	(__gcov_reset): Adjust for changed interfaces.
	(__gcov_fork): Remove local declaration of __gcov_flush_mx.

From-SVN: r213719
parent 8bd8ef50
2014-08-07 Nathan Sidwell <nathan@acm.org>
* Makefile.in (LIBGCOV_INTERFACE): Move _gcov_dump ...
(LIBGCOV_DRIVER): ... to here.
* libgcov.h (gcov_do_dump): New #define.
(struct gcov_root): New.
(__gcov_root): New declaration.
(__gcov_dump_one): Declare.
* libgcov-driver.c (gcov_list, gcov_dump_complete,
run_accounted): Delete.
(gcov_compute_histogram): Add LIST argument, adjust.
(compute_summary): Adjust gcov_compute_histogram call.
(gcov_do_dump): Not hidden, static in libgcov.
(gcov_clear): Move to interface.c.
(__gcov_dump_one): New, broken out of ...
(gcov_exit): ... here. Make static.
(__gcov_root): New.
(__gcov_init): Adjust.
* libgcov-interface.c (gcov_clear, gcov_exit): Remove
declarations.
(__gcov_flush): Use __gcov_dump_one and __gcov_reset.
(gcov_clear): Moved from driver.c. Add LIST argument.
(__gcov_reset): Adjust for changed interfaces.
(__gcov_fork): Remove local declaration of __gcov_flush_mx.
2014-08-04 Rohit <rohitarulraj@freescale.com> 2014-08-04 Rohit <rohitarulraj@freescale.com>
PR target/60102 PR target/60102
......
...@@ -859,9 +859,8 @@ LIBGCOV_PROFILER = _gcov_interval_profiler _gcov_pow2_profiler \ ...@@ -859,9 +859,8 @@ LIBGCOV_PROFILER = _gcov_interval_profiler _gcov_pow2_profiler \
_gcov_average_profiler _gcov_ior_profiler \ _gcov_average_profiler _gcov_ior_profiler \
_gcov_indirect_call_profiler_v2 _gcov_time_profiler _gcov_indirect_call_profiler_v2 _gcov_time_profiler
LIBGCOV_INTERFACE = _gcov_flush _gcov_fork _gcov_execl _gcov_execlp \ LIBGCOV_INTERFACE = _gcov_flush _gcov_fork _gcov_execl _gcov_execlp \
_gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset \ _gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset
_gcov_dump LIBGCOV_DRIVER = _gcov _gcov_dump
LIBGCOV_DRIVER = _gcov
libgcov-merge-objects = $(patsubst %,%$(objext),$(LIBGCOV_MERGE)) libgcov-merge-objects = $(patsubst %,%$(objext),$(LIBGCOV_MERGE))
libgcov-profiler-objects = $(patsubst %,%$(objext),$(LIBGCOV_PROFILER)) libgcov-profiler-objects = $(patsubst %,%$(objext),$(LIBGCOV_PROFILER))
......
...@@ -73,16 +73,6 @@ struct gcov_filename ...@@ -73,16 +73,6 @@ struct gcov_filename
size_t prefix; /* chars to prepend to filename */ size_t prefix; /* chars to prepend to filename */
}; };
/* Chain of per-object gcov structures. */
#ifndef IN_GCOV_TOOL
/* We need to expose this static variable when compiling for gcov-tool. */
static
#endif
struct gcov_info *gcov_list;
/* Flag when the profile has already been dumped via __gcov_dump(). */
static int gcov_dump_complete;
static struct gcov_fn_buffer * static struct gcov_fn_buffer *
free_fn_data (const struct gcov_info *gi_ptr, struct gcov_fn_buffer *buffer, free_fn_data (const struct gcov_info *gi_ptr, struct gcov_fn_buffer *buffer,
unsigned limit) unsigned limit)
...@@ -222,7 +212,7 @@ gcov_histogram_insert(gcov_bucket_type *histogram, gcov_type value) ...@@ -222,7 +212,7 @@ gcov_histogram_insert(gcov_bucket_type *histogram, gcov_type value)
/* Computes a histogram of the arc counters to place in the summary SUM. */ /* Computes a histogram of the arc counters to place in the summary SUM. */
static void static void
gcov_compute_histogram (struct gcov_summary *sum) gcov_compute_histogram (struct gcov_info *list, struct gcov_summary *sum)
{ {
struct gcov_info *gi_ptr; struct gcov_info *gi_ptr;
const struct gcov_fn_info *gfi_ptr; const struct gcov_fn_info *gfi_ptr;
...@@ -248,7 +238,7 @@ gcov_compute_histogram (struct gcov_summary *sum) ...@@ -248,7 +238,7 @@ gcov_compute_histogram (struct gcov_summary *sum)
/* Walk through all the per-object structures and record each of /* Walk through all the per-object structures and record each of
the count values in histogram. */ the count values in histogram. */
for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next) for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
{ {
if (!gi_ptr->merge[t_ix]) if (!gi_ptr->merge[t_ix])
continue; continue;
...@@ -279,10 +269,6 @@ gcov_compute_histogram (struct gcov_summary *sum) ...@@ -279,10 +269,6 @@ gcov_compute_histogram (struct gcov_summary *sum)
static struct gcov_fn_buffer *fn_buffer; static struct gcov_fn_buffer *fn_buffer;
/* buffer for summary from other programs to be written out. */ /* buffer for summary from other programs to be written out. */
static struct gcov_summary_buffer *sum_buffer; static struct gcov_summary_buffer *sum_buffer;
/* If application calls fork or exec multiple times, we end up storing
profile repeadely. We should not account this as multiple runs or
functions executed once may mistakely become cold. */
static int run_accounted = 0;
/* This function computes the program level summary and the histo-gram. /* This function computes the program level summary and the histo-gram.
It computes and returns CRC32 and stored summary in THIS_PRG. It computes and returns CRC32 and stored summary in THIS_PRG.
...@@ -346,7 +332,7 @@ compute_summary (struct gcov_info *list, struct gcov_summary *this_prg, ...@@ -346,7 +332,7 @@ compute_summary (struct gcov_info *list, struct gcov_summary *this_prg,
} }
} }
} }
gcov_compute_histogram (this_prg); gcov_compute_histogram (list, this_prg);
return crc32; return crc32;
} }
...@@ -752,7 +738,10 @@ read_fatal:; ...@@ -752,7 +738,10 @@ read_fatal:;
summary and then traverses gcov_list list and dumps the gcov_info summary and then traverses gcov_list list and dumps the gcov_info
objects one by one. */ objects one by one. */
void ATTRIBUTE_HIDDEN #if !IN_GCOV_TOOL
static
#endif
void
gcov_do_dump (struct gcov_info *list, int run_counted) gcov_do_dump (struct gcov_info *list, int run_counted)
{ {
struct gcov_info *gi_ptr; struct gcov_info *gi_ptr;
...@@ -777,50 +766,24 @@ gcov_do_dump (struct gcov_info *list, int run_counted) ...@@ -777,50 +766,24 @@ gcov_do_dump (struct gcov_info *list, int run_counted)
#if !IN_GCOV_TOOL #if !IN_GCOV_TOOL
void void
gcov_exit (void) __gcov_dump_one (struct gcov_root *root)
{ {
/* Prevent the counters from being dumped a second time on exit when the if (root->dumped)
application already wrote out the profile using __gcov_dump(). */
if (gcov_dump_complete)
return; return;
gcov_dump_complete = 1; gcov_do_dump (root->list, root->run_counted);
gcov_do_dump (gcov_list, run_accounted); root->dumped = 1;
root->run_counted = 1;
run_accounted = 1;
} }
/* Reset all counters to zero. */ /* Per-program/shared-object gcov state. */
struct gcov_root __gcov_root;
void static void
gcov_clear (void) gcov_exit (void)
{ {
const struct gcov_info *gi_ptr; __gcov_dump_one (&__gcov_root);
gcov_dump_complete = 0;
for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
{
unsigned f_ix;
for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
{
unsigned t_ix;
const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix];
if (!gfi_ptr || gfi_ptr->key != gi_ptr)
continue;
const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs;
for (t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++)
{
if (!gi_ptr->merge[t_ix])
continue;
memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
ci_ptr++;
}
}
}
} }
/* Add a new object file onto the bb chain. Invoked automatically /* Add a new object file onto the bb chain. Invoked automatically
...@@ -833,11 +796,11 @@ __gcov_init (struct gcov_info *info) ...@@ -833,11 +796,11 @@ __gcov_init (struct gcov_info *info)
return; return;
if (gcov_version (info, info->version, 0)) if (gcov_version (info, info->version, 0))
{ {
if (!gcov_list) if (!__gcov_root.list)
atexit (gcov_exit); atexit (gcov_exit);
info->next = gcov_list; info->next = __gcov_root.list;
gcov_list = info; __gcov_root.list = info;
} }
info->version = 0; info->version = 0;
} }
......
...@@ -42,8 +42,7 @@ void __gcov_dump (void) {} ...@@ -42,8 +42,7 @@ void __gcov_dump (void) {}
#else #else
extern void gcov_clear (void) ATTRIBUTE_HIDDEN; extern __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
extern void gcov_exit (void) ATTRIBUTE_HIDDEN;
extern __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN; extern __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
#ifdef L_gcov_flush #ifdef L_gcov_flush
...@@ -77,8 +76,8 @@ __gcov_flush (void) ...@@ -77,8 +76,8 @@ __gcov_flush (void)
init_mx_once (); init_mx_once ();
__gthread_mutex_lock (&__gcov_flush_mx); __gthread_mutex_lock (&__gcov_flush_mx);
gcov_exit (); __gcov_dump_one (&__gcov_root);
gcov_clear (); __gcov_reset ();
__gthread_mutex_unlock (&__gcov_flush_mx); __gthread_mutex_unlock (&__gcov_flush_mx);
} }
...@@ -87,31 +86,61 @@ __gcov_flush (void) ...@@ -87,31 +86,61 @@ __gcov_flush (void)
#ifdef L_gcov_reset #ifdef L_gcov_reset
/* Reset all counters to zero. */
static void
gcov_clear (const struct gcov_info *list)
{
const struct gcov_info *gi_ptr;
for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
{
unsigned f_ix;
for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
{
unsigned t_ix;
const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix];
if (!gfi_ptr || gfi_ptr->key != gi_ptr)
continue;
const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs;
for (t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++)
{
if (!gi_ptr->merge[t_ix])
continue;
memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
ci_ptr++;
}
}
}
}
/* Function that can be called from application to reset counters to zero, /* Function that can be called from application to reset counters to zero,
in order to collect profile in region of interest. */ in order to collect profile in region of interest. */
void void
__gcov_reset (void) __gcov_reset (void)
{ {
gcov_clear (); gcov_clear (__gcov_root.list);
__gcov_root.dumped = 0;
} }
#endif /* L_gcov_reset */ #endif /* L_gcov_reset */
#ifdef L_gcov_dump #ifdef L_gcov_dump
/* Function that can be called from application to write profile collected /* Function that can be called from application to write profile collected
so far, in order to collect profile in region of interest. */ so far, in order to collect profile in region of interest. */
void void
__gcov_dump (void) __gcov_dump (void)
{ {
gcov_exit (); __gcov_dump_one (&__gcov_root);
} }
#endif /* L_gcov_dump */ #endif /* L_gcov_dump */
#ifdef L_gcov_fork #ifdef L_gcov_fork
/* A wrapper for the fork function. Flushes the accumulated profiling data, so /* A wrapper for the fork function. Flushes the accumulated profiling data, so
that they are not counted twice. */ that they are not counted twice. */
...@@ -120,7 +149,6 @@ pid_t ...@@ -120,7 +149,6 @@ pid_t
__gcov_fork (void) __gcov_fork (void)
{ {
pid_t pid; pid_t pid;
extern __gthread_mutex_t __gcov_flush_mx;
__gcov_flush (); __gcov_flush ();
pid = fork (); pid = fork ();
if (pid == 0) if (pid == 0)
......
...@@ -100,7 +100,6 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI))); ...@@ -100,7 +100,6 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI)));
#define gcov_read_unsigned __gcov_read_unsigned #define gcov_read_unsigned __gcov_read_unsigned
#define gcov_read_counter __gcov_read_counter #define gcov_read_counter __gcov_read_counter
#define gcov_read_summary __gcov_read_summary #define gcov_read_summary __gcov_read_summary
#define gcov_do_dump __gcov_do_dump
#else /* IN_GCOV_TOOL */ #else /* IN_GCOV_TOOL */
/* About the host. */ /* About the host. */
...@@ -207,6 +206,19 @@ struct gcov_info ...@@ -207,6 +206,19 @@ struct gcov_info
#endif /* !IN_GCOV_TOOL */ #endif /* !IN_GCOV_TOOL */
}; };
/* Root of a program/shared-object state */
struct gcov_root
{
struct gcov_info *list;
unsigned dumped : 1; /* counts have been dumped. */
unsigned run_counted : 1; /* run has been accounted for. */
};
extern struct gcov_root __gcov_root ATTRIBUTE_HIDDEN;
/* Dump a set of gcov objects. */
extern void __gcov_dump_one (struct gcov_root *) ATTRIBUTE_HIDDEN;
/* Register a new object file module. */ /* Register a new object file module. */
extern void __gcov_init (struct gcov_info *) ATTRIBUTE_HIDDEN; extern void __gcov_init (struct gcov_info *) ATTRIBUTE_HIDDEN;
......
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