Add ccache-report target to standard Makefile (#3011)

Using the standard model Makefile, when in addition to an explicit
target, the target 'ccache-report' is also given, a summary of ccache
hits/misses during this invocation of 'make' will be prited at the end
of the build.
This commit is contained in:
Geza Lore 2021-06-07 00:56:30 +01:00 committed by GitHub
parent 31bb73e3de
commit 0edf1f0c94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 213 additions and 11 deletions

View File

@ -131,6 +131,7 @@ DISTFILES1 = $(INFOS) .gitignore \
verilator-config.cmake.in \
verilator-config-version.cmake.in \
bin/verilator \
bin/verilator_ccache_report \
bin/verilator_coverage \
bin/verilator_difftree \
bin/verilator_gantt \
@ -194,6 +195,7 @@ DISTFILES2 = \
INST_PROJ_FILES = \
bin/verilator \
bin/verilator_ccache_report \
bin/verilator_coverage \
bin/verilator_gantt \
bin/verilator_includer \
@ -282,7 +284,7 @@ verilator.pdf: Makefile
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
VL_INST_BIN_FILES = verilator verilator_bin$(EXEEXT) verilator_bin_dbg$(EXEEXT) verilator_coverage_bin_dbg$(EXEEXT) \
verilator_coverage verilator_gantt verilator_includer verilator_profcfunc
verilator_ccache_report verilator_coverage verilator_gantt verilator_includer verilator_profcfunc
# Some scripts go into both the search path and pkgdatadir,
# so they can be found by the user, and under $VERILATOR_ROOT.
@ -311,6 +313,7 @@ installbin:
( cd bin ; $(INSTALL_PROGRAM) verilator_coverage_bin_dbg$(EXEEXT) $(DESTDIR)$(bindir)/verilator_coverage_bin_dbg$(EXEEXT) )
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/bin
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_includer $(DESTDIR)$(pkgdatadir)/bin/verilator_includer )
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_ccache_report $(DESTDIR)$(pkgdatadir)/bin/verilator_ccache_report )
# Man files can either be part of the original kit, or built in current directory
# So important we use $^ so VPATH is searched
@ -477,6 +480,7 @@ clang-format:
$(CLANGFORMAT) $(CLANGFORMAT_FLAGS) $(CLANGFORMAT_FILES)
PY_PROGRAMS = \
bin/verilator_ccache_report \
examples/xml_py/vl_file_copy \
examples/xml_py/vl_hier_graph \
docs/guide/conf.py \

59
bin/verilator_ccache_report Executable file
View File

@ -0,0 +1,59 @@
#!/usr/bin/env python3
# pylint: disable=C0103,C0114,C0115,C0116,C0123,C0301,R0902,R0913,R0914,R0912,R0915,W0621
######################################################################
import argparse
import collections
import re
parser = argparse.ArgumentParser(
allow_abbrev=False,
formatter_class=argparse.RawDescriptionHelpFormatter,
description="""Report ccache behavior of a Verilated model build.""",
epilog=
"""Copyright 2002-2021 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0""")
parser.add_argument('-o', type=argparse.FileType('w'), metavar="OUTFILE",
required=True,
help='output file')
parser.add_argument('logfile', type=argparse.FileType('r'),
help='ccache log file')
args = parser.parse_args()
results = {}
for line in args.logfile:
line = line.strip()
match = re.match(r'.*Object file: (.*)$', line)
if match:
obj = match.group(1)
match = re.match(r'.*Result: (.*)$', line)
if match:
results[obj] = match.group(1)
args.o.write("#" * 80 + "\n")
args.o.write("ccache report (from verilator_ccache_report) :\n")
if not results:
args.o.write("\nAll object files up to date\n")
else:
args.o.write("\nCompiled object files:\n")
width = max(len(_) for _ in results) + 1
for k in sorted(results.keys()):
args.o.write("{:{width}} : {}\n".format(k, results[k], width=width))
args.o.write("\nSummary:\n")
counts = collections.Counter(_ for _ in results.values())
total = sum(counts.values())
width = max(len(_) for _ in results.values()) + 1
for k in sorted(counts.keys()):
c = counts[k]
args.o.write("{:{width}}| {} ({:.2%})\n".format(k, c, c / total, width=width))
args.o.write("#" * 80 + "\n")

View File

@ -387,7 +387,7 @@ How do I get faster build times?
identical source builds, even across different users. If ccache was
installed when Verilator was built it is used, or see OBJCACHE
environment variable to override this. Also see the
:vlopt:`--output-split` option.
:vlopt:`--output-split` option and :ref: `Profiling ccache efficiency`
* To reduce the compile time of classes that use a Verilated module (e.g. a
top CPP file) you may wish to add a

View File

@ -316,6 +316,35 @@ statistics.
For more information see :command:`verilator_gantt`.
.. _Profiling ccache efficiency:
Profiling ccache efficiency
===========================
The Verilator generated Makefile provides support for basic profiling of
ccache behavior during the build. This can be used to track down files that
might be unnecessarily rebuilt, though as of today even small code changes
will usually require rebuilding a large number of files. Improving ccache
efficiency during the edit/compile/test loop is an active area of
development.
To get a basic report of how well ccache is doing, add the `ccache-report`
target when invoking the generated Makefile:
.. code-block:: bash
make -C obj_dir -f Vout.mk Vout ccache-report
This will print a report based on all executions of ccache during this
invocation of Make. The report is also written to a file, in this example
`obj_dir/Vout__cache_report.txt`.
To use the `ccache-report` target, at least one other explicit build target
must be specified, and OBJCACHE must be set to 'ccache'.
This feature is currently experimental and might change in subsequent
releases.
.. _Save/Restore:
Save/Restore

View File

@ -10,6 +10,7 @@
######################################################################
PERL = @PERL@
PYTHON3 = @PYTHON3@
CXX = @CXX@
LINK = @CXX@
AR = ar
@ -35,6 +36,7 @@ CFG_LDLIBS_THREADS = @CFG_LDLIBS_THREADS@
VERILATOR_COVERAGE = $(PERL) $(VERILATOR_ROOT)/bin/verilator_coverage
VERILATOR_INCLUDER = $(PERL) $(VERILATOR_ROOT)/bin/verilator_includer
VERILATOR_CCACHE_REPORT = $(PYTHON3) $(VERILATOR_ROOT)/bin/verilator_ccache_report
######################################################################
# Make checks
@ -254,6 +256,37 @@ endif
#.cpp.o:
# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
######################################################################
### ccache report
ifneq ($(findstring ccache-report,$(MAKECMDGOALS)),)
ifneq ($(OBJCACHE),ccache)
$(error ccache-report requires OBJCACHE to equal 'ccache')
endif
VK_OTHER_GOALS := $(strip $(subst ccache-report,,$(MAKECMDGOALS)))
ifeq ($(VK_OTHER_GOALS),)
$(error ccache-report must be used with at least one other explicit target)
endif
# Report ccache behaviour for this invocation of make
export CCACHE_LOGFILE := $(VM_PREFIX).ccache-log
VK_CCACHE_REPORT := $(VM_PREFIX)__ccache_report.txt
# Truncate logfile
$(shell echo "" > $(CCACHE_LOGFILE))
# Remove previous report
$(shell rm -f $(VK_CCACHE_REPORT))
$(VK_CCACHE_REPORT): $(VK_OBJS)
$(VERILATOR_CCACHE_REPORT) -o $@ $(CCACHE_LOGFILE)
.PHONY: ccache-report
ccache-report: $(VK_CCACHE_REPORT)
@cat $<
# ccache-report runs last
ccache-report: $(VK_OTHER_GOALS)
endif
######################################################################
### Debugging

View File

@ -2304,6 +2304,10 @@ sub cfg_with_threaded {
return 1; # C++11 now always required
}
sub cfg_with_ccache {
return `grep "OBJCACHE \?= ccache" "$ENV{VERILATOR_ROOT}/include/verilated.mk"` ne "";
}
sub tries {
# Number of retries when reading logfiles, generally only need many
# retries when system is busy running a lot of tests

View File

@ -0,0 +1,49 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2021 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(vlt => 1);
if (!$Self->cfg_with_ccache) {
skip("Requires configuring with ccache");
}
top_filename("t_a1_first_cc.v");
# This test requires rebuilding the object files to check the ccache log
foreach my $filename (glob ("$Self->{obj_dir}/*.o")) {
print "rm $filename\n" if $Self->{verbose};
unlink $filename;
}
compile(
verilator_flags2 => ['--trace'],
make_flags => "ccache-report"
);
my $report = "$Self->{obj_dir}/$Self->{VM_PREFIX}__ccache_report.txt";
# We do not actually want to make this test depend on whether the file was
# cached or not, so trim the report to ignore actual caching behaviour
run(cmd => ["sed", "-i", "-e", "'s/ : .*/ : IGNORED/; /^Summary/,\$d;'", $report]);
files_identical($report, "t/$Self->{name}__ccache_report_initial.out");
# Now rebuild again (should be all up to date)
run(
logfile => "$Self->{obj_dir}/rebuild.log",
cmd => ["make", "-C", $Self->{obj_dir},
"-f", "$Self->{VM_PREFIX}.mk",
$Self->{VM_PREFIX}, "ccache-report"]
);
files_identical($report, "t/$Self->{name}__ccache_report_rebuild.out");
ok(1);
1;

View File

@ -0,0 +1,9 @@
################################################################################
ccache report (from verilator_ccache_report) :
Compiled object files:
Vt_ccache_report__ALL.o : IGNORED
Vt_ccache_report__main.o : IGNORED
verilated.o : IGNORED
verilated_vcd_c.o : IGNORED

View File

@ -0,0 +1,5 @@
################################################################################
ccache report (from verilator_ccache_report) :
All object files up to date
################################################################################

View File

@ -10,23 +10,33 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(dist => 1);
# See also t_flag_version.pl
sub check {
my $interpreter = shift;
my $prog = shift;
run(fails => 0,
cmd => [$interpreter, $prog, "--help"],
logfile => "$Self->{obj_dir}/t_help.log",
tee => 0,
verilator_run => 1,
);
file_grep("$Self->{obj_dir}/t_help.log", qr/DISTRIBUTION/i);
}
foreach my $prog (
# See also t_flag_version.pl
"../bin/verilator",
"../bin/verilator_coverage",
"../bin/verilator_difftree",
"../bin/verilator_gantt",
"../bin/verilator_profcfunc",
) {
run(fails => 0,
cmd => ["perl", $prog,
"--help"],
logfile => "$Self->{obj_dir}/t_help.log",
tee => 0,
verilator_run => 1,
);
file_grep("$Self->{obj_dir}/t_help.log", qr/DISTRIBUTION/i);
check("perl", $prog);
}
check("python3", "../bin/verilator_ccache_report");
ok(1);
1;