summaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2014-08-07 18:02:06 +0000
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2014-08-07 18:02:06 +0000
commit859fa1a929899e98127696afc9895fe33f2123e1 (patch)
tree96f601ae4d1e3bbc82671ac85806d78d72ba85a0 /libgcc
parentf59ea09778e927f6c947ee7347f97aa21ada6f38 (diff)
downloadgcc-859fa1a929899e98127696afc9895fe33f2123e1.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@213719 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog25
-rw-r--r--libgcc/Makefile.in5
-rw-r--r--libgcc/libgcov-driver.c77
-rw-r--r--libgcc/libgcov-interface.c46
-rw-r--r--libgcc/libgcov.h14
5 files changed, 97 insertions, 70 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index e1456587771..911c16d3e3e 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,28 @@
+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>
PR target/60102
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index f37515ece31..e9caad3eeec 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -859,9 +859,8 @@ LIBGCOV_PROFILER = _gcov_interval_profiler _gcov_pow2_profiler \
_gcov_average_profiler _gcov_ior_profiler \
_gcov_indirect_call_profiler_v2 _gcov_time_profiler
LIBGCOV_INTERFACE = _gcov_flush _gcov_fork _gcov_execl _gcov_execlp \
- _gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset \
- _gcov_dump
-LIBGCOV_DRIVER = _gcov
+ _gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset
+LIBGCOV_DRIVER = _gcov _gcov_dump
libgcov-merge-objects = $(patsubst %,%$(objext),$(LIBGCOV_MERGE))
libgcov-profiler-objects = $(patsubst %,%$(objext),$(LIBGCOV_PROFILER))
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 50755358d6e..34c58cd5fec 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -73,16 +73,6 @@ struct gcov_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 *
free_fn_data (const struct gcov_info *gi_ptr, struct gcov_fn_buffer *buffer,
unsigned limit)
@@ -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. */
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;
const struct gcov_fn_info *gfi_ptr;
@@ -248,7 +238,7 @@ gcov_compute_histogram (struct gcov_summary *sum)
/* Walk through all the per-object structures and record each of
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])
continue;
@@ -279,10 +269,6 @@ gcov_compute_histogram (struct gcov_summary *sum)
static struct gcov_fn_buffer *fn_buffer;
/* buffer for summary from other programs to be written out. */
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.
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,
}
}
}
- gcov_compute_histogram (this_prg);
+ gcov_compute_histogram (list, this_prg);
return crc32;
}
@@ -752,7 +738,10 @@ read_fatal:;
summary and then traverses gcov_list list and dumps the gcov_info
objects one by one. */
-void ATTRIBUTE_HIDDEN
+#if !IN_GCOV_TOOL
+static
+#endif
+void
gcov_do_dump (struct gcov_info *list, int run_counted)
{
struct gcov_info *gi_ptr;
@@ -777,50 +766,24 @@ gcov_do_dump (struct gcov_info *list, int run_counted)
#if !IN_GCOV_TOOL
void
-gcov_exit (void)
+__gcov_dump_one (struct gcov_root *root)
{
- /* Prevent the counters from being dumped a second time on exit when the
- application already wrote out the profile using __gcov_dump(). */
- if (gcov_dump_complete)
+ if (root->dumped)
return;
- gcov_dump_complete = 1;
-
- gcov_do_dump (gcov_list, run_accounted);
+ gcov_do_dump (root->list, root->run_counted);
- run_accounted = 1;
+ root->dumped = 1;
+ root->run_counted = 1;
}
-/* Reset all counters to zero. */
+/* Per-program/shared-object gcov state. */
+struct gcov_root __gcov_root;
-void
-gcov_clear (void)
+static void
+gcov_exit (void)
{
- const struct gcov_info *gi_ptr;
-
- 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++;
- }
- }
- }
+ __gcov_dump_one (&__gcov_root);
}
/* Add a new object file onto the bb chain. Invoked automatically
@@ -833,11 +796,11 @@ __gcov_init (struct gcov_info *info)
return;
if (gcov_version (info, info->version, 0))
{
- if (!gcov_list)
+ if (!__gcov_root.list)
atexit (gcov_exit);
- info->next = gcov_list;
- gcov_list = info;
+ info->next = __gcov_root.list;
+ __gcov_root.list = info;
}
info->version = 0;
}
diff --git a/libgcc/libgcov-interface.c b/libgcc/libgcov-interface.c
index d4a7f50c22f..f73666c1367 100644
--- a/libgcc/libgcov-interface.c
+++ b/libgcc/libgcov-interface.c
@@ -42,8 +42,7 @@ void __gcov_dump (void) {}
#else
-extern void gcov_clear (void) 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
@@ -77,8 +76,8 @@ __gcov_flush (void)
init_mx_once ();
__gthread_mutex_lock (&__gcov_flush_mx);
- gcov_exit ();
- gcov_clear ();
+ __gcov_dump_one (&__gcov_root);
+ __gcov_reset ();
__gthread_mutex_unlock (&__gcov_flush_mx);
}
@@ -87,31 +86,61 @@ __gcov_flush (void)
#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,
in order to collect profile in region of interest. */
void
__gcov_reset (void)
{
- gcov_clear ();
+ gcov_clear (__gcov_root.list);
+ __gcov_root.dumped = 0;
}
#endif /* L_gcov_reset */
#ifdef L_gcov_dump
-
/* Function that can be called from application to write profile collected
so far, in order to collect profile in region of interest. */
void
__gcov_dump (void)
{
- gcov_exit ();
+ __gcov_dump_one (&__gcov_root);
}
#endif /* L_gcov_dump */
-
#ifdef L_gcov_fork
/* A wrapper for the fork function. Flushes the accumulated profiling data, so
that they are not counted twice. */
@@ -120,7 +149,6 @@ pid_t
__gcov_fork (void)
{
pid_t pid;
- extern __gthread_mutex_t __gcov_flush_mx;
__gcov_flush ();
pid = fork ();
if (pid == 0)
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index 618a4d5b5d9..dfef181ce1a 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -100,7 +100,6 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI)));
#define gcov_read_unsigned __gcov_read_unsigned
#define gcov_read_counter __gcov_read_counter
#define gcov_read_summary __gcov_read_summary
-#define gcov_do_dump __gcov_do_dump
#else /* IN_GCOV_TOOL */
/* About the host. */
@@ -207,6 +206,19 @@ struct gcov_info
#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. */
extern void __gcov_init (struct gcov_info *) ATTRIBUTE_HIDDEN;