Commit c77556a5 by Rong Xu Committed by Rong Xu

Add gcov-tool: an offline gcda profile processing tool Support.

2014-07-10  Rong Xu  <xur@google.com>

	Add gcov-tool: an offline gcda profile processing tool
	Support.
	* gcc/gcov-io.c (gcov_position): Make avaialble to gcov-tool.
	(gcov_is_error): Ditto.
	(gcov_read_string): Ditto.
	(gcov_read_sync): Ditto.
	* gcc/gcov-io.h: Move counter defines to gcov-counter.def.
	* gcc/gcov-dump.c (tag_counters): Use gcov-counter.def.
	* gcc/coverage.c: Ditto.
	* gcc/gcov-tool.c: Offline gcda profile processing tool.
        (unlink_gcda_file): Remove one gcda file.
	(unlink_profile_dir): Remove gcda files from the profile path.
	(gcov_output_files): Output gcda files to an output dir.
	(profile_merge): Merge two profiles in directory.
	(print_merge_usage_message): Print merge usage.
	(merge_usage): Print merge usage and exit.
	(do_merge): Driver for profile merge sub-command.
	(profile_rewrite): Rewrite profile.
	(print_rewrite_usage_message): Print rewrite usage.
	(rewrite_usage): Print rewrite usage and exit.
	(do_rewrite): Driver for profile rewrite sub-command.
	(print_usage): Print gcov-info usage and exit.
	(print_version): Print gcov-info version.
	(process_args): Process arguments.
	(main): Main routine for gcov-tool.
	* gcc/Makefile.in: Build and install gcov-tool.
	* gcc/gcov-counter.def: New file split from gcov-io.h.
	* libgcc/libgcov-driver.c (gcov_max_filename): Make available
        to gcov-tool.
	* libgcc/libgcov-merge.c (__gcov_merge_add): Replace
        gcov_read_counter() with a Macro.
	(__gcov_merge_ior): Ditto.
	(__gcov_merge_time_profile): Ditto.
	(__gcov_merge_single): Ditto.
	(__gcov_merge_delta): Ditto.
	* libgcc/libgcov-util.c (void gcov_set_verbose): Set the verbose flag
        in the utility functions.
	(set_fn_ctrs): Utility function for reading gcda files to in-memory
        gcov_list object link lists.
	(tag_function): Ditto.
	(tag_blocks): Ditto.
	(tag_arcs): Ditto.
	(tag_lines): Ditto.
	(tag_counters): Ditto.
	(tag_summary): Ditto.
	(read_gcda_finalize): Ditto.
	(read_gcda_file): Ditto.
	(ftw_read_file): Ditto.
	(read_profile_dir_init): Ditto.
	(gcov_read_profile_dir): Ditto.
	(gcov_read_counter_mem): Ditto.
	(gcov_get_merge_weight): Ditto.
	(merge_wrapper): A wrapper function that calls merging handler.
	(gcov_merge): Merge two gcov_info objects with weights.
	(find_match_gcov_info): Find the matched gcov_info in the list.
	(gcov_profile_merge): Merge two gcov_info object lists.
	(__gcov_add_counter_op): Process edge profile counter values.
	(__gcov_ior_counter_op): Process IOR profile counter values.
	(__gcov_delta_counter_op): Process delta profile counter values.
	(__gcov_single_counter_op): Process single  profile counter values.
	(fp_scale): Callback function for float-point scaling.
	(int_scale): Callback function for integer fraction scaling. 
	(gcov_profile_scale): Scaling profile counters.
	(gcov_profile_normalize): Normalize profile counters.
	* libgcc/libgcov.h: Add headers and functions for gcov-tool use.
        (gcov_get_counter): New.
        (gcov_get_counter_target): Ditto.
        (struct gcov_info): Make the functions field mutable in gcov-tool
        compilation.
	* gcc/doc/gcc.texi: Include gcov-tool.texi.
	* gcc/doc/gcov-tool.texi: Document for gcov-tool.

From-SVN: r212448
parent c14e64d4
2014-07-10 Rong Xu <xur@google.com>
Add gcov-tool: an offline gcda profile processing tool
Support.
* gcov-io.c (gcov_position): Make avaialble to gcov-tool.
(gcov_is_error): Ditto.
(gcov_read_string): Ditto.
(gcov_read_sync): Ditto.
* gcov-io.h: Move counter defines to gcov-counter.def.
* gcov-dump.c (tag_counters): Use gcov-counter.def.
* coverage.c: Ditto.
* gcov-tool.c: Offline gcda profile processing tool.
(unlink_gcda_file): Remove one gcda file.
(unlink_profile_dir): Remove gcda files from the profile path.
(gcov_output_files): Output gcda files to an output dir.
(profile_merge): Merge two profiles in directory.
(print_merge_usage_message): Print merge usage.
(merge_usage): Print merge usage and exit.
(do_merge): Driver for profile merge sub-command.
(profile_rewrite): Rewrite profile.
(print_rewrite_usage_message): Print rewrite usage.
(rewrite_usage): Print rewrite usage and exit.
(do_rewrite): Driver for profile rewrite sub-command.
(print_usage): Print gcov-info usage and exit.
(print_version): Print gcov-info version.
(process_args): Process arguments.
(main): Main routine for gcov-tool.
* Makefile.in: Build and install gcov-tool.
* gcov-counter.def: New file split from gcov-io.h.
* doc/gcc.texi: Include gcov-tool.texi.
* doc/gcov-tool.texi: Document for gcov-tool.
2014-07-10 Richard Biener <rguenther@suse.de>
PR tree-optimization/61757
......
......@@ -123,7 +123,8 @@ SUBDIRS =@subdirs@ build
# Selection of languages to be made.
CONFIG_LANGUAGES = @all_selected_languages@
LANGUAGES = c gcov$(exeext) gcov-dump$(exeext) $(CONFIG_LANGUAGES)
LANGUAGES = c gcov$(exeext) gcov-dump$(exeext) gcov-tool$(exeext) \
$(CONFIG_LANGUAGES)
# Default values for variables overridden in Makefile fragments.
# CFLAGS is for the user to override to, e.g., do a cross build with -O2.
......@@ -196,6 +197,9 @@ GCC_WARN_CXXFLAGS = $(LOOSE_WARN) $($(@D)-warn) $(NOCOMMON_FLAG) $($@-warn)
# flex output may yield harmless "no previous prototype" warnings
build/gengtype-lex.o-warn = -Wno-error
gengtype-lex.o-warn = -Wno-error
libgcov-util.o-warn = -Wno-error
libgcov-driver-tool.o-warn = -Wno-error
libgcov-merge-tool.o-warn = -Wno-error
# All warnings have to be shut off in stage1 if the compiler used then
# isn't gcc; configure determines that. WARN_CFLAGS will be either
......@@ -769,6 +773,7 @@ GCC_INSTALL_NAME := $(shell echo gcc|sed '$(program_transform_name)')
GCC_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo gcc|sed '$(program_transform_name)')
CPP_INSTALL_NAME := $(shell echo cpp|sed '$(program_transform_name)')
GCOV_INSTALL_NAME := $(shell echo gcov|sed '$(program_transform_name)')
GCOV_TOOL_INSTALL_NAME := $(shell echo gcov-tool|sed '$(program_transform_name)')
# Setup the testing framework, if you have one
EXPECT = `if [ -f $${rootme}/../expect/expect ] ; then \
......@@ -890,7 +895,7 @@ BASIC_BLOCK_H = basic-block.h $(PREDICT_H) $(VEC_H) $(FUNCTION_H) \
GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h $(VEC_H) \
$(GGC_H) $(BASIC_BLOCK_H) $(TREE_H) tree-ssa-operands.h \
tree-ssa-alias.h $(INTERNAL_FN_H) $(HASH_TABLE_H) is-a.h
GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h
GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h gcov-counter.def
RECOG_H = recog.h
EMIT_RTL_H = emit-rtl.h
FLAGS_H = flags.h flag-types.h $(OPTIONS_H)
......@@ -1492,7 +1497,7 @@ ALL_HOST_FRONTEND_OBJS = $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS))
ALL_HOST_BACKEND_OBJS = $(GCC_OBJS) $(OBJS) $(OBJS-libcommon) \
$(OBJS-libcommon-target) @TREEBROWSER@ main.o c-family/cppspec.o \
$(COLLECT2_OBJS) $(EXTRA_GCC_OBJS) $(GCOV_OBJS) $(GCOV_DUMP_OBJS) \
lto-wrapper.o collect-utils.o
$(GCOV_TOOL_OBJS) lto-wrapper.o collect-utils.o
# This lists all host object files, whether they are included in this
# compilation or not.
......@@ -1517,6 +1522,7 @@ MOSTLYCLEANFILES = insn-flags.h insn-config.h insn-codes.h \
$(SPECS) collect2$(exeext) gcc-ar$(exeext) gcc-nm$(exeext) \
gcc-ranlib$(exeext) \
gcov-iov$(build_exeext) gcov$(exeext) gcov-dump$(exeext) \
gcov-tool$(exeect) \
gengtype$(exeext) *.[0-9][0-9].* *.[si] *-checksum.c libbackend.a \
libcommon-target.a libcommon.a libgcc.mk
......@@ -2576,6 +2582,22 @@ GCOV_DUMP_OBJS = gcov-dump.o
gcov-dump$(exeext): $(GCOV_DUMP_OBJS) $(LIBDEPS)
+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) $(GCOV_DUMP_OBJS) \
$(LIBS) -o $@
GCOV_TOOL_DEP_FILES = $(srcdir)/../libgcc/libgcov-util.c gcov-io.c $(GCOV_IO_H) \
$(srcdir)/../libgcc/libgcov-driver.c $(srcdir)/../libgcc/libgcov-driver-system.c \
$(srcdir)/../libgcc/libgcov-merge.c \
$(SYSTEM_H) coretypes.h $(TM_H) $(CONFIG_H) version.h intl.h $(DIAGNOSTIC_H)
libgcov-util.o: $(srcdir)/../libgcc/libgcov-util.c $(GCOV_TOOL_DEP_FILES)
+$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -o $@ $<
libgcov-driver-tool.o: $(srcdir)/../libgcc/libgcov-driver.c $(GCOV_TOOL_DEP_FILES)
+$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-DIN_GCOV_TOOL=1 -o $@ $<
libgcov-merge-tool.o: $(srcdir)/../libgcc/libgcov-merge.c $(GCOV_TOOL_DEP_FILES)
+$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-DIN_GCOV_TOOL=1 -o $@ $<
GCOV_TOOL_OBJS = gcov-tool.o libgcov-util.o libgcov-driver-tool.o libgcov-merge-tool.o
gcov-tool$(exeext): $(GCOV_TOOL_OBJS) $(LIBDEPS)
+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) $(GCOV_TOOL_OBJS) $(LIBS) -o $@
#
# Build the include directories. The stamp files are stmp-* rather than
# s-* so that mostlyclean does not force the include directory to
......@@ -2804,7 +2826,8 @@ TEXI_GCC_FILES = gcc.texi gcc-common.texi gcc-vers.texi frontends.texi \
contribute.texi compat.texi funding.texi gnu.texi gpl_v3.texi \
fdl.texi contrib.texi cppenv.texi cppopts.texi avr-mmcu.texi \
implement-c.texi implement-cxx.texi arm-neon-intrinsics.texi \
arm-acle-intrinsics.texi aarch64-acle-intrinsics.texi
arm-acle-intrinsics.texi aarch64-acle-intrinsics.texi \
gcov-tool.texi
# we explicitly use $(srcdir)/doc/tm.texi here to avoid confusion with
# the generated tm.texi; the latter might have a more recent timestamp,
......@@ -2925,7 +2948,8 @@ $(build_htmldir)/gccinstall/index.html: $(TEXI_GCCINSTALL_FILES)
DESTDIR=$(@D) \
$(SHELL) $(srcdir)/doc/install.texi2html
MANFILES = doc/gcov.1 doc/cpp.1 doc/gcc.1 doc/gfdl.7 doc/gpl.7 doc/fsf-funding.7
MANFILES = doc/gcov.1 doc/cpp.1 doc/gcc.1 doc/gfdl.7 doc/gpl.7 \
doc/fsf-funding.7 doc/gcov-tool.1
generated-manpages: man
......@@ -3212,6 +3236,13 @@ install-common: native lang.install-common installdirs
rm -f $(DESTDIR)$(bindir)/$(GCOV_INSTALL_NAME)$(exeext); \
$(INSTALL_PROGRAM) gcov$(exeext) $(DESTDIR)$(bindir)/$(GCOV_INSTALL_NAME)$(exeext); \
fi
# Install gcov-tool if it was compiled.
-if [ -f gcov-tool$(exeext) ]; \
then \
rm -f $(DESTDIR)$(bindir)/$(GCOV_TOOL_INSTALL_NAME)$(exeext); \
$(INSTALL_PROGRAM) \
gcov-tool$(exeext) $(DESTDIR)$(bindir)/$(GCOV_TOOL_INSTALL_NAME)$(exeext); \
fi
# Install the driver program as $(target_noncanonical)-gcc,
# $(target_noncanonical)-gcc-$(version), and also as gcc if native.
......@@ -3317,6 +3348,11 @@ $(DESTDIR)$(man1dir)/$(GCOV_INSTALL_NAME)$(man1ext): doc/gcov.1 installdirs
-$(INSTALL_DATA) $< $@
-chmod a-x $@
$(DESTDIR)$(man1dir)/$(GCOV_TOOL_INSTALL_NAME)$(man1ext): doc/gcov-tool.1 installdirs
-rm -f $@
-$(INSTALL_DATA) $< $@
-chmod a-x $@
# Install all the header files built in the include subdirectory.
install-headers: $(INSTALL_HEADERS_DIR)
# Fix symlinks to absolute paths in the installed include directory to
......
......@@ -120,8 +120,19 @@ static unsigned bbg_file_stamp;
static char *da_file_name;
/* The names of merge functions for counters. */
static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
#define STR(str) #str
#define DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) STR(__gcov_merge ## FN_TYPE),
static const char *const ctr_merge_functions[GCOV_COUNTERS] = {
#include "gcov-counter.def"
};
#undef DEF_GCOV_COUNTER
#undef STR
#define DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) NAME,
static const char *const ctr_names[GCOV_COUNTERS] = {
#include "gcov-counter.def"
};
#undef DEF_GCOV_COUNTER
/* Forward declarations. */
static void read_counts_file (void);
......
......@@ -66,6 +66,7 @@ Texts being (a) (see below), and with the Back-Cover Texts being (b)
* gcc: (gcc). The GNU Compiler Collection.
* g++: (gcc). The GNU C++ compiler.
* gcov: (gcc) Gcov. @command{gcov}---a test coverage program.
* gcov-tool: (gcc) Gcov-tool. @command{gcov-tool}---an offline gcda profile processing program.
@end direntry
This file documents the use of the GNU compilers.
@sp 1
......@@ -138,6 +139,7 @@ Introduction, gccint, GNU Compiler Collection (GCC) Internals}.
* Objective-C:: GNU Objective-C runtime features.
* Compatibility:: Binary Compatibility
* Gcov:: @command{gcov}---a test coverage program.
* Gcov-tool:: @command{gcov-tool}---an offline gcda profile processing program.
* Trouble:: If you have trouble using GCC.
* Bugs:: How, why and where to report bugs.
* Service:: How To Get Help with GCC
......@@ -164,6 +166,7 @@ Introduction, gccint, GNU Compiler Collection (GCC) Internals}.
@include objc.texi
@include compat.texi
@include gcov.texi
@include gcov-tool.texi
@include trouble.texi
@include bugreport.texi
@include service.texi
......
@c Copyright (C) 2014 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@ignore
@c man begin COPYRIGHT
Copyright @copyright{} 2014 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with the
Invariant Sections being ``GNU General Public License'' and ``Funding
Free Software'', the Front-Cover texts being (a) (see below), and with
the Back-Cover Texts being (b) (see below). A copy of the license is
included in the gfdl(7) man page.
(a) The FSF's Front-Cover Text is:
A GNU Manual
(b) The FSF's Back-Cover Text is:
You have freedom to copy and modify this GNU Manual, like GNU
software. Copies published by the Free Software Foundation raise
funds for GNU development.
@c man end
@c Set file name and title for the man page.
@setfilename gcov-tool
@settitle offline gcda profile processing tool
@end ignore
@node Gcov-tool
@chapter @command{gcov-tool}---an Offline Gcda Profile Processing Tool
@command{gcov-tool} is a tool you can use in conjunction with GCC to
manipulate or process gcda profile files offline.
@menu
* Gcov-tool Intro:: Introduction to gcov-tool.
* Invoking Gcov-tool:: How to use gcov-tool.
@end menu
@node Gcov-tool Intro
@section Introduction to @command{gcov-tool}
@c man begin DESCRIPTION
@command{gcov-tool} is an offline tool to process gcc's gcda profile files.
Current gcov-tool supports the following functionalities:
@itemize @bullet
@item
merge two sets of profiles with weights.
@item
read one set of profile and rewrite profile contents. One can scale or
normalize the count values.
@end itemize
Examples of the use cases for this tool are:
@itemize @bullet
@item
Collect the profiles for different set of inputs, and use this tool to merge
them. One can specify the weight to factor in the relative importance of
each input.
@item
Rewrite the profile after removing a subset of the gcda files, while maintaining
the consistency of the summary and the histogram.
@item
It can also be used to debug or libgcov code as the tools shares the majority
code as the runtime library.
@end itemize
Note that for the merging operation, this profile generated offline may
contain slight different values from the online merged profile. Here are
a list of typical differences:
@itemize @bullet
@item
histogram difference: This offline tool recomputes the histogram after merging
the counters. The resulting histogram, therefore, is precise. The online
merging does not have this capability -- the histogram is merged from two
histograms and the result is an approximation.
@item
summary checksum difference: Summary checksum uses a CRC32 operation. The value
depends on the link list order of gcov-info objects. This order is different in
gcov-tool from that in the online merge. It's expected to have different
summary checksums. It does not really matter as the compiler does not use this
checksum anywhere.
@item
value profile counter values difference: Some counter values for value profile
are runtime dependent, like heap addresses. It's normal to see some difference
in these kind of counters.
@end itemize
@c man end
@node Invoking Gcov-tool
@section Invoking @command{gcov-tool}
@smallexample
gcov-tool @r{[}@var{global-options}@r{]} SUB_COMMAND
@r{[}@var{sub_command-options}@r{]} @var{profile_dir}
@end smallexample
@command{gcov-tool} accepts the following options:
@ignore
@c man begin SYNOPSIS
gcov-tool [@option{-v}|@option{--version}] [@option{-h}|@option{--help}]
gcov-tool merge [merge-options] @var{directory1} @var{directory2}
[@option{-v}|@option{--verbose}]
[@option{-o}|@option{ --output} @var{directory}]
[@option{-w}|@option{--weight} @var{w1,w2}]
gcov-tool rewrite [rewrite-options] @var{directory}
[@option{-v}|@option{--verbose}]
[@option{-o}|@option{--output} @var{directory}]
[@option{-s}|@option{--scale} @var{float_or_simple-frac_value}]
[@option{-n}|@option{--normalize} @var{long_long_value}]
@c man end
@c man begin SEEALSO
gpl(7), gfdl(7), fsf-funding(7), gcc(1), gcov(1) and the Info entry for
@file{gcc}.
@c man end
@end ignore
@c man begin OPTIONS
@table @gcctabopt
@item -h
@itemx --help
Display help about using @command{gcov-tool} (on the standard output), and
exit without doing any further processing.
@item -v
@itemx --version
Display the @command{gcov-tool} version number (on the standard output),
and exit without doing any further processing.
@item merge
Merge two profile directories.
@table @gcctabopt
@item -v
@itemx --verbose
Set the verbose mode.
@item -o @var{directory}
@itemx --output @var{directory}
Set the output profile directory. Default output directory name is
@var{merged_profile}.
@item -w @var{w1},@var{w2}
@itemx --weight @var{w1},@var{w2}
Set the merge weights of the @var{directory1} and @var{directory2},
respectively. The default weights are 1 for both.
@end table
@item rewrite
Read the specified profile directory and rewrite to a new directory.
@table @gcctabopt
@item -v
@itemx --verbose
Set the verbose mode.
@item -o @var{directory}
@itemx --output @var{directory}
Set the output profile directory. Default output name is @var{rewrite_profile}.
@item -s @var{float_or_simple-frac_value}
@itemx --scale @var{float_or_simple-frac_value}
Scale the profile counters. The specified value can be in floating point value,
or simple fraction value form, such 1, 2, 2/3, and 5/3.
@item -n @var{long_long_value}
@itemx --normalize <long_long_value>
Normalize the profile. The specified value is the max counter value
in the new profile.
@end table
@end table
@c man end
/* Definitions for the gcov counters in the GNU compiler.
Copyright (C) 2001-2014 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* Before including this file, define a macro:
DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE)
This macro will be expanded to all supported gcov counters, their
names, or the type of handler functions. FN_TYPE will be
expanded to a handler function, like in gcov_merge, it is
expanded to __gcov_merge ## FN_TYPE. */
/* Arc transitions. */
DEF_GCOV_COUNTER(GCOV_COUNTER_ARCS, "arcs", _add)
/* Histogram of value inside an interval. */
DEF_GCOV_COUNTER(GCOV_COUNTER_V_INTERVAL, "interval", _add)
/* Histogram of exact power2 logarithm of a value. */
DEF_GCOV_COUNTER(GCOV_COUNTER_V_POW2, "pow2", _add)
/* The most common value of expression. */
DEF_GCOV_COUNTER(GCOV_COUNTER_V_SINGLE, "single", _single)
/* The most common difference between consecutive values of expression. */
DEF_GCOV_COUNTER(GCOV_COUNTER_V_DELTA, "delta", _delta)
/* The most common indirect address. */
DEF_GCOV_COUNTER(GCOV_COUNTER_V_INDIR, "indirect_call", _single)
/* Compute average value passed to the counter. */
DEF_GCOV_COUNTER(GCOV_COUNTER_AVERAGE, "average", _add)
/* IOR of the all values passed to counter. */
DEF_GCOV_COUNTER(GCOV_COUNTER_IOR, "ior", _ior)
/* Time profile collecting first run of a function */
DEF_GCOV_COUNTER(GCOV_TIME_PROFILER, "time_profiler", _time_profile)
......@@ -422,7 +422,11 @@ static void
tag_counters (const char *filename ATTRIBUTE_UNUSED,
unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
{
static const char *const counter_names[] = GCOV_COUNTER_NAMES;
#define DEF_GCOV_COUNTER(COUNTER, NAME, MERGE_FN) NAME,
static const char *const counter_names[] = {
#include "gcov-counter.def"
};
#undef DEF_GCOV_COUNTER
unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
printf (" %s %u counts",
......
......@@ -64,7 +64,11 @@ GCOV_LINKAGE struct gcov_var
} gcov_var;
/* Save the current position in the gcov file. */
static inline gcov_position_t
/* We need to expose this function when compiling for gcov-tool. */
#ifndef IN_GCOV_TOOL
static inline
#endif
gcov_position_t
gcov_position (void)
{
gcov_nonruntime_assert (gcov_var.mode > 0);
......@@ -72,7 +76,11 @@ gcov_position (void)
}
/* Return nonzero if the error flag is set. */
static inline int
/* We need to expose this function when compiling for gcov-tool. */
#ifndef IN_GCOV_TOOL
static inline
#endif
int
gcov_is_error (void)
{
return gcov_var.file ? gcov_var.error : 1;
......@@ -557,11 +565,13 @@ gcov_read_counter (void)
return value;
}
/* We need to expose the below function when compiling for gcov-tool. */
#if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
/* 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. */
#if !IN_LIBGCOV
GCOV_LINKAGE const char *
gcov_read_string (void)
{
......@@ -642,7 +652,9 @@ gcov_read_summary (struct gcov_summary *summary)
}
}
#if !IN_LIBGCOV
/* We need to expose the below function when compiling for gcov-tool. */
#if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
/* Reset to a known position. BASE should have been obtained from
gcov_position, LENGTH should be a record length. */
......
......@@ -247,50 +247,29 @@ typedef uint64_t gcov_type_unsigned;
/* Counters that are collected. */
#define GCOV_COUNTER_ARCS 0 /* Arc transitions. */
#define GCOV_COUNTERS_SUMMABLE 1 /* Counters which can be
summaried. */
#define GCOV_FIRST_VALUE_COUNTER 1 /* The first of counters used for value
profiling. They must form a consecutive
interval and their order must match
the order of HIST_TYPEs in
value-prof.h. */
#define GCOV_COUNTER_V_INTERVAL 1 /* Histogram of value inside an interval. */
#define GCOV_COUNTER_V_POW2 2 /* Histogram of exact power2 logarithm
of a value. */
#define GCOV_COUNTER_V_SINGLE 3 /* The most common value of expression. */
#define GCOV_COUNTER_V_DELTA 4 /* The most common difference between
consecutive values of expression. */
#define GCOV_COUNTER_V_INDIR 5 /* The most common indirect address */
#define GCOV_COUNTER_AVERAGE 6 /* Compute average value passed to the
counter. */
#define GCOV_COUNTER_IOR 7 /* IOR of the all values passed to
counter. */
#define GCOV_TIME_PROFILER 8 /* Time profile collecting first run of a function */
#define GCOV_LAST_VALUE_COUNTER 8 /* The last of counters used for value
profiling. */
#define GCOV_COUNTERS 9
#define DEF_GCOV_COUNTER(COUNTER, NAME, MERGE_FN) COUNTER,
enum {
#include "gcov-counter.def"
GCOV_COUNTERS
};
#undef DEF_GCOV_COUNTER
/* Counters which can be summaried. */
#define GCOV_COUNTERS_SUMMABLE (GCOV_COUNTER_ARCS + 1)
/* The first of counters used for value profiling. They must form a
consecutive interval and their order must match the order of
HIST_TYPEs in value-prof.h. */
#define GCOV_FIRST_VALUE_COUNTER GCOV_COUNTERS_SUMMABLE
/* The last of counters used for value profiling. */
#define GCOV_LAST_VALUE_COUNTER (GCOV_COUNTERS - 1)
/* Number of counters used for value profiling. */
#define GCOV_N_VALUE_COUNTERS \
(GCOV_LAST_VALUE_COUNTER - GCOV_FIRST_VALUE_COUNTER + 1)
/* A list of human readable names of the counters */
#define GCOV_COUNTER_NAMES {"arcs", "interval", "pow2", "single", \
"delta", "indirect_call", "average", "ior", "time_profiler"}
/* Names of merge functions for counters. */
#define GCOV_MERGE_FUNCTIONS {"__gcov_merge_add", \
"__gcov_merge_add", \
"__gcov_merge_add", \
"__gcov_merge_single", \
"__gcov_merge_delta", \
"__gcov_merge_single", \
"__gcov_merge_add", \
"__gcov_merge_ior", \
"__gcov_merge_time_profile" }
/* Convert a counter index to a tag. */
#define GCOV_TAG_FOR_COUNTER(COUNT) \
(GCOV_TAG_COUNTER_BASE + ((gcov_unsigned_t)(COUNT) << 17))
......
This diff is collapsed. Click to expand it.
2014-07-10 Rong Xu <xur@google.com>
Add gcov-tool: an offline gcda profile processing tool
Support.
* libgcov-driver.c (gcov_max_filename): Make available
to gcov-tool.
* libgcov-merge.c (__gcov_merge_add): Replace
gcov_read_counter() with a Macro.
(__gcov_merge_ior): Ditto.
(__gcov_merge_time_profile): Ditto.
(__gcov_merge_single): Ditto.
(__gcov_merge_delta): Ditto.
* libgcov-util.c (void gcov_set_verbose): Set the verbose flag
in the utility functions.
(set_fn_ctrs): Utility function for reading gcda files to in-memory
gcov_list object link lists.
(tag_function): Ditto.
(tag_blocks): Ditto.
(tag_arcs): Ditto.
(tag_lines): Ditto.
(tag_counters): Ditto.
(tag_summary): Ditto.
(read_gcda_finalize): Ditto.
(read_gcda_file): Ditto.
(ftw_read_file): Ditto.
(read_profile_dir_init): Ditto.
(gcov_read_profile_dir): Ditto.
(gcov_read_counter_mem): Ditto.
(gcov_get_merge_weight): Ditto.
(merge_wrapper): A wrapper function that calls merging handler.
(gcov_merge): Merge two gcov_info objects with weights.
(find_match_gcov_info): Find the matched gcov_info in the list.
(gcov_profile_merge): Merge two gcov_info object lists.
(__gcov_add_counter_op): Process edge profile counter values.
(__gcov_ior_counter_op): Process IOR profile counter values.
(__gcov_delta_counter_op): Process delta profile counter values.
(__gcov_single_counter_op): Process single profile counter values.
(fp_scale): Callback function for float-point scaling.
(int_scale): Callback function for integer fraction scaling.
(gcov_profile_scale): Scaling profile counters.
(gcov_profile_normalize): Normalize profile counters.
* libgcov.h: Add headers and functions for gcov-tool use.
(gcov_get_counter): New.
(gcov_get_counter_target): Ditto.
(struct gcov_info): Make the functions field mutable in gcov-tool
compilation.
2014-06-23 Kai Tietz <ktietz@redhat.com>
PR libgcc/61585
......
......@@ -81,7 +81,11 @@ set_gcov_list (struct gcov_info *head)
}
/* Size of the longest file name. */
static size_t gcov_max_filename = 0;
/* We need to expose this static variable when compiling for gcov-tool. */
#ifndef IN_GCOV_TOOL
static
#endif
size_t gcov_max_filename = 0;
/* Flag when the profile has already been dumped via __gcov_dump(). */
static int gcov_dump_complete;
......
......@@ -53,7 +53,7 @@ void
__gcov_merge_add (gcov_type *counters, unsigned n_counters)
{
for (; n_counters; counters++, n_counters--)
*counters += gcov_read_counter ();
*counters += gcov_get_counter ();
}
#endif /* L_gcov_merge_add */
......@@ -65,7 +65,7 @@ void
__gcov_merge_ior (gcov_type *counters, unsigned n_counters)
{
for (; n_counters; counters++, n_counters--)
*counters |= gcov_read_counter ();
*counters |= gcov_get_counter_target ();
}
#endif
......@@ -81,7 +81,7 @@ __gcov_merge_time_profile (gcov_type *counters, unsigned n_counters)
for (i = 0; i < n_counters; i++)
{
value = gcov_read_counter ();
value = gcov_get_counter_target ();
if (value && (!counters[i] || value < counters[i]))
counters[i] = value;
......@@ -109,9 +109,9 @@ __gcov_merge_single (gcov_type *counters, unsigned n_counters)
n_measures = n_counters / 3;
for (i = 0; i < n_measures; i++, counters += 3)
{
value = gcov_read_counter ();
counter = gcov_read_counter ();
all = gcov_read_counter ();
value = gcov_get_counter_target ();
counter = gcov_get_counter ();
all = gcov_get_counter ();
if (counters[0] == value)
counters[1] += counter;
......@@ -148,10 +148,10 @@ __gcov_merge_delta (gcov_type *counters, unsigned n_counters)
n_measures = n_counters / 4;
for (i = 0; i < n_measures; i++, counters += 4)
{
/* last = */ gcov_read_counter ();
value = gcov_read_counter ();
counter = gcov_read_counter ();
all = gcov_read_counter ();
/* last = */ gcov_get_counter ();
value = gcov_get_counter_target ();
counter = gcov_get_counter ();
all = gcov_get_counter ();
if (counters[1] == value)
counters[2] += counter;
......
......@@ -33,6 +33,10 @@
#define xcalloc calloc
#endif
#ifndef IN_GCOV_TOOL
/* About the target. */
/* This path will be used by libgcov runtime. */
#include "tconfig.h"
#include "tsystem.h"
#include "coretypes.h"
......@@ -79,6 +83,43 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI)));
#define GCOV_LOCKED 0
#endif
#else /* IN_GCOV_TOOL */
/* About the host. */
/* This path will be compiled for the host and linked into
gcov-tool binary. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
typedef unsigned gcov_unsigned_t;
typedef unsigned gcov_position_t;
/* gcov_type is typedef'd elsewhere for the compiler */
#if defined (HOST_HAS_F_SETLKW)
#define GCOV_LOCKED 1
#else
#define GCOV_LOCKED 0
#endif
/* Some Macros specific to gcov-tool. */
#define L_gcov 1
#define L_gcov_merge_add 1
#define L_gcov_merge_single 1
#define L_gcov_merge_delta 1
#define L_gcov_merge_ior 1
#define L_gcov_merge_time_profile 1
/* Make certian internal functions/variables in libgcov available for
gcov-tool access. */
#define GCOV_TOOL_LINKAGE
extern gcov_type gcov_read_counter_mem ();
extern unsigned gcov_get_merge_weight ();
#endif /* !IN_GCOV_TOOL */
#if defined(inhibit_libc)
#define IN_LIBGCOV (-1)
#else
......@@ -159,8 +200,13 @@ struct gcov_info
unused) */
unsigned n_functions; /* number of functions */
#ifndef IN_GCOV_TOOL
const struct gcov_fn_info *const *functions; /* pointer to pointers
to function information */
to function information */
#else
const struct gcov_fn_info **functions;
#endif /* !IN_GCOV_TOOL */
};
/* Register a new object file module. */
......@@ -224,6 +270,46 @@ GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN;
GCOV_LINKAGE inline void gcov_rewrite (void);
/* "Counts" stored in gcda files can be a real counter value, or
an target address. When differentiate these two types because
when manipulating counts, we should only change real counter values,
rather target addresses. */
static inline gcov_type
gcov_get_counter (void)
{
#ifndef IN_GCOV_TOOL
/* This version is for reading count values in libgcov runtime:
we read from gcda files. */
return gcov_read_counter ();
#else
/* This version is for gcov-tool. We read the value from memory and
multiply it by the merge weight. */
return gcov_read_counter_mem () * gcov_get_merge_weight ();
#endif
}
/* Similar function as gcov_get_counter(), but handles target address
counters. */
static inline gcov_type
gcov_get_counter_target (void)
{
#ifndef IN_GCOV_TOOL
/* This version is for reading count target values in libgcov runtime:
we read from gcda files. */
return gcov_read_counter ();
#else
/* This version is for gcov-tool. We read the value from memory and we do NOT
multiply it by the merge weight. */
return gcov_read_counter_mem ();
#endif
}
#endif /* !inhibit_libc */
#endif /* GCC_LIBGCOV_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment