This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] time stamp gcov files
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Zdenek Dvorak <rakdver at atrey dot karlin dot mff dot cuni dot cz>
- Date: Sun, 06 Jul 2003 15:57:41 +0100
- Subject: [PATCH] time stamp gcov files
- Organization: Codesourcery LLC
Hi,
I've installed this patch which adds a local time stamp to gcov files.
Zdenek pointed out that using the .da files is not an idempotent operation
-- the compiler would delete them. The reason for that was to prevent
libgcov trying to merge inconsistent sets of data. This time stamp fixes
that by allowing libgcov to know when to do the .da file truncation itself.
All the time stamp has to to is increment fast enough so that no
compile-profile-recompile cycle gets the same stamp, and cycle slow enough
that several compile-profile-recompile iterations never recycle the stamp.
With gettimeofday that is 1mS ticks and a 49 day cycle.
booted & tested on i686-pc-linux-gnu.
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
The voices in my head said this was stupid too
nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
2003-07-05 Nathan Sidwell <nathan@codesourcery.com>
* gcov-io.h: Add a local time stamp.
(struct gcov_info): Add stamp field.
(gcov_truncate): New.
* coverage.c (read_counts_file): Skip the stamp.
(coverage_begin_output): Write the stamp.
(build_gcov_info): Declare and init the stamp.
(coverage_finish): Only unlink data file, if stamp is zero.
* gcov-dump.c (dump_file): Dump the stamp.
* gcov.c (bbg_stamp): New.
(release_structures): Clear bbg_stamp.
(read_graph_file): Read stamp.
(read_count_file): Check stamp.
* libgcov.c (gcov_exit): Check stamp and truncate if needed.
Index: coverage.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/coverage.c,v
retrieving revision 1.14
diff -c -3 -p -r1.14 coverage.c
*** coverage.c 29 Jun 2003 12:07:06 -0000 1.14
--- coverage.c 5 Jul 2003 15:12:10 -0000
*************** read_counts_file (void)
*** 182,187 ****
--- 182,190 ----
return;
}
+ /* Read and discard the stamp. */
+ gcov_read_unsigned ();
+
counts_hash = htab_create (10,
htab_counts_entry_hash, htab_counts_entry_eq,
htab_counts_entry_del);
*************** coverage_begin_output (void)
*** 445,450 ****
--- 448,454 ----
{
gcov_write_unsigned (GCOV_GRAPH_MAGIC);
gcov_write_unsigned (GCOV_VERSION);
+ gcov_write_unsigned (local_tick);
}
bbg_file_opened = 1;
}
*************** build_gcov_info (void)
*** 708,713 ****
--- 712,725 ----
fields = field;
value = tree_cons (field, null_pointer_node, value);
+ /* stamp */
+ field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+ value = tree_cons (field, convert (unsigned_intSI_type_node,
+ build_int_2 (local_tick, 0)),
+ value);
+
/* Filename */
string_type = build_pointer_type (build_qualified_type (char_type_node,
TYPE_QUAL_CONST));
*************** coverage_finish (void)
*** 905,917 ****
if (error)
unlink (bbg_file_name);
! #if SELF_COVERAGE
! /* If the compiler is instrumented, we should not
! unconditionally remove the counts file, because we might be
! recompiling ourselves. The .da files are all removed during
! copying the stage1 files. */
! if (error)
! #endif
unlink (da_file_name);
}
}
--- 917,925 ----
if (error)
unlink (bbg_file_name);
! if (!local_tick)
! /* Only remove the da file, if we cannot stamp it. If we can
! stamp it, libgcov will DTRT. */
unlink (da_file_name);
}
}
Index: gcov-dump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcov-dump.c,v
retrieving revision 1.14
diff -c -3 -p -r1.14 gcov-dump.c
*** gcov-dump.c 29 May 2003 21:33:35 -0000 1.14
--- gcov-dump.c 5 Jul 2003 15:12:12 -0000
*************** dump_file (filename)
*** 189,194 ****
--- 189,201 ----
printf ("%s:warning:current version is `%.4s'\n", filename, e);
}
+ /* stamp */
+ {
+ unsigned stamp = gcov_read_unsigned ();
+
+ printf ("%s:stamp %lu\n", filename, (unsigned long)stamp);
+ }
+
while (1)
{
gcov_position_t base, position = gcov_position ();
Index: gcov-io.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcov-io.h,v
retrieving revision 1.40
diff -c -3 -p -r1.40 gcov-io.h
*** gcov-io.h 1 Jul 2003 12:17:53 -0000 1.40
--- gcov-io.h 5 Jul 2003 15:12:12 -0000
*************** Software Foundation, 59 Temple Place - S
*** 52,62 ****
The basic format of the files is
! file : int32:magic int32:version record*
The magic ident is different for the bbg and the counter files.
The version is the same for both files and is derived from gcc's
! version number. Although the ident and version are formally 32 bit
numbers, they are derived from 4 character ASCII strings. The
version number consists of the single character major version
number, a two character minor version number (leading zero for
--- 52,68 ----
The basic format of the files is
! file : int32:magic int32:version int32:stamp record*
The magic ident is different for the bbg and the counter files.
The version is the same for both files and is derived from gcc's
! version number. The stamp value is used to synchronize bbg and
! counter files and to synchronize merging within a counter file. It
! need not be an absolute time stamp, merely a ticker that increments
! fast enough and cycles slow enough to distinguish different
! compile/run/compile cycles.
!
! Although the ident and version are formally 32 bit
numbers, they are derived from 4 character ASCII strings. The
version number consists of the single character major version
number, a two character minor version number (leading zero for
*************** struct gcov_info
*** 370,377 ****
gcov_unsigned_t version; /* expected version number */
struct gcov_info *next; /* link to next, used by libgcc */
const char *filename; /* output file name */
!
unsigned n_functions; /* number of functions */
const struct gcov_fn_info *functions; /* table of functions */
--- 376,384 ----
gcov_unsigned_t version; /* expected version number */
struct gcov_info *next; /* link to next, used by libgcc */
+ gcov_unsigned_t stamp; /* uniquifying time stamp */
const char *filename; /* output file name */
!
unsigned n_functions; /* number of functions */
const struct gcov_fn_info *functions; /* table of functions */
*************** GCOV_LINKAGE void gcov_write_counter (gc
*** 453,458 ****
--- 460,466 ----
GCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t, gcov_unsigned_t);
GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
const struct gcov_summary *);
+ static void gcov_truncate (void);
static void gcov_rewrite (void);
GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/);
#else
*************** gcov_rewrite (void)
*** 524,529 ****
--- 532,543 ----
gcov_var.start = 0;
gcov_var.offset = 0;
fseek (gcov_var.file, 0L, SEEK_SET);
+ }
+
+ static inline void
+ gcov_truncate (void)
+ {
+ ftruncate (fileno (gcov_var.file), 0L);
}
#endif
Index: gcov.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcov.c,v
retrieving revision 1.70
diff -c -3 -p -r1.70 gcov.c
*** gcov.c 1 Jul 2003 12:17:53 -0000 1.70
--- gcov.c 5 Jul 2003 15:12:16 -0000
*************** static time_t bbg_file_time;
*** 269,274 ****
--- 269,277 ----
static char *bbg_file_name;
+ /* Stamp of the bbg file */
+ static unsigned bbg_stamp;
+
/* Name and file pointer of the input file for the arc count data. */
static char *da_file_name;
*************** release_structures ()
*** 583,588 ****
--- 586,592 ----
free (da_file_name);
da_file_name = bbg_file_name = NULL;
bbg_file_time = 0;
+ bbg_stamp = 0;
while ((src = sources))
{
*************** read_graph_file ()
*** 740,746 ****
fnotice (stderr, "%s:version `%.4s', prefer `%.4s'\n",
bbg_file_name, v, e);
}
!
while ((tag = gcov_read_unsigned ()))
{
unsigned length = gcov_read_unsigned ();
--- 744,751 ----
fnotice (stderr, "%s:version `%.4s', prefer `%.4s'\n",
bbg_file_name, v, e);
}
! bbg_stamp = gcov_read_unsigned ();
!
while ((tag = gcov_read_unsigned ()))
{
unsigned length = gcov_read_unsigned ();
*************** read_count_file ()
*** 1007,1012 ****
--- 1012,1023 ----
}
fnotice (stderr, "%s:version `%.4s', prefer version `%.4s'\n",
da_file_name, v, e);
+ }
+ tag = gcov_read_unsigned ();
+ if (tag != bbg_stamp)
+ {
+ fnotice (stderr, "%s:stamp mismatch with graph file\n", da_file_name);
+ goto cleanup;
}
while ((tag = gcov_read_unsigned ()))
Index: libgcov.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/libgcov.c,v
retrieving revision 1.17
diff -c -3 -p -r1.17 libgcov.c
*** libgcov.c 29 Jun 2003 13:53:08 -0000 1.17
--- libgcov.c 5 Jul 2003 15:12:22 -0000
*************** gcov_exit (void)
*** 167,174 ****
gcov_unsigned_t tag, length;
gcov_position_t summary_pos = 0;
- /* Totals for this object file. */
memset (&this_object, 0, sizeof (this_object));
for (t_ix = c_ix = 0,
ci_ptr = gi_ptr->counts, cs_ptr = this_object.ctrs;
t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++, cs_ptr++)
--- 167,176 ----
gcov_unsigned_t tag, length;
gcov_position_t summary_pos = 0;
memset (&this_object, 0, sizeof (this_object));
+ memset (&object, 0, sizeof (object));
+
+ /* Totals for this object file. */
for (t_ix = c_ix = 0,
ci_ptr = gi_ptr->counts, cs_ptr = this_object.ctrs;
t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++, cs_ptr++)
*************** gcov_exit (void)
*** 223,228 ****
--- 225,239 ----
gcov_version_mismatch (gi_ptr, length);
goto read_fatal;
}
+
+ length = gcov_read_unsigned ();
+ if (length != gi_ptr->stamp)
+ {
+ /* Read from a different compilation. Overwrite the
+ file. */
+ gcov_truncate ();
+ goto rewrite;
+ }
/* Merge execution counts for each function. */
for (f_ix = gi_ptr->n_functions, fi_ptr = gi_ptr->functions;
*************** gcov_exit (void)
*** 298,305 ****
rewrite:;
gcov_rewrite ();
}
- else
- memset (&object, 0, sizeof (object));
if (!summary_pos)
memset (&program, 0, sizeof (program));
--- 309,314 ----
*************** gcov_exit (void)
*** 355,360 ****
--- 364,370 ----
/* Write out the data. */
gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
+ gcov_write_unsigned (gi_ptr->stamp);
/* Write execution counts for each function. */
for (f_ix = gi_ptr->n_functions, fi_ptr = gi_ptr->functions; f_ix--;