[PATCH] Add support for profile merging hooks
Zdenek Dvorak
rakdver@atrey.karlin.mff.cuni.cz
Sat May 3 21:58:00 GMT 2003
Hello,
> could you commit your updated patch, I have some other changes I'd like
> to commence with.
OK this way?
Zdenek
Index: Makefile.in
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.1047
diff -c -3 -p -r1.1047 Makefile.in
*** Makefile.in 3 May 2003 21:44:24 -0000 1.1047
--- Makefile.in 3 May 2003 21:56:00 -0000
*************** STAGESTUFF = *$(objext) insn-flags.h ins
*** 854,860 ****
LIB2FUNCS_ST = _eprintf __gcc_bcmp
# Defined in libgcov.c, included only in gcov library
! LIBGCOV = _gcov
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 \
--- 854,860 ----
LIB2FUNCS_ST = _eprintf __gcc_bcmp
# Defined in libgcov.c, included only in gcov library
! LIBGCOV = _gcov _gcov_merge_add
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 \
Index: coverage.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/coverage.c,v
retrieving revision 1.4
diff -c -3 -p -r1.4 coverage.c
*** coverage.c 1 May 2003 16:13:28 -0000 1.4
--- coverage.c 3 May 2003 21:56:00 -0000
*************** static htab_t counts_hash = NULL;
*** 98,103 ****
--- 98,106 ----
/* The names of the counter tables. */
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. */
static hashval_t htab_counts_entry_hash PARAMS ((const void *));
static int htab_counts_entry_eq PARAMS ((const void *, const void *));
*************** build_ctr_info_type ()
*** 559,564 ****
--- 562,568 ----
{
tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
tree field, fields = NULL_TREE;
+ tree gcov_merge_fn_type;
/* counters */
field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
*************** build_ctr_info_type ()
*** 571,576 ****
--- 575,592 ----
TREE_CHAIN (field) = fields;
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);
return type;
*************** build_ctr_info_value (counter, type)
*** 587,592 ****
--- 604,610 ----
{
tree value = NULL_TREE;
tree fields = TYPE_FIELDS (type);
+ tree fn;
/* counters */
value = tree_cons (fields,
*************** build_ctr_info_value (counter, type)
*** 614,619 ****
--- 632,651 ----
}
else
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));
Index: gcov-io.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/gcov-io.h,v
retrieving revision 1.30
diff -c -3 -p -r1.30 gcov-io.h
*** gcov-io.h 24 Apr 2003 09:46:16 -0000 1.30
--- gcov-io.h 3 May 2003 21:56:00 -0000
*************** typedef HOST_WIDEST_INT gcov_type;
*** 176,190 ****
#endif
#endif
! /* In lib gcov we want function linkage to be static, so we do not
! polute the global namespace. In the compiler we want it extern, so
! that they can be accessed from elsewhere. */
! #if IN_LIBGCOV || IN_GCOV
#define GCOV_LINKAGE static
! #else
#ifndef GCOV_LINKAGE
#define GCOV_LINKAGE extern
#endif
#endif
/* File suffixes. */
--- 176,221 ----
#endif
#endif
! /* In gcov we want function linkage to be static, so we do not
! polute the global namespace. In libgcov we need these functions
! to be extern, so prefix them with __gcov so that we do not conflict.
! 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
!
! #else /* !IN_LIBGCOV && !IN_GCOV */
!
#ifndef GCOV_LINKAGE
#define GCOV_LINKAGE extern
#endif
+
#endif
/* File suffixes. */
*************** typedef HOST_WIDEST_INT gcov_type;
*** 220,225 ****
--- 251,259 ----
/* A list of human readable names of the counters */
#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. */
#define GCOV_TAG_FOR_COUNTER(COUNT) \
(GCOV_TAG_COUNTER_BASE + ((COUNT) << 17))
*************** struct gcov_fn_info
*** 286,296 ****
--- 320,334 ----
unsigned n_ctrs[0]; /* instrumented counters */
};
+ /* Type of function used to merge counters. */
+ typedef void (*gcov_merge_fn) (gcov_type *, unsigned);
+
/* Information about counters. */
struct gcov_ctr_info
{
unsigned num; /* number of counters. */
gcov_type *values; /* their values. */
+ gcov_merge_fn merge; /* The function used to merge them. */
};
/* Information about a single object file. */
*************** extern void __gcov_init (struct gcov_inf
*** 317,322 ****
--- 355,362 ----
/* Called before fork, to avoid double counting. */
extern void __gcov_flush (void);
+ /* The merge function that just sums the counters. */
+ extern void __gcov_merge_add (gcov_type *, unsigned);
#endif /* IN_LIBGCOV */
/* Because small reads and writes, interspersed with seeks cause lots
Index: libgcov.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/libgcov.c,v
retrieving revision 1.10
diff -c -3 -p -r1.10 libgcov.c
*** libgcov.c 24 Apr 2003 09:46:17 -0000 1.10
--- libgcov.c 3 May 2003 21:56:00 -0000
*************** Software Foundation, 59 Temple Place - S
*** 32,42 ****
--- 32,50 ----
#if defined(inhibit_libc)
/* If libc and its header files are not available, provide dummy functions. */
+ #ifdef L_gcov
void __gcov_init (void *p);
void __gcov_flush (void);
void __gcov_init (void *p) { }
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
*************** void __gcov_flush (void) { }
*** 59,64 ****
--- 67,74 ----
#endif
#define IN_LIBGCOV 1
#include "gcov-io.h"
+
+ #ifdef L_gcov
#include "gcov-io.c"
/* Chain of per-object gcov structures. */
*************** gcov_exit (void)
*** 227,233 ****
if ((1 << t_ix) & gi_ptr->ctr_mask)
{
unsigned n_counts;
! gcov_type *c_ptr;
tag = gcov_read_unsigned ();
length = gcov_read_unsigned ();
--- 237,243 ----
if ((1 << t_ix) & gi_ptr->ctr_mask)
{
unsigned n_counts;
! gcov_merge_fn merge;
tag = gcov_read_unsigned ();
length = gcov_read_unsigned ();
*************** gcov_exit (void)
*** 235,245 ****
if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
|| fi_ptr->n_ctrs[c_ix] * 8 != length)
goto read_mismatch;
! c_ptr = values[c_ix];
! for (n_counts = fi_ptr->n_ctrs[c_ix];
! n_counts--; c_ptr++)
! *c_ptr += gcov_read_counter ();
! values[c_ix] = c_ptr;
c_ix++;
}
if ((error = gcov_is_error ()))
--- 245,254 ----
if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
|| fi_ptr->n_ctrs[c_ix] * 8 != length)
goto read_mismatch;
! n_counts = fi_ptr->n_ctrs[c_ix];
! merge = gi_ptr->counts[c_ix].merge;
! (*merge) (values[c_ix], n_counts);
! values[c_ix] += n_counts;
c_ix++;
}
if ((error = gcov_is_error ()))
*************** __gcov_flush (void)
*** 449,453 ****
--- 458,478 ----
}
}
}
+
+ #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 */
More information about the Gcc-patches
mailing list