Break out coverage routines to new file.

* Makefile.in (COVERAGE_H): New variable
        (C_OBJS): Add coverage.o
        (coverage.o): New target.
        (profile.o, loop-init.o, sched-ebb.o, predict.o, tracer.o): Adjust
        dependencies.
        (GTFILES): Adjust.
        (gt-coverage.h): New target.
        (gt-profile.h): Remove.
        * profile.h: Remove. Move to ...
        * coverage.h: ... here. New. #include gcov-io.h.
        * gcov-io.h: Move function definitions to ...
        * gcov-io.c: ... here. New.
        * profile.c: Move coverage routines to coverage.c.
        (instrument_edges, get_exec_counts, branch_prob, init_branch_prob,
        end_branch_prob): Adjust.
        * coverage.c: New. Coverage routines from profile.c
        (coverage_counter_ref, coverage_init, coverage_finish,
        coverage_end_function, coverage_begin_output,
        coverage_counter_ref, get_coverage_counts): Define.
        * gcov-dump.c, gcov.c: #include gcov-io.c.
        * libgcov.c: Likewise. Adjust.
        * loop-init.c: Don't #include profile.h
        * tracer.c, predict.c, sched-ebb.c: Adjust #includes.
        * rtl.h: Add coverage prototypes.
        * toplev.c (compile_file): Init coverage, not branch_prob.
        Always call coverage_finish.
        (rest_of_compilation): Call coverage_end_function.

From-SVN: r65897
This commit is contained in:
Nathan Sidwell 2003-04-21 19:48:10 +00:00
parent 1774b2132f
commit ca29da4301
13 changed files with 1801 additions and 1564 deletions

View File

@ -1,3 +1,34 @@
2003-04-21 Nathan Sidwell <nathan@codesourcery.com>
Break out coverage routines to new file.
* Makefile.in (COVERAGE_H): New variable
(C_OBJS): Add coverage.o
(coverage.o): New target.
(profile.o, loop-init.o, sched-ebb.o, predict.o, tracer.o): Adjust
dependencies.
(GTFILES): Adjust.
(gt-coverage.h): New target.
(gt-profile.h): Remove.
* profile.h: Remove. Move to ...
* coverage.h: ... here. New. #include gcov-io.h.
* gcov-io.h: Move function definitions to ...
* gcov-io.c: ... here. New.
* profile.c: Move coverage routines to coverage.c.
(instrument_edges, get_exec_counts, branch_prob, init_branch_prob,
end_branch_prob): Adjust.
* coverage.c: New. Coverage routines from profile.c
(coverage_counter_ref, coverage_init, coverage_finish,
coverage_end_function, coverage_begin_output,
coverage_counter_ref, get_coverage_counts): Define.
* gcov-dump.c, gcov.c: #include gcov-io.c.
* libgcov.c: Likewise. Adjust.
* loop-init.c: Don't #include profile.h
* tracer.c, predict.c, sched-ebb.c: Adjust #includes.
* rtl.h: Add coverage prototypes.
* toplev.c (compile_file): Init coverage, not branch_prob.
Always call coverage_finish.
(rest_of_compilation): Call coverage_end_function.
2003-04-21 Matt Kraai <kraai@alumni.cmu.edu>
* config/rs6000/rs6000.md (*movsf_softfloat): Add "h" <- "0" case.
@ -417,12 +448,14 @@ Sat Apr 19 14:56:17 CEST 2003 Jan Hubicka <jh@suse.cz>
Fri Apr 18 01:28:51 CEST 2003 Jan Hubicka <jh@suse.cz>
* gcov-dump.c (tag_summary): Remove max_sum
* gcov-io.h (gcov_summary, gcov_write_summary, gcov_read_summary): Kill
max_sum.
* libgcov.c (gcov_exit): Do one pass over the data. Make error message
more verbose.
* gcov-io.h (gcov_summary, gcov_write_summary,
gcov_read_summary): Kill max_sum.
* libgcov.c (gcov_exit): Do one pass over the data. Make error
message more verbose.
* emit-rtl.c (subreg_hard_regno): Check that register is representable.
* emit-rtl.c (subreg_hard_regno): Check that register is
representable.
* reload.c (reload_inner_reg_of_subreg): When register is not
representable, reload the whole thing.
(find_reloads): Likewsie.
@ -430,7 +463,8 @@ Fri Apr 18 01:28:51 CEST 2003 Jan Hubicka <jh@suse.cz>
* profile.c (compute_branch_probabilities): Cleanup sanity checking;
allow negative probabilities for edges from the call to exit.
(branch_prob): Do not add fake edges for functions that may return twice
(branch_prob): Do not add fake edges for functions that may return
twice.
2003-04-17 DJ Delorie <dj@redhat.com>

View File

@ -636,6 +636,7 @@ TREE_H = tree.h tree.def $(MACHMODE_H) tree-check.h version.h builtins.def \
location.h
BASIC_BLOCK_H = basic-block.h bitmap.h sbitmap.h varray.h $(PARTITION_H) \
hard-reg-set.h
COVERAGE_H = coverage.h gcov-io.h gcov-iov.h
DEMANGLE_H = $(srcdir)/../include/demangle.h
RECOG_H = recog.h
EXPR_H = expr.h
@ -803,8 +804,8 @@ C_OBJS = c-parse.o c-lang.o c-pretty-print.o $(C_AND_OBJC_OBJS)
OBJS = alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o \
cfg.o cfganal.o cfgbuild.o cfgcleanup.o cfglayout.o cfgloop.o \
cfgloopanal.o cfgloopmanip.o loop-init.o loop-unswitch.o loop-unroll.o \
cfgrtl.o combine.o conflict.o convert.o cse.o cselib.o dbxout.o \
debug.o df.o diagnostic.o dojump.o doloop.o dominance.o \
cfgrtl.o combine.o conflict.o convert.o coverage.o cse.o cselib.o \
dbxout.o debug.o df.o diagnostic.o dojump.o doloop.o dominance.o \
dwarf2asm.o dwarf2out.o dwarfout.o emit-rtl.o except.o explow.o \
expmed.o expr.o final.o flow.o fold-const.o function.o gcse.o \
genrtl.o ggc-common.o global.o graph.o gtype-desc.o \
@ -1584,6 +1585,10 @@ cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
langhooks.h tree-inline.h toplev.h flags.h ggc.h $(TARGET_H) cgraph.h gt-cgraph.h
cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
langhooks.h tree-inline.h toplev.h flags.h ggc.h $(TARGET_H) cgraph.h
coverage.o : coverage.c gcov-io.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(TREE_H) flags.h output.h $(REGS_H) $(EXPR_H) function.h \
toplev.h $(GGC_H) $(TARGET_H) langhooks.h $(COVERAGE_H) libfuncs.h \
gt-coverage.h $(HASHTAB_H)
cselib.o : cselib.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
output.h function.h cselib.h $(GGC_H) $(TM_P_H) gt-cselib.h
@ -1615,10 +1620,9 @@ df.o : df.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(BASIC_BLOCK_H) df.h $(FIBHEAP_H)
conflict.o : conflict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(OBSTACK_H) \
$(HASHTAB_H) $(RTL_H) hard-reg-set.h $(BASIC_BLOCK_H)
profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
flags.h insn-config.h output.h $(REGS_H) $(EXPR_H) function.h \
gcov-io.h gcov-iov.h toplev.h $(GGC_H) hard-reg-set.h $(BASIC_BLOCK_H) \
$(TARGET_H) langhooks.h profile.h libfuncs.h gt-profile.h $(HASHTAB_H)
profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) flags.h output.h $(REGS_H) $(EXPR_H) function.h \
toplev.h $(BASIC_BLOCK_H) $(COVERAGE_H)
loop.o : loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h $(LOOP_H) \
insn-config.h $(REGS_H) hard-reg-set.h $(RECOG_H) $(EXPR_H) \
real.h $(PREDICT_H) $(BASIC_BLOCK_H) function.h cfgloop.h \
@ -1656,7 +1660,7 @@ cfgloopanal.o : cfgloopanal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h output.h coretypes.h $(TM_H)
loop-init.o : loop-init.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h profile.h \
$(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h \
coretypes.h $(TM_H)
loop-unswitch.o : loop-unswitch.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \
$(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h params.h \
@ -1728,7 +1732,7 @@ sched-rgn.o : sched-rgn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H) $(TARGET_H)
sched-ebb.o : sched-ebb.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
sched-int.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
$(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H) $(PARAMS_H) profile.h
$(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H) $(PARAMS_H)
sched-vis.o : sched-vis.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
sched-int.h hard-reg-set.h $(BASIC_BLOCK_H) $(INSN_ATTR_H) $(REGS_H) $(TM_P_H) \
$(TARGET_H) real.h
@ -1747,14 +1751,14 @@ sreal.o: sreal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) sreal.h
predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
flags.h insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
$(RECOG_H) function.h except.h $(EXPR_H) $(TM_P_H) $(PREDICT_H) sreal.h \
$(PARAMS_H) $(TARGET_H) cfgloop.h
$(PARAMS_H) $(TARGET_H) cfgloop.h $(COVERAGE_H)
lists.o: lists.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h $(RTL_H) $(GGC_H)
bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(BASIC_BLOCK_H) flags.h output.h cfglayout.h $(FIBHEAP_H) \
$(TARGET_H)
tracer.o : tracer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
$(BASIC_BLOCK_H) hard-reg-set.h output.h cfglayout.h flags.h \
$(PARAMS_H) profile.h
$(PARAMS_H) $(COVERAGE_H)
cfglayout.o : cfglayout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TREE_H) insn-config.h $(BASIC_BLOCK_H) hard-reg-set.h output.h \
function.h cfglayout.h cfgloop.h $(TARGET_H)
@ -1966,10 +1970,10 @@ s-preds: genpreds$(build_exeext) $(srcdir)/move-if-change
GTFILES = $(srcdir)/location.h $(srcdir)/coretypes.h $(srcdir)/cpplib.h \
$(host_xm_file_list) $(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) \
$(srcdir)/bitmap.h $(srcdir)/function.h $(srcdir)/rtl.h $(srcdir)/optabs.h \
$(srcdir)/tree.h $(srcdir)/libfuncs.h $(srcdir)/hashtable.h $(srcdir)/real.h \
$(srcdir)/varray.h $(srcdir)/ssa.h $(srcdir)/insn-addr.h $(srcdir)/cselib.h \
$(srcdir)/basic-block.h $(srcdir)/location.h \
$(srcdir)/bitmap.h $(srcdir)/coverage.c $(srcdir)/function.h $(srcdir)/rtl.h \
$(srcdir)/optabs.h $(srcdir)/tree.h $(srcdir)/libfuncs.h $(srcdir)/hashtable.h \
$(srcdir)/real.h $(srcdir)/varray.h $(srcdir)/ssa.h $(srcdir)/insn-addr.h \
$(srcdir)/cselib.h $(srcdir)/basic-block.h $(srcdir)/location.h \
$(srcdir)/c-common.h $(srcdir)/c-tree.h \
$(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \
$(srcdir)/dbxout.c $(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \
@ -1988,14 +1992,15 @@ GTFILES_FILES_FILES = @all_gtfiles_files_files@
GTFILES_LANG_DIR_NAMES = @subdirs@
GTFILES_SRCDIR = @srcdir@
gt-cgraph.h gtype-desc.h gtype-desc.c gt-except.h gt-function.h : s-gtype; @true
gt-integrate.h gt-stmt.h gt-tree.h gt-varasm.h gt-emit-rtl.h : s-gtype; @true
gt-explow.h gt-stor-layout.h gt-regclass.h gt-lists.h : s-gtype; @true
gt-alias.h gt-cselib.h gt-fold-const.h gt-gcse.h gt-profile.h : s-gtype; @true
gt-expr.h gt-sdbout.h gt-optabs.h gt-bitmap.h gt-dwarf2out.h : s-gtype ; @true
gt-ra-build.h gt-reg-stack.h gt-dwarf2asm.h gt-dbxout.h : s-gtype ; @true
gt-c-common.h gt-c-decl.h gt-c-parse.h gt-c-pragma.h : s-gtype; @true
gt-c-objc-common.h gtype-c.h gt-location.h gt-stringpool.h : s-gtype ; @true
gt-cgraph.h gt-coverage.h gtype-desc.h gtype-desc.c gt-except.h \
gt-function.h gt-integrate.h gt-stmt.h gt-tree.h gt-varasm.h \
gt-emit-rtl.h gt-explow.h gt-stor-layout.h gt-regclass.h \
gt-lists.h gt-alias.h gt-cselib.h gt-fold-const.h gt-gcse.h \
gt-expr.h gt-sdbout.h gt-optabs.h gt-bitmap.h \
gt-dwarf2out.h gt-ra-build.h gt-reg-stack.h gt-dwarf2asm.h \
gt-dbxout.h gt-c-common.h gt-c-decl.h gt-c-parse.h \
gt-c-pragma.h gt-c-objc-common.h gtype-c.h gt-location.h \
gt-stringpool.h : s-gtype ; @true
gtyp-gen.h: Makefile
echo "/* This file is machine generated. Do not edit. */" > tmp-gtyp.h

1146
gcc/coverage.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* profile.h - Defines data exported from profile.c to other passes.
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
/* coverage.h - Defines data exported from coverage.c
Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@ -18,8 +18,10 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#ifndef GCC_PROFILE_H
#define GCC_PROFILE_H
#ifndef GCC_COVERAGE_H
#define GCC_COVERAGE_H
#include "gcov-io.h"
/* The number of different counter sections. */
#define MAX_COUNTER_SECTIONS 1
@ -57,6 +59,14 @@ struct profile_info
extern struct profile_info profile_info;
extern void coverage_init (const char *);
extern void coverage_finish (void);
extern void coverage_end_function (void);
extern int coverage_begin_output (void);
extern rtx coverage_counter_ref (unsigned /*tag*/, unsigned/*num*/);
gcov_type *get_coverage_counts (unsigned /*tag*/, unsigned /*expected*/);
struct section_info *find_counters_section PARAMS ((unsigned));
#endif

View File

@ -25,6 +25,7 @@ Boston, MA 02111-1307, USA. */
#include <getopt.h>
#define IN_GCOV (-1)
#include "gcov-io.h"
#include "gcov-io.c"
static void dump_file PARAMS ((const char *));
static void print_prefix PARAMS ((const char *, unsigned));

431
gcc/gcov-io.c Normal file
View File

@ -0,0 +1,431 @@
/* File format for coverage information
Copyright (C) 1996, 1997, 1998, 2000, 2002,
2003 Free Software Foundation, Inc.
Contributed by Bob Manson <manson@cygnus.com>.
Completely remangled by Nathan Sidwell <nathan@codesourcery.com>.
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 2, 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* Routines declared in gcov-io.h. This file should be #included by
another source file, after having #included gcov-io.h. */
/* Open a gcov file. NAME is the name of the file to open and MODE
indicates whether a new file should be created, or an existing file
opened for modification. If MODE is >= 0 an existing file will be
opened, if possible, and if MODE is <= 0, a new file will be
created. Use MODE=0 to attempt to reopen an existing file and then
fall back on creating a new one. Return zero on failure, >0 on
opening an existing file and <0 on creating a new one. */
GCOV_LINKAGE int
gcov_open (const char *name, int mode)
{
int result = 1;
size_t alloc = 1024;
#if defined (TARGET_HAS_F_SETLKW) && IN_LIBGCOV
struct flock s_flock;
s_flock.l_type = F_WRLCK;
s_flock.l_whence = SEEK_SET;
s_flock.l_start = 0;
s_flock.l_len = 0; /* Until EOF. */
s_flock.l_pid = getpid ();
#endif
if (gcov_var.file)
abort ();
gcov_var.position = gcov_var.length = 0;
gcov_var.error = gcov_var.modified = 0;
if (mode >= 0)
gcov_var.file = fopen (name, "r+b");
if (!gcov_var.file && mode <= 0)
{
result = -1;
gcov_var.file = fopen (name, "w+b");
}
if (!gcov_var.file)
return 0;
#if defined (TARGET_HAS_F_SETLKW) && IN_LIBGCOV
while (fcntl (fileno (gcov_var.file), F_SETLKW, &s_flock)
&& errno == EINTR)
continue;
#endif
if (result >= 0)
{
if (fseek (gcov_var.file, 0, SEEK_END))
{
fclose (gcov_var.file);
gcov_var.file = 0;
return 0;
}
gcov_var.length = ftell (gcov_var.file);
fseek (gcov_var.file, 0, SEEK_SET);
alloc += gcov_var.length;
}
if (alloc > gcov_var.alloc)
{
if (gcov_var.buffer)
free (gcov_var.buffer);
gcov_var.alloc = alloc;
#if IN_LIBGCOV
gcov_var.buffer = malloc (gcov_var.alloc);
if (!gcov_var.buffer)
{
fclose (gcov_var.file);
gcov_var.file = 0;
gcov_var.length = 0;
gcov_var.alloc = 0;
return 0;
}
#else
gcov_var.buffer = xmalloc (gcov_var.alloc);
#endif
}
if (result >= 0
&& fread (gcov_var.buffer, gcov_var.length, 1, gcov_var.file) != 1)
{
fclose (gcov_var.file);
gcov_var.file = 0;
gcov_var.length = 0;
return 0;
}
return result;
}
/* Close the current gcov file. Flushes data to disk. Returns nonzero
on failure or error flag set. */
GCOV_LINKAGE int
gcov_close ()
{
int result = 0;
if (gcov_var.file)
{
if (gcov_var.modified
&& (fseek (gcov_var.file, 0, SEEK_SET)
|| fwrite (gcov_var.buffer, gcov_var.length,
1, gcov_var.file) != 1))
result = 1;
fclose (gcov_var.file);
gcov_var.file = 0;
gcov_var.length = 0;
}
#if !IN_LIBGCOV
free (gcov_var.buffer);
gcov_var.alloc = 0;
gcov_var.buffer = 0;
#endif
return result ? 1 : gcov_var.error;
}
#if !IN_GCOV
/* Allocate space to write BYTES bytes to the gcov file. Return a
pointer to those bytes, or NULL on failure. */
GCOV_LINKAGE unsigned char *
gcov_write_bytes (unsigned bytes)
{
char unsigned *result;
if (gcov_var.position + bytes > gcov_var.alloc)
{
size_t new_size = (gcov_var.alloc + bytes) * 3 / 2;
if (!gcov_var.buffer)
return 0;
#if IN_LIBGCOV
result = realloc (gcov_var.buffer, new_size);
if (!result)
{
free (gcov_var.buffer);
gcov_var.buffer = 0;
gcov_var.alloc = 0;
gcov_var.position = gcov_var.length = 0;
gcov_var.error = 1;
return 0;
}
#else
result = xrealloc (gcov_var.buffer, new_size);
#endif
gcov_var.alloc = new_size;
gcov_var.buffer = result;
}
result = &gcov_var.buffer[gcov_var.position];
gcov_var.position += bytes;
gcov_var.modified = 1;
if (gcov_var.position > gcov_var.length)
gcov_var.length = gcov_var.position;
return result;
}
/* Write unsigned VALUE to coverage file. Sets error flag
appropriately. */
GCOV_LINKAGE void
gcov_write_unsigned (unsigned value)
{
unsigned char *buffer = gcov_write_bytes (4);
unsigned ix;
if (!buffer)
return;
for (ix = 4; ix--; )
{
buffer[ix] = value;
value >>= 8;
}
if (sizeof (value) > 4 && value)
gcov_var.error = -1;
return;
}
/* Write counter VALUE to coverage file. Sets error flag
appropriately. */
#if IN_LIBGCOV
GCOV_LINKAGE void
gcov_write_counter (gcov_type value)
{
unsigned char *buffer = gcov_write_bytes (8);
unsigned ix;
if (!buffer)
return;
for (ix = 8; ix--; )
{
buffer[ix] = value;
value >>= 8;
}
if ((sizeof (value) > 8 && value) || value < 0)
gcov_var.error = -1;
return;
}
#endif /* IN_LIBGCOV */
/* Write STRING to coverage file. Sets error flag on file
error, overflow flag on overflow */
GCOV_LINKAGE void
gcov_write_string (const char *string)
{
unsigned length = 0;
unsigned pad = 0;
unsigned rem = 0;
unsigned char *buffer;
if (string)
{
length = strlen (string);
rem = 4 - (length & 3);
}
buffer = gcov_write_bytes (4 + length + rem);
if (buffer)
{
unsigned ix;
unsigned value = length;
for (ix = 4; ix--; )
{
buffer[ix] = value;
value >>= 8;
}
memcpy (buffer + 4, string, length);
memcpy (buffer + 4 + length, &pad, rem);
}
}
/* Write a tag TAG and reserve space for the record length. Return a
value to be used for gcov_write_length. */
GCOV_LINKAGE unsigned long
gcov_write_tag (unsigned tag)
{
unsigned long result = gcov_var.position;
unsigned char *buffer = gcov_write_bytes (8);
unsigned ix;
if (!buffer)
return 0;
for (ix = 4; ix--; )
{
buffer[ix] = tag;
tag >>= 8;
}
memset (buffer + 4, 0, 4);
return result;
}
/* Write a record length using POSITION, which was returned by
gcov_write_tag. The current file position is the end of the
record, and is restored before returning. Returns nonzero on
overflow. */
GCOV_LINKAGE void
gcov_write_length (unsigned long position)
{
if (position)
{
unsigned length = gcov_var.position - position - 8;
unsigned char *buffer = &gcov_var.buffer[position + 4];
unsigned ix;
for (ix = 4; ix--; )
{
buffer[ix] = length;
length >>= 8;
}
}
}
#if IN_LIBGCOV
/* Write a summary structure to the gcov file. Return non-zero on
overflow. */
GCOV_LINKAGE void
gcov_write_summary (unsigned tag, const struct gcov_summary *summary)
{
unsigned long base;
base = gcov_write_tag (tag);
gcov_write_unsigned (summary->checksum);
gcov_write_unsigned (summary->runs);
gcov_write_unsigned (summary->arcs);
gcov_write_counter (summary->arc_sum);
gcov_write_counter (summary->arc_max_one);
gcov_write_counter (summary->arc_sum_max);
gcov_write_length (base);
}
#endif /* IN_LIBGCOV */
#endif /*!IN_GCOV */
/* Return a pointer to read BYTES bytes from the gcov file. Returns
NULL on failure (read past EOF). */
GCOV_LINKAGE const unsigned char *
gcov_read_bytes (unsigned bytes)
{
const unsigned char *result;
if (gcov_var.position + bytes > gcov_var.length)
{
gcov_var.error = 1;
return 0;
}
result = &gcov_var.buffer[gcov_var.position];
gcov_var.position += bytes;
return result;
}
/* Read unsigned value from a coverage file. Sets error flag on file
error, overflow flag on overflow */
GCOV_LINKAGE unsigned
gcov_read_unsigned ()
{
unsigned value = 0;
unsigned ix;
const unsigned char *buffer = gcov_read_bytes (4);
if (!buffer)
return 0;
for (ix = sizeof (value); ix < 4; ix++)
if (buffer[ix])
gcov_var.error = -1;
for (ix = 0; ix != 4; ix++)
{
value <<= 8;
value |= buffer[ix];
}
return value;
}
/* Read counter value from a coverage file. Sets error flag on file
error, overflow flag on overflow */
GCOV_LINKAGE gcov_type
gcov_read_counter ()
{
gcov_type value = 0;
unsigned ix;
const unsigned char *buffer = gcov_read_bytes (8);
if (!buffer)
return 0;
for (ix = sizeof (value); ix < 8; ix++)
if (buffer[ix])
gcov_var.error = -1;
for (ix = 0; ix != 8; ix++)
{
value <<= 8;
value |= buffer[ix];
}
if (value < 0)
gcov_var.error = -1;
return value;
}
/* Read string from coverage file. Returns a pointer to a static
buffer, or NULL on empty string. You must copy the string before
calling another gcov function. */
GCOV_LINKAGE const char *
gcov_read_string ()
{
unsigned length = gcov_read_unsigned ();
if (!length)
return 0;
length += 4 - (length & 3);
return (const char *) gcov_read_bytes (length);
}
GCOV_LINKAGE void
gcov_read_summary (struct gcov_summary *summary)
{
summary->checksum = gcov_read_unsigned ();
summary->runs = gcov_read_unsigned ();
summary->arcs = gcov_read_unsigned ();
summary->arc_sum = gcov_read_counter ();
summary->arc_max_one = gcov_read_counter ();
summary->arc_sum_max = gcov_read_counter ();
}
#if IN_GCOV > 0
/* Return the modification time of the current gcov file. */
GCOV_LINKAGE time_t
gcov_time ()
{
struct stat status;
if (fstat (fileno (gcov_var.file), &status))
return 0;
else
return status.st_mtime;
}
#endif /* IN_GCOV */

View File

@ -1,5 +1,6 @@
/* File format for coverage information
Copyright (C) 1996, 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
Copyright (C) 1996, 1997, 1998, 2000, 2002,
2003 Free Software Foundation, Inc.
Contributed by Bob Manson <manson@cygnus.com>.
Completely remangled by Nathan Sidwell <nathan@codesourcery.com>.
@ -160,6 +161,17 @@ typedef HOST_WIDEST_INT gcov_type;
#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. */
#define GCOV_DATA_SUFFIX ".da"
#define GCOV_GRAPH_SUFFIX ".bbg"
@ -227,7 +239,7 @@ struct gcov_summary
by write_profile must match these. */
/* Information about section of counters for a function. */
struct counter_section
struct gcov_counter_section
{
unsigned tag; /* Tag of the section. */
unsigned n_counters; /* Number of counters in the section. */
@ -235,7 +247,7 @@ struct counter_section
#if IN_LIBGCOV
/* Information about section of counters for an object file. */
struct counter_section_data
struct gcov_counter_section_data
{
unsigned tag; /* Tag of the section. */
unsigned n_counters; /* Number of counters in the section. */
@ -243,12 +255,12 @@ struct counter_section_data
};
/* Information about a single function. */
struct function_info
struct gcov_function_info
{
const char *name; /* (mangled) name of function */
unsigned checksum; /* function checksum */
unsigned n_counter_sections; /* Number of types of counters */
const struct counter_section *counter_sections;
const struct gcov_counter_section *counter_sections;
/* The section descriptions */
};
@ -262,10 +274,10 @@ struct gcov_info
long wkspc; /* libgcc workspace */
unsigned n_functions; /* number of functions */
const struct function_info *functions; /* table of functions */
const struct gcov_function_info *functions; /* table of functions */
unsigned n_counter_sections; /* Number of types of counters */
const struct counter_section_data *counter_sections;
const struct gcov_counter_section_data *counter_sections;
/* The data to be put into the sections. */
};
@ -275,18 +287,12 @@ extern void __gcov_init (struct gcov_info *);
/* Called before fork, to avoid double counting. */
extern void __gcov_flush (void);
/* Since this file is used in both host and target files, and we don't
include ansidecl.h in target files, provide some necessary macros. */
#ifndef ATTRIBUTE_UNUSED
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
#endif
#endif /* IN_LIBGCOV */
/* Because small reads and writes, interspersed with seeks cause lots
of disk activity, we buffer the entire count files. */
static struct gcov_var
GCOV_LINKAGE struct gcov_var
{
FILE *file;
size_t position;
@ -298,26 +304,26 @@ static struct gcov_var
} gcov_var;
/* Functions for reading and writing gcov files. */
static int gcov_open (const char */*name*/, int /*truncate*/);
static int gcov_close (void);
GCOV_LINKAGE int gcov_open (const char */*name*/, int /*truncate*/);
GCOV_LINKAGE int gcov_close (void);
#if !IN_GCOV
static unsigned char *gcov_write_bytes (unsigned);
static void gcov_write_unsigned (unsigned);
GCOV_LINKAGE unsigned char *gcov_write_bytes (unsigned);
GCOV_LINKAGE void gcov_write_unsigned (unsigned);
#if IN_LIBGCOV
static void gcov_write_counter (gcov_type);
GCOV_LINKAGE void gcov_write_counter (gcov_type);
#endif
static void gcov_write_string (const char *);
static unsigned long gcov_write_tag (unsigned);
static void gcov_write_length (unsigned long /*position*/);
GCOV_LINKAGE void gcov_write_string (const char *);
GCOV_LINKAGE unsigned long gcov_write_tag (unsigned);
GCOV_LINKAGE void gcov_write_length (unsigned long /*position*/);
#if IN_LIBGCOV
static void gcov_write_summary (unsigned, const struct gcov_summary *);
GCOV_LINKAGE void gcov_write_summary (unsigned, const struct gcov_summary *);
#endif
#endif /* !IN_GCOV */
static const unsigned char *gcov_read_bytes (unsigned);
static unsigned gcov_read_unsigned (void);
static gcov_type gcov_read_counter (void);
static const char *gcov_read_string (void);
static void gcov_read_summary (struct gcov_summary *);
GCOV_LINKAGE const unsigned char *gcov_read_bytes (unsigned);
GCOV_LINKAGE unsigned gcov_read_unsigned (void);
GCOV_LINKAGE gcov_type gcov_read_counter (void);
GCOV_LINKAGE const char *gcov_read_string (void);
GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *);
static unsigned long gcov_position (void);
static void gcov_seek (unsigned long /*base*/, unsigned /*length */);
@ -325,400 +331,9 @@ static unsigned long gcov_seek_end (void);
static int gcov_is_eof (void);
static int gcov_is_error (void);
#if IN_GCOV > 0
static time_t gcov_time (void);
GCOV_LINKAGE time_t gcov_time (void);
#endif
/* Open a gcov file. NAME is the name of the file to open and MODE
indicates whether a new file should be created, or an existing file
opened for modification. If MODE is >= 0 an existing file will be
opened, if possible, and if MODE is <= 0, a new file will be
created. Use MODE=0 to attempt to reopen an existing file and then
fall back on creating a new one. Return zero on failure, >0 on
opening an existing file and <0 on creating a new one. */
static int
gcov_open (const char *name, int mode)
{
int result = 1;
size_t alloc = 1024;
#if defined (TARGET_HAS_F_SETLKW) && IN_LIBGCOV
struct flock s_flock;
s_flock.l_type = F_WRLCK;
s_flock.l_whence = SEEK_SET;
s_flock.l_start = 0;
s_flock.l_len = 0; /* Until EOF. */
s_flock.l_pid = getpid ();
#endif
if (gcov_var.file)
abort ();
gcov_var.position = gcov_var.length = 0;
gcov_var.error = gcov_var.modified = 0;
if (mode >= 0)
gcov_var.file = fopen (name, "r+b");
if (!gcov_var.file && mode <= 0)
{
result = -1;
gcov_var.file = fopen (name, "w+b");
}
if (!gcov_var.file)
return 0;
#if defined (TARGET_HAS_F_SETLKW) && IN_LIBGCOV
while (fcntl (fileno (gcov_var.file), F_SETLKW, &s_flock)
&& errno == EINTR)
continue;
#endif
if (result >= 0)
{
if (fseek (gcov_var.file, 0, SEEK_END))
{
fclose (gcov_var.file);
gcov_var.file = 0;
return 0;
}
gcov_var.length = ftell (gcov_var.file);
fseek (gcov_var.file, 0, SEEK_SET);
alloc += gcov_var.length;
}
if (alloc > gcov_var.alloc)
{
if (gcov_var.buffer)
free (gcov_var.buffer);
gcov_var.alloc = alloc;
#if IN_LIBGCOV
gcov_var.buffer = malloc (gcov_var.alloc);
if (!gcov_var.buffer)
{
fclose (gcov_var.file);
gcov_var.file = 0;
gcov_var.length = 0;
gcov_var.alloc = 0;
return 0;
}
#else
gcov_var.buffer = xmalloc (gcov_var.alloc);
#endif
}
if (result >= 0
&& fread (gcov_var.buffer, gcov_var.length, 1, gcov_var.file) != 1)
{
fclose (gcov_var.file);
gcov_var.file = 0;
gcov_var.length = 0;
return 0;
}
return result;
}
/* Close the current gcov file. Flushes data to disk. Returns nonzero
on failure or error flag set. */
static int
gcov_close ()
{
int result = 0;
if (gcov_var.file)
{
if (gcov_var.modified
&& (fseek (gcov_var.file, 0, SEEK_SET)
|| fwrite (gcov_var.buffer, gcov_var.length,
1, gcov_var.file) != 1))
result = 1;
fclose (gcov_var.file);
gcov_var.file = 0;
gcov_var.length = 0;
}
#if !IN_LIBGCOV
free (gcov_var.buffer);
gcov_var.alloc = 0;
gcov_var.buffer = 0;
#endif
return result ? 1 : gcov_var.error;
}
#if !IN_GCOV
/* Allocate space to write BYTES bytes to the gcov file. Return a
pointer to those bytes, or NULL on failure. */
static unsigned char *
gcov_write_bytes (unsigned bytes)
{
char unsigned *result;
if (gcov_var.position + bytes > gcov_var.alloc)
{
size_t new_size = (gcov_var.alloc + bytes) * 3 / 2;
if (!gcov_var.buffer)
return 0;
#if IN_LIBGCOV
result = realloc (gcov_var.buffer, new_size);
if (!result)
{
free (gcov_var.buffer);
gcov_var.buffer = 0;
gcov_var.alloc = 0;
gcov_var.position = gcov_var.length = 0;
gcov_var.error = 1;
return 0;
}
#else
result = xrealloc (gcov_var.buffer, new_size);
#endif
gcov_var.alloc = new_size;
gcov_var.buffer = result;
}
result = &gcov_var.buffer[gcov_var.position];
gcov_var.position += bytes;
gcov_var.modified = 1;
if (gcov_var.position > gcov_var.length)
gcov_var.length = gcov_var.position;
return result;
}
/* Write unsigned VALUE to coverage file. Sets error flag
appropriately. */
static void
gcov_write_unsigned (unsigned value)
{
unsigned char *buffer = gcov_write_bytes (4);
unsigned ix;
if (!buffer)
return;
for (ix = 4; ix--; )
{
buffer[ix] = value;
value >>= 8;
}
if (sizeof (value) > 4 && value)
gcov_var.error = -1;
return;
}
/* Write counter VALUE to coverage file. Sets error flag
appropriately. */
#if IN_LIBGCOV
static void
gcov_write_counter (gcov_type value)
{
unsigned char *buffer = gcov_write_bytes (8);
unsigned ix;
if (!buffer)
return;
for (ix = 8; ix--; )
{
buffer[ix] = value;
value >>= 8;
}
if ((sizeof (value) > 8 && value) || value < 0)
gcov_var.error = -1;
return;
}
#endif /* IN_LIBGCOV */
/* Write STRING to coverage file. Sets error flag on file
error, overflow flag on overflow */
static void
gcov_write_string (const char *string)
{
unsigned length = 0;
unsigned pad = 0;
unsigned rem = 0;
unsigned char *buffer;
if (string)
{
length = strlen (string);
rem = 4 - (length & 3);
}
buffer = gcov_write_bytes (4 + length + rem);
if (buffer)
{
unsigned ix;
unsigned value = length;
for (ix = 4; ix--; )
{
buffer[ix] = value;
value >>= 8;
}
memcpy (buffer + 4, string, length);
memcpy (buffer + 4 + length, &pad, rem);
}
}
/* Write a tag TAG and reserve space for the record length. Return a
value to be used for gcov_write_length. */
static unsigned long
gcov_write_tag (unsigned tag)
{
unsigned long result = gcov_var.position;
unsigned char *buffer = gcov_write_bytes (8);
unsigned ix;
if (!buffer)
return 0;
for (ix = 4; ix--; )
{
buffer[ix] = tag;
tag >>= 8;
}
memset (buffer + 4, 0, 4);
return result;
}
/* Write a record length using POSITION, which was returned by
gcov_write_tag. The current file position is the end of the
record, and is restored before returning. Returns nonzero on
overflow. */
static void
gcov_write_length (unsigned long position)
{
if (position)
{
unsigned length = gcov_var.position - position - 8;
unsigned char *buffer = &gcov_var.buffer[position + 4];
unsigned ix;
for (ix = 4; ix--; )
{
buffer[ix] = length;
length >>= 8;
}
}
}
#if IN_LIBGCOV
/* Write a summary structure to the gcov file. Return non-zero on
overflow. */
static void
gcov_write_summary (unsigned tag, const struct gcov_summary *summary)
{
unsigned long base;
base = gcov_write_tag (tag);
gcov_write_unsigned (summary->checksum);
gcov_write_unsigned (summary->runs);
gcov_write_unsigned (summary->arcs);
gcov_write_counter (summary->arc_sum);
gcov_write_counter (summary->arc_max_one);
gcov_write_counter (summary->arc_sum_max);
gcov_write_length (base);
}
#endif /* IN_LIBGCOV */
#endif /*!IN_GCOV */
/* Return a pointer to read BYTES bytes from the gcov file. Returns
NULL on failure (read past EOF). */
static const unsigned char *
gcov_read_bytes (unsigned bytes)
{
const unsigned char *result;
if (gcov_var.position + bytes > gcov_var.length)
{
gcov_var.error = 1;
return 0;
}
result = &gcov_var.buffer[gcov_var.position];
gcov_var.position += bytes;
return result;
}
/* Read unsigned value from a coverage file. Sets error flag on file
error, overflow flag on overflow */
static unsigned
gcov_read_unsigned ()
{
unsigned value = 0;
unsigned ix;
const unsigned char *buffer = gcov_read_bytes (4);
if (!buffer)
return 0;
for (ix = sizeof (value); ix < 4; ix++)
if (buffer[ix])
gcov_var.error = -1;
for (ix = 0; ix != 4; ix++)
{
value <<= 8;
value |= buffer[ix];
}
return value;
}
/* Read counter value from a coverage file. Sets error flag on file
error, overflow flag on overflow */
static gcov_type
gcov_read_counter ()
{
gcov_type value = 0;
unsigned ix;
const unsigned char *buffer = gcov_read_bytes (8);
if (!buffer)
return 0;
for (ix = sizeof (value); ix < 8; ix++)
if (buffer[ix])
gcov_var.error = -1;
for (ix = 0; ix != 8; ix++)
{
value <<= 8;
value |= buffer[ix];
}
if (value < 0)
gcov_var.error = -1;
return value;
}
/* Read string from coverage file. Returns a pointer to a static
buffer, or NULL on empty string. You must copy the string before
calling another gcov function. */
static const char *
gcov_read_string ()
{
unsigned length = gcov_read_unsigned ();
if (!length)
return 0;
length += 4 - (length & 3);
return (const char *) gcov_read_bytes (length);
}
#define GCOV_SUMMARY_LENGTH 44
static void
gcov_read_summary (struct gcov_summary *summary)
{
summary->checksum = gcov_read_unsigned ();
summary->runs = gcov_read_unsigned ();
summary->arcs = gcov_read_unsigned ();
summary->arc_sum = gcov_read_counter ();
summary->arc_max_one = gcov_read_counter ();
summary->arc_sum_max = gcov_read_counter ();
}
/* Save the current position in the gcov file. */
static inline unsigned long
@ -770,18 +385,4 @@ gcov_is_error ()
return gcov_var.file ? gcov_var.error : 1;
}
#if IN_GCOV > 0
/* Return the modification time of the current gcov file. */
static time_t
gcov_time ()
{
struct stat status;
if (fstat (fileno (gcov_var.file), &status))
return 0;
else
return status.st_mtime;
}
#endif /* IN_GCOV */
#endif /* GCC_GCOV_IO_H */

View File

@ -59,6 +59,7 @@ void __gcov_flush (void) { }
#endif
#define IN_LIBGCOV 1
#include "gcov-io.h"
#include "gcov-io.c"
/* Chain of per-object gcov structures. */
static struct gcov_info *gcov_list;
@ -136,7 +137,7 @@ gcov_exit (void)
int error;
int merging;
unsigned long base;
const struct function_info *fn_info;
const struct gcov_function_info *fn_info;
gcov_type **counters;
gcov_type *count_ptr;
gcov_type object_max_one = 0;

View File

@ -27,7 +27,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "basic-block.h"
#include "cfgloop.h"
#include "cfglayout.h"
#include "profile.h"
/* Initialize loop optimizer. */

File diff suppressed because it is too large Load Diff

View File

@ -2210,11 +2210,15 @@ extern void dump_local_alloc PARAMS ((FILE *));
extern int local_alloc PARAMS ((void));
extern int function_invariant_p PARAMS ((rtx));
/* In coverage.c */
extern void coverage_init (const char *);
extern void coverage_finish (void);
extern void coverage_end_function (void);
/* In profile.c */
extern void init_branch_prob PARAMS ((const char *));
extern void init_branch_prob PARAMS ((void));
extern void branch_prob PARAMS ((void));
extern void end_branch_prob PARAMS ((void));
extern void create_profiler PARAMS ((void));
/* In reg-stack.c */
#ifdef BUFSIZ

View File

@ -2195,7 +2195,7 @@ compile_file ()
/* Initialize yet another pass. */
init_final (main_input_filename);
init_branch_prob (aux_base_name);
coverage_init (aux_base_name);
timevar_push (TV_PARSE);
@ -2216,11 +2216,10 @@ compile_file ()
(*lang_hooks.decls.final_write_globals)();
if (profile_arc_flag)
/* This must occur after the loop to output deferred functions.
Else the profiler initializer would not be emitted if all the
functions in this compilation unit were deferred. */
create_profiler ();
/* This must occur after the loop to output deferred functions.
Else the coverage initializer would not be emitted if all the
functions in this compilation unit were deferred. */
coverage_finish ();
/* Write out any pending weak symbol declarations. */
@ -3765,6 +3764,8 @@ rest_of_compilation (decl)
exit_rest_of_compilation:
coverage_end_function ();
/* In case the function was not output,
don't leave any temporary anonymous types
queued up for sdb output. */

View File

@ -1,6 +1,6 @@
/* The tracer pass for the GNU compiler.
Contributed by Jan Hubicka, SuSE Labs.
Copyright (C) 2001, 2002 Free Software Foundation, Inc.
Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@ -46,7 +46,7 @@
#include "fibheap.h"
#include "flags.h"
#include "params.h"
#include "profile.h"
#include "coverage.h"
static int count_insns PARAMS ((basic_block));
static bool ignore_bb_p PARAMS ((basic_block));