Makefile.in (LIBGCOV): Add _gcov_merge_add.
* Makefile.in (LIBGCOV): Add _gcov_merge_add. * gcov-io.h: Make GCOV_LINKAGE extern in libgcov and prevent resulting namespace clash. (GCOV_MERGE_FUNCTIONS): New. (gcov_merge_fn): Declare. (struct gcov_ctr_info): New field "merge". (__gcov_merge_add): Declare. * coverage.c (ctr_merge_functions): New. (build_ctr_info_type, build_ctr_info_value): Initialize merge field of gcov_ctr_info type. * libgcov.c (__gcov_merge_add): New. (gcov_exit): Call a hook to merge values of counters. From-SVN: r66457
This commit is contained in:
parent
c71f2ffd78
commit
09780dfb65
@ -1,3 +1,18 @@
|
|||||||
|
2003-05-04 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
|
||||||
|
|
||||||
|
* Makefile.in (LIBGCOV): Add _gcov_merge_add.
|
||||||
|
* gcov-io.h: Make GCOV_LINKAGE extern in libgcov and prevent resulting
|
||||||
|
namespace clash.
|
||||||
|
(GCOV_MERGE_FUNCTIONS): New.
|
||||||
|
(gcov_merge_fn): Declare.
|
||||||
|
(struct gcov_ctr_info): New field "merge".
|
||||||
|
(__gcov_merge_add): Declare.
|
||||||
|
* coverage.c (ctr_merge_functions): New.
|
||||||
|
(build_ctr_info_type, build_ctr_info_value): Initialize merge field
|
||||||
|
of gcov_ctr_info type.
|
||||||
|
* libgcov.c (__gcov_merge_add): New.
|
||||||
|
(gcov_exit): Call a hook to merge values of counters.
|
||||||
|
|
||||||
2003-05-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
2003-05-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||||
|
|
||||||
* toplev.h (pedwarn_with_file_and_line): Don't declare.
|
* toplev.h (pedwarn_with_file_and_line): Don't declare.
|
||||||
|
@ -854,7 +854,7 @@ STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
|
|||||||
LIB2FUNCS_ST = _eprintf __gcc_bcmp
|
LIB2FUNCS_ST = _eprintf __gcc_bcmp
|
||||||
|
|
||||||
# Defined in libgcov.c, included only in gcov library
|
# Defined in libgcov.c, included only in gcov library
|
||||||
LIBGCOV = _gcov
|
LIBGCOV = _gcov _gcov_merge_add
|
||||||
|
|
||||||
FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \
|
FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \
|
||||||
_fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \
|
_fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \
|
||||||
|
@ -98,6 +98,9 @@ static htab_t counts_hash = NULL;
|
|||||||
/* The names of the counter tables. */
|
/* The names of the counter tables. */
|
||||||
static GTY(()) rtx ctr_labels[GCOV_COUNTERS];
|
static GTY(()) rtx ctr_labels[GCOV_COUNTERS];
|
||||||
|
|
||||||
|
/* The names of merge functions for counters. */
|
||||||
|
static const char *ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
|
||||||
|
|
||||||
/* Forward declarations. */
|
/* Forward declarations. */
|
||||||
static hashval_t htab_counts_entry_hash PARAMS ((const void *));
|
static hashval_t htab_counts_entry_hash PARAMS ((const void *));
|
||||||
static int htab_counts_entry_eq PARAMS ((const void *, const void *));
|
static int htab_counts_entry_eq PARAMS ((const void *, const void *));
|
||||||
@ -559,6 +562,7 @@ build_ctr_info_type ()
|
|||||||
{
|
{
|
||||||
tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
|
tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
|
||||||
tree field, fields = NULL_TREE;
|
tree field, fields = NULL_TREE;
|
||||||
|
tree gcov_merge_fn_type;
|
||||||
|
|
||||||
/* counters */
|
/* counters */
|
||||||
field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
|
field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
|
||||||
@ -571,6 +575,18 @@ build_ctr_info_type ()
|
|||||||
TREE_CHAIN (field) = fields;
|
TREE_CHAIN (field) = fields;
|
||||||
fields = field;
|
fields = field;
|
||||||
|
|
||||||
|
/* merge */
|
||||||
|
gcov_merge_fn_type =
|
||||||
|
build_function_type_list (
|
||||||
|
void_type_node,
|
||||||
|
build_pointer_type (make_signed_type (GCOV_TYPE_SIZE)),
|
||||||
|
unsigned_type_node,
|
||||||
|
NULL_TREE);
|
||||||
|
field = build_decl (FIELD_DECL, NULL_TREE,
|
||||||
|
build_pointer_type (gcov_merge_fn_type));
|
||||||
|
TREE_CHAIN (field) = fields;
|
||||||
|
fields = field;
|
||||||
|
|
||||||
finish_builtin_struct (type, "__gcov_ctr_info", fields, NULL_TREE);
|
finish_builtin_struct (type, "__gcov_ctr_info", fields, NULL_TREE);
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
@ -587,6 +603,7 @@ build_ctr_info_value (counter, type)
|
|||||||
{
|
{
|
||||||
tree value = NULL_TREE;
|
tree value = NULL_TREE;
|
||||||
tree fields = TYPE_FIELDS (type);
|
tree fields = TYPE_FIELDS (type);
|
||||||
|
tree fn;
|
||||||
|
|
||||||
/* counters */
|
/* counters */
|
||||||
value = tree_cons (fields,
|
value = tree_cons (fields,
|
||||||
@ -614,6 +631,20 @@ build_ctr_info_value (counter, type)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
value = tree_cons (fields, null_pointer_node, value);
|
value = tree_cons (fields, null_pointer_node, value);
|
||||||
|
fields = TREE_CHAIN (fields);
|
||||||
|
|
||||||
|
fn = build_decl (FUNCTION_DECL,
|
||||||
|
get_identifier (ctr_merge_functions[counter]),
|
||||||
|
TREE_TYPE (TREE_TYPE (fields)));
|
||||||
|
DECL_EXTERNAL (fn) = 1;
|
||||||
|
TREE_PUBLIC (fn) = 1;
|
||||||
|
DECL_ARTIFICIAL (fn) = 1;
|
||||||
|
TREE_NOTHROW (fn) = 1;
|
||||||
|
value = tree_cons (fields,
|
||||||
|
build1 (ADDR_EXPR,
|
||||||
|
TREE_TYPE (fields),
|
||||||
|
fn),
|
||||||
|
value);
|
||||||
|
|
||||||
value = build_constructor (type, nreverse (value));
|
value = build_constructor (type, nreverse (value));
|
||||||
|
|
||||||
|
@ -176,15 +176,46 @@ typedef HOST_WIDEST_INT gcov_type;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* In lib gcov we want function linkage to be static, so we do not
|
/* In gcov we want function linkage to be static, so we do not
|
||||||
polute the global namespace. In the compiler we want it extern, so
|
polute the global namespace. In libgcov we need these functions
|
||||||
that they can be accessed from elsewhere. */
|
to be extern, so prefix them with __gcov so that we do not conflict.
|
||||||
#if IN_LIBGCOV || IN_GCOV
|
In the compiler we want it extern, so that they can be accessed from
|
||||||
|
elsewhere. */
|
||||||
|
#if IN_LIBGCOV
|
||||||
|
|
||||||
|
#define GCOV_LINKAGE /* nothing */
|
||||||
|
#define gcov_var __gcov_var
|
||||||
|
#define gcov_open __gcov_open
|
||||||
|
#define gcov_close __gcov_close
|
||||||
|
#define gcov_write_bytes __gcov_write_bytes
|
||||||
|
#define gcov_write_unsigned __gcov_write_unsigned
|
||||||
|
#define gcov_write_counter __gcov_write_counter
|
||||||
|
#define gcov_write_string __gcov_write_string
|
||||||
|
#define gcov_write_tag __gcov_write_tag
|
||||||
|
#define gcov_write_length __gcov_write_length
|
||||||
|
#define gcov_write_summary __gcov_write_summary
|
||||||
|
#define gcov_read_bytes __gcov_read_bytes
|
||||||
|
#define gcov_read_unsigned __gcov_read_unsigned
|
||||||
|
#define gcov_read_counter __gcov_read_counter
|
||||||
|
#define gcov_read_string __gcov_read_string
|
||||||
|
#define gcov_read_summary __gcov_read_summary
|
||||||
|
#define gcov_position __gcov_position
|
||||||
|
#define gcov_seek __gcov_seek
|
||||||
|
#define gcov_seek_end __gcov_seek_end
|
||||||
|
#define gcov_is_eof __gcov_is_eof
|
||||||
|
#define gcov_is_error __gcov_is_error
|
||||||
|
#define gcov_time __gcov_time
|
||||||
|
|
||||||
|
#elif IN_GCOV
|
||||||
|
|
||||||
#define GCOV_LINKAGE static
|
#define GCOV_LINKAGE static
|
||||||
#else
|
|
||||||
|
#else /* !IN_LIBGCOV && !IN_GCOV */
|
||||||
|
|
||||||
#ifndef GCOV_LINKAGE
|
#ifndef GCOV_LINKAGE
|
||||||
#define GCOV_LINKAGE extern
|
#define GCOV_LINKAGE extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* File suffixes. */
|
/* File suffixes. */
|
||||||
@ -220,6 +251,9 @@ typedef HOST_WIDEST_INT gcov_type;
|
|||||||
/* A list of human readable names of the counters */
|
/* A list of human readable names of the counters */
|
||||||
#define GCOV_COUNTER_NAMES {"arcs"}
|
#define GCOV_COUNTER_NAMES {"arcs"}
|
||||||
|
|
||||||
|
/* Names of merge functions for counters. */
|
||||||
|
#define GCOV_MERGE_FUNCTIONS {"__gcov_merge_add"}
|
||||||
|
|
||||||
/* Convert a counter index to a tag. */
|
/* Convert a counter index to a tag. */
|
||||||
#define GCOV_TAG_FOR_COUNTER(COUNT) \
|
#define GCOV_TAG_FOR_COUNTER(COUNT) \
|
||||||
(GCOV_TAG_COUNTER_BASE + ((COUNT) << 17))
|
(GCOV_TAG_COUNTER_BASE + ((COUNT) << 17))
|
||||||
@ -286,11 +320,15 @@ struct gcov_fn_info
|
|||||||
unsigned n_ctrs[0]; /* instrumented counters */
|
unsigned n_ctrs[0]; /* instrumented counters */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Type of function used to merge counters. */
|
||||||
|
typedef void (*gcov_merge_fn) (gcov_type *, unsigned);
|
||||||
|
|
||||||
/* Information about counters. */
|
/* Information about counters. */
|
||||||
struct gcov_ctr_info
|
struct gcov_ctr_info
|
||||||
{
|
{
|
||||||
unsigned num; /* number of counters. */
|
unsigned num; /* number of counters. */
|
||||||
gcov_type *values; /* their values. */
|
gcov_type *values; /* their values. */
|
||||||
|
gcov_merge_fn merge; /* The function used to merge them. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Information about a single object file. */
|
/* Information about a single object file. */
|
||||||
@ -317,6 +355,8 @@ extern void __gcov_init (struct gcov_info *);
|
|||||||
/* Called before fork, to avoid double counting. */
|
/* Called before fork, to avoid double counting. */
|
||||||
extern void __gcov_flush (void);
|
extern void __gcov_flush (void);
|
||||||
|
|
||||||
|
/* The merge function that just sums the counters. */
|
||||||
|
extern void __gcov_merge_add (gcov_type *, unsigned);
|
||||||
#endif /* IN_LIBGCOV */
|
#endif /* IN_LIBGCOV */
|
||||||
|
|
||||||
/* Because small reads and writes, interspersed with seeks cause lots
|
/* Because small reads and writes, interspersed with seeks cause lots
|
||||||
|
@ -32,11 +32,19 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||||||
#if defined(inhibit_libc)
|
#if defined(inhibit_libc)
|
||||||
/* If libc and its header files are not available, provide dummy functions. */
|
/* If libc and its header files are not available, provide dummy functions. */
|
||||||
|
|
||||||
|
#ifdef L_gcov
|
||||||
void __gcov_init (void *p);
|
void __gcov_init (void *p);
|
||||||
void __gcov_flush (void);
|
void __gcov_flush (void);
|
||||||
|
|
||||||
void __gcov_init (void *p) { }
|
void __gcov_init (void *p) { }
|
||||||
void __gcov_flush (void) { }
|
void __gcov_flush (void) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef L_gcov_merge_add
|
||||||
|
void __gcov_merge_add (gcov_type *, unsigned);
|
||||||
|
|
||||||
|
void __gcov_merge_add (gcov_type *counters, unsigned n_counters) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@ -59,6 +67,8 @@ void __gcov_flush (void) { }
|
|||||||
#endif
|
#endif
|
||||||
#define IN_LIBGCOV 1
|
#define IN_LIBGCOV 1
|
||||||
#include "gcov-io.h"
|
#include "gcov-io.h"
|
||||||
|
|
||||||
|
#ifdef L_gcov
|
||||||
#include "gcov-io.c"
|
#include "gcov-io.c"
|
||||||
|
|
||||||
/* Chain of per-object gcov structures. */
|
/* Chain of per-object gcov structures. */
|
||||||
@ -227,7 +237,7 @@ gcov_exit (void)
|
|||||||
if ((1 << t_ix) & gi_ptr->ctr_mask)
|
if ((1 << t_ix) & gi_ptr->ctr_mask)
|
||||||
{
|
{
|
||||||
unsigned n_counts;
|
unsigned n_counts;
|
||||||
gcov_type *c_ptr;
|
gcov_merge_fn merge;
|
||||||
|
|
||||||
tag = gcov_read_unsigned ();
|
tag = gcov_read_unsigned ();
|
||||||
length = gcov_read_unsigned ();
|
length = gcov_read_unsigned ();
|
||||||
@ -235,11 +245,10 @@ gcov_exit (void)
|
|||||||
if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
|
if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
|
||||||
|| fi_ptr->n_ctrs[c_ix] * 8 != length)
|
|| fi_ptr->n_ctrs[c_ix] * 8 != length)
|
||||||
goto read_mismatch;
|
goto read_mismatch;
|
||||||
c_ptr = values[c_ix];
|
n_counts = fi_ptr->n_ctrs[c_ix];
|
||||||
for (n_counts = fi_ptr->n_ctrs[c_ix];
|
merge = gi_ptr->counts[c_ix].merge;
|
||||||
n_counts--; c_ptr++)
|
(*merge) (values[c_ix], n_counts);
|
||||||
*c_ptr += gcov_read_counter ();
|
values[c_ix] += n_counts;
|
||||||
values[c_ix] = c_ptr;
|
|
||||||
c_ix++;
|
c_ix++;
|
||||||
}
|
}
|
||||||
if ((error = gcov_is_error ()))
|
if ((error = gcov_is_error ()))
|
||||||
@ -450,4 +459,20 @@ __gcov_flush (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* L_gcov */
|
||||||
|
|
||||||
|
#ifdef L_gcov_merge_add
|
||||||
|
/* The profile merging function that just adds the counters. It is given
|
||||||
|
an array COUNTERS of N_COUNTERS old counters and it reads the same number
|
||||||
|
of counters from the gcov file. */
|
||||||
|
void
|
||||||
|
__gcov_merge_add (counters, n_counters)
|
||||||
|
gcov_type *counters;
|
||||||
|
unsigned n_counters;
|
||||||
|
{
|
||||||
|
for (; n_counters; counters++, n_counters--)
|
||||||
|
*counters += gcov_read_counter ();
|
||||||
|
}
|
||||||
|
#endif /* L_gcov_merge_add */
|
||||||
|
|
||||||
#endif /* inhibit_libc */
|
#endif /* inhibit_libc */
|
||||||
|
Loading…
Reference in New Issue
Block a user