gcc/libgcc/libgcov-interface.c
Rong Xu d6d3f03341 The patch re-factors libgcov.c to make it better modulelized.
2013-11-12  Rong Xu  <xur@google.com>

The patch re-factors libgcov.c to make it better modulelized.
It contains two pieces of work:
1. break gcov_exit() into the following structure:
   gcov_exit()
      --> gcov_exit_compute_summary()
      --> allocate_filename_struct()
          for gi_ptr in gcov_list
            --> gcov_exit_dump_gcov()
                   --> gcov_exit_open_gcda_file()
                   --> gcov_exit_merge_gcda ()
                   --> gcov_exit_merge_summary ()
                   --> gcov_exit_write_gcda ()
2. split libgcov.c into the following files:
     libgcov-profiler.c
     libgcov-merge.c
     libgcov-interface.c
     libgcov-driver.c
       libgcov-driver-system.c (source included into libgcov-driver.c)

	* libgcc/libgcov.c: Delete as part of re-factoring.
	* gcc/gcov-io.h (__gcov_indirect_call_profiler): Add the decl to
        avoid warning.
	* libgcc/libgcov-interface.c (init_mx): Moved from libgcov.c.
	(init_mx_once): Ditto.
	(__gcov_flush): Ditto.
	(__gcov_reset): Ditto.
	(__gcov_dump): Ditto.
	(__gcov_fork): Ditto.
	(__gcov_execl): Ditto.
	(__gcov_execlp): Ditto.
	(__gcov_execle): Ditto.
	(__gcov_execv): Ditto.
	(__gcov_execvp): Ditto.
	(__gcov_execve): Ditto.
        * libgcc/libgcov-merge.c (__gcov_merge_time_profile): Moved from
        libgcov.c.
	(__gcov_merge_add): Ditto.
	(__gcov_merge_ior): Ditto.
	(__gcov_merge_single): Ditto.
	(__gcov_merge_delta): Ditto.
	* libgcc/libgcov-profiler.c 
	(__gcov_interval_profiler): Ditto.
	(__gcov_pow2_profiler): Ditto.
	(__gcov_one_value_profiler_body): Ditto.
	(__gcov_one_value_profiler): Ditto.
	(__gcov_indirect_call_profiler): Ditto.
	(__gcov_indirect_call_profiler_v2): Ditto.
	(__gcov_time_profiler): Ditto.
	(__gcov_average_profiler): Ditto.
	(__gcov_ior_profiler): Ditto.
	* libgcc/libgcov-driver.c (set_gcov_list): New.
	(get_gcov_dump_complete): Ditto.
	(set_gcov_dump_complete):Ditto.
	(reset_gcov_dump_complete):Ditto.
	(gcov_exit_compute_summary): New function split from gcov_exit().
	(gcov_exit_merge_gcda): Ditto.
	(gcov_exit_write_gcda): Ditto.
	(gcov_exit_merge_summary): Ditto.
	(gcov_exit_dump_gcov): Ditto.
	(struct gcov_fn_buffer): Moved from libgcov.c
	(struct gcov_summary_buffer): Ditto.
	(free_fn_data): Ditto.
	(buffer_fn_data): Ditto.
	(crc32_unsigned): Ditto.
	(gcov_version): Ditto.
	(gcov_histogram_insert): Ditto.
	(gcov_compute_histogram): Ditto.
	(gcov_exit): Ditto.
	(gcov_clear): Ditto.
	(__gcov_init): Ditto.
        (this_prg): Make it file scope static variable.
        (all_prg): Ditto.
        (crc32): Ditto.
        (gi_filename): Ditto.
        (fn_buffer): Ditto.
        (sum_buffer): Ditto.
        (struct gcov_filename_aux): New types to store auxiliary information
        for gi_filename.
	* libgcc/libgcov-driver-system.c (gcov_error): New utility function.
	(allocate_filename_struct): New function split from gcov_exit().
	(gcov_exit_open_gcda_file): Ditto.
	(create_file_directory): Moved from libgcov.c
	* libgcc/Makefile.in: Change to build newly added files.

From-SVN: r204730
2013-11-13 00:24:49 +00:00

280 lines
6.0 KiB
C

/* Routines required for instrumenting a program. */
/* Compile this one with gcc. */
/* Copyright (C) 1989-2013 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 3, or (at your option) any later
version.
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.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#include "tconfig.h"
#include "tsystem.h"
#include "coretypes.h"
#include "tm.h"
#include "libgcc_tm.h"
#include "gthr.h"
#if defined(inhibit_libc)
#define IN_LIBGCOV (-1)
#else
#define IN_LIBGCOV 1
#endif
#include "gcov-io.h"
#if defined(inhibit_libc)
#ifdef L_gcov_flush
void __gcov_flush (void) {}
#endif
#ifdef L_gcov_reset
void __gcov_reset (void) {}
#endif
#ifdef L_gcov_dump
void __gcov_dump (void) {}
#endif
#else
extern void gcov_clear (void) ATTRIBUTE_HIDDEN;
extern void gcov_exit (void) ATTRIBUTE_HIDDEN;
extern void set_gcov_dump_complete (void) ATTRIBUTE_HIDDEN;
extern void reset_gcov_dump_complete (void) ATTRIBUTE_HIDDEN;
#ifdef L_gcov_flush
#ifdef __GTHREAD_MUTEX_INIT
ATTRIBUTE_HIDDEN __gthread_mutex_t __gcov_flush_mx = __GTHREAD_MUTEX_INIT;
#define init_mx_once()
#else
__gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
static void
init_mx (void)
{
__GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
}
static void
init_mx_once (void)
{
static __gthread_once_t once = __GTHREAD_ONCE_INIT;
__gthread_once (&once, init_mx);
}
#endif
/* 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)
{
init_mx_once ();
__gthread_mutex_lock (&__gcov_flush_mx);
gcov_exit ();
gcov_clear ();
__gthread_mutex_unlock (&__gcov_flush_mx);
}
#endif /* L_gcov_flush */
#ifdef L_gcov_reset
/* 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 ();
/* Re-enable dumping to support collecting profile in multiple regions
of interest. */
reset_gcov_dump_complete ();
}
#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 ();
/* Prevent profile from being dumped a second time on application exit. */
set_gcov_dump_complete ();
}
#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. */
pid_t
__gcov_fork (void)
{
pid_t pid;
extern __gthread_mutex_t __gcov_flush_mx;
__gcov_flush ();
pid = fork ();
if (pid == 0)
__GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
return pid;
}
#endif
#ifdef L_gcov_execl
/* A wrapper for the execl function. Flushes the accumulated profiling data, so
that they are not lost. */
int
__gcov_execl (const char *path, char *arg, ...)
{
va_list ap, aq;
unsigned i, length;
char **args;
__gcov_flush ();
va_start (ap, arg);
va_copy (aq, ap);
length = 2;
while (va_arg (ap, char *))
length++;
va_end (ap);
args = (char **) alloca (length * sizeof (void *));
args[0] = arg;
for (i = 1; i < length; i++)
args[i] = va_arg (aq, char *);
va_end (aq);
return execv (path, args);
}
#endif
#ifdef L_gcov_execlp
/* A wrapper for the execlp function. Flushes the accumulated profiling data, so
that they are not lost. */
int
__gcov_execlp (const char *path, char *arg, ...)
{
va_list ap, aq;
unsigned i, length;
char **args;
__gcov_flush ();
va_start (ap, arg);
va_copy (aq, ap);
length = 2;
while (va_arg (ap, char *))
length++;
va_end (ap);
args = (char **) alloca (length * sizeof (void *));
args[0] = arg;
for (i = 1; i < length; i++)
args[i] = va_arg (aq, char *);
va_end (aq);
return execvp (path, args);
}
#endif
#ifdef L_gcov_execle
/* A wrapper for the execle function. Flushes the accumulated profiling data, so
that they are not lost. */
int
__gcov_execle (const char *path, char *arg, ...)
{
va_list ap, aq;
unsigned i, length;
char **args;
char **envp;
__gcov_flush ();
va_start (ap, arg);
va_copy (aq, ap);
length = 2;
while (va_arg (ap, char *))
length++;
va_end (ap);
args = (char **) alloca (length * sizeof (void *));
args[0] = arg;
for (i = 1; i < length; i++)
args[i] = va_arg (aq, char *);
envp = va_arg (aq, char **);
va_end (aq);
return execve (path, args, envp);
}
#endif
#ifdef L_gcov_execv
/* A wrapper for the execv function. Flushes the accumulated profiling data, so
that they are not lost. */
int
__gcov_execv (const char *path, char *const argv[])
{
__gcov_flush ();
return execv (path, argv);
}
#endif
#ifdef L_gcov_execvp
/* A wrapper for the execvp function. Flushes the accumulated profiling data, so
that they are not lost. */
int
__gcov_execvp (const char *path, char *const argv[])
{
__gcov_flush ();
return execvp (path, argv);
}
#endif
#ifdef L_gcov_execve
/* A wrapper for the execve function. Flushes the accumulated profiling data, so
that they are not lost. */
int
__gcov_execve (const char *path, char *const argv[], char *const envp[])
{
__gcov_flush ();
return execve (path, argv, envp);
}
#endif
#endif /* inhibit_libc */