diff --git a/Changes b/Changes index 56c2573ed..933c642b9 100644 --- a/Changes +++ b/Changes @@ -24,6 +24,7 @@ Verilator 4.205 devel **Minor:** +* Add --prof-c to pass profiling to compiler (#3059). [Alexander Grobman] * Optimize a lot more model variables into function locals (#3027). [Geza Lore] * Support middle-of-design nested topmodules (#3026). [Dan Petrisko] * Remove deprecated --no-relative-cfuncs option (#3024). [Geza Lore] diff --git a/bin/verilator b/bin/verilator index 0e7dddd1b..b8d272440 100755 --- a/bin/verilator +++ b/bin/verilator @@ -367,6 +367,7 @@ detailed descriptions of these arguments. --pipe-filter Filter all input through a script --pp-comments Show preprocessor comments with -E --prefix Name of top level class + --prof-c Compile C++ code with profiling --prof-cfuncs Name functions for profiling --prof-threads Enable generating gantt chart data for threads --protect-key Key for symbol protection diff --git a/bin/verilator_profcfunc b/bin/verilator_profcfunc index e0c5340bf..7ee22f54c 100755 --- a/bin/verilator_profcfunc +++ b/bin/verilator_profcfunc @@ -202,7 +202,7 @@ verilator_profcfunc - Read gprof report created with --prof-cfuncs =head1 SYNOPSIS verilator --prof-cfuncs .... - gcc --ggdb -pg .... + gcc .... {run executable} gprof verilator_profcfuncs gprof.out diff --git a/ci/ci-script.bash b/ci/ci-script.bash index 6ffcda655..0e02a9371 100755 --- a/ci/ci-script.bash +++ b/ci/ci-script.bash @@ -69,6 +69,7 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then if [ "$CI_OS_NAME" = "osx" ]; then export VERILATOR_TEST_NO_GDB=1 # Pain to get GDB to work on OS X + # TODO below may no longer be requried as configure checks for -pg export VERILATOR_TEST_NO_GPROF=1 # Apple Clang has no -pg # export PATH="/Applications/gtkwave.app/Contents/Resources/bin:$PATH" # fst2vcd file bin/verilator_bin @@ -84,6 +85,7 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then "$MAKE" -j "$NPROC" -k elif [ "$CI_OS_NAME" = "freebsd" ]; then export VERILATOR_TEST_NO_GDB=1 # Disable for now, ideally should run + # TODO below may no longer be requried as configure checks for -pg export VERILATOR_TEST_NO_GPROF=1 # gprof is a bit different on FreeBSD, disable fi diff --git a/configure.ac b/configure.ac index aa5be2ee7..903986a47 100644 --- a/configure.ac +++ b/configure.ac @@ -340,6 +340,10 @@ if test "$CFG_ENABLE_COVERAGE" = "yes"; then _MY_CXX_CHECK_OPT(CXX,-DVL_GCOV) fi +# Compiler flags to enable profiling +_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PROFILE,-pg) +AC_SUBST(CFG_CXXFLAGS_PROFILE) + # Flag to select newest language standard supported # Macros work such that first option that passes is the one we take # Currently enabled gnu++14/c++14 due to packaged SystemC dependency diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index 9fc6b68e8..f92024741 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -803,6 +803,13 @@ Summary: prepended to the name of the :vlopt:`--top` option, or V prepended to the first Verilog filename passed on the command line. +.. option:: --prof-c + + When compiling the C++ code, enable the compiler's profiling flag + (e.g. :code:`g++ -pg`). See :ref:`Profiling`. + + Using :vlopt:`--prof-cfuncs` also enables :vlopt:`prof-c`. + .. option:: --prof-cfuncs Modify the created C++ functions to support profiling. The functions @@ -813,6 +820,8 @@ Summary: came from. This allows gprof or oprofile reports to be correlated with the original Verilog source statements. See :ref:`Profiling`. + Using :vlopt:`--prof-cfuncs` also enables :vlopt:`prof-c`. + .. option:: --prof-threads Enable gantt chart data collection for threaded builds. See :ref:`Thread diff --git a/docs/guide/simulating.rst b/docs/guide/simulating.rst index 3033a5c22..19f54f198 100644 --- a/docs/guide/simulating.rst +++ b/docs/guide/simulating.rst @@ -272,8 +272,6 @@ profiled C++ code functions. To use profiling: #. Use Verilator's :vlopt:`--prof-cfuncs`. -#. Use Verilator's :vlopt:`-CFLAGS "-g -pg" <-CFLAGS>` to pass the - profiling flags through to GCC/Clang. #. Build and run the simulation model. #. The model will create gmon.out. #. Run :command:`gprof` to see where in the C++ code the time is spent. diff --git a/include/verilated.mk.in b/include/verilated.mk.in index d11a75745..39e263fa3 100644 --- a/include/verilated.mk.in +++ b/include/verilated.mk.in @@ -19,6 +19,8 @@ PYTHON3 = @PYTHON3@ CFG_WITH_CCWARN = @CFG_WITH_CCWARN@ CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@ +# Compiler flags to enable profiling +CFG_CXXFLAGS_PROFILE = @CFG_CXXFLAGS_PROFILE@ # Select newest language CFG_CXXFLAGS_STD_NEWEST = @CFG_CXXFLAGS_STD_NEWEST@ # Select oldest language (for Verilator internal testing only) @@ -103,6 +105,14 @@ OPT_FAST = -Os # to change this as the library is small, but can have significant speed impact. OPT_GLOBAL = -Os +####################################################################### +##### Profile builds + +ifeq ($(VM_PROFC),1) + CPPFLAGS += $(CFG_CXXFLAGS_PROFILE) + LDFLAGS += $(CFG_CXXFLAGS_PROFILE) +endif + ####################################################################### ##### SystemC builds diff --git a/src/V3EmitMk.cpp b/src/V3EmitMk.cpp index dda111668..23e89fea8 100644 --- a/src/V3EmitMk.cpp +++ b/src/V3EmitMk.cpp @@ -168,6 +168,8 @@ public: } of.puts("\n### Switches...\n"); + of.puts("# C++ code coverage 0/1 (from --prof-c)\n"); + of.puts(string("VM_PROFC = ") + ((v3Global.opt.profC()) ? "1" : "0") + "\n"); of.puts("# SystemC output mode? 0/1 (from --sc)\n"); of.puts(string("VM_SC = ") + ((v3Global.opt.systemC()) ? "1" : "0") + "\n"); of.puts("# Legacy or SystemC output mode? 0/1 (from --sc)\n"); diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 9fb3da414..3710dfd3a 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -1222,8 +1222,10 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char if (m_modPrefix == "") m_modPrefix = m_prefix; }); DECL_OPTION("-private", CbCall, [this]() { m_public = false; }); - DECL_OPTION("-prof-cfuncs", OnOff, &m_profCFuncs); - DECL_OPTION("-profile-cfuncs", OnOff, &m_profCFuncs).undocumented(); // Renamed + DECL_OPTION("-prof-c", OnOff, &m_profC); + DECL_OPTION("-prof-cfuncs", CbCall, [this]() { m_profC = m_profCFuncs = true; }); + DECL_OPTION("-profile-cfuncs", CbCall, + [this]() { m_profC = m_profCFuncs = true; }); // Renamed DECL_OPTION("-prof-threads", OnOff, &m_profThreads); DECL_OPTION("-protect-ids", OnOff, &m_protectIds); DECL_OPTION("-protect-key", Set, &m_protectKey); diff --git a/src/V3Options.h b/src/V3Options.h index f6002f722..b8b2c7082 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -253,6 +253,7 @@ private: bool m_pinsScBigUint = false; // main switch: --pins-sc-biguint bool m_pinsUint8 = false; // main switch: --pins-uint8 bool m_ppComments = false; // main switch: --pp-comments + bool m_profC = false; // main switch: --prof-c bool m_profCFuncs = false; // main switch: --prof-cfuncs bool m_profThreads = false; // main switch: --prof-threads bool m_protectIds = false; // main switch: --protect-ids @@ -462,6 +463,7 @@ public: bool pinsScBigUint() const { return m_pinsScBigUint; } bool pinsUint8() const { return m_pinsUint8; } bool ppComments() const { return m_ppComments; } + bool profC() const { return m_profC; } bool profCFuncs() const { return m_profCFuncs; } bool profThreads() const { return m_profThreads; } bool protectIds() const { return m_protectIds; } diff --git a/test_regress/t/t_prof.pl b/test_regress/t/t_prof.pl index d817c90af..bfa4cb19c 100755 --- a/test_regress/t/t_prof.pl +++ b/test_regress/t/t_prof.pl @@ -10,6 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(vlt_all => 1); +# TODO below might no longer be requried as configure checks for -pg if ($ENV{VERILATOR_TEST_NO_GPROF}) { skip("Skipping due to VERILATOR_TEST_NO_GPROF"); } else { @@ -20,7 +21,7 @@ ok(1); sub dotest { compile( - verilator_flags2 => ["--stats --prof-cfuncs -CFLAGS '-pg' -LDFLAGS '-pg'"], + verilator_flags2 => ["--stats --prof-cfuncs"], ); unlink $_ foreach (glob "$Self->{obj_dir}/gmon.out.*"); diff --git a/test_regress/t/t_profc.pl b/test_regress/t/t_profc.pl new file mode 100755 index 000000000..ec6efa483 --- /dev/null +++ b/test_regress/t/t_profc.pl @@ -0,0 +1,38 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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); + +top_filename("t_prof.v"); + +ok(1); + +sub dotest { + compile( + verilator_flags2 => ["--stats --prof-c"], + ); + + unlink $_ foreach (glob "$Self->{obj_dir}/gmon.out.*"); + setenv('GMON_OUT_PREFIX', "$Self->{obj_dir}/gmon.out"); + + execute( + check_finished => 1, + ); + + my $gmon_path; + $gmon_path = $_ foreach (glob "$Self->{obj_dir}/gmon.out.*"); + $gmon_path or error("Profiler did not create a gmon.out"); + (my $gmon_base = $gmon_path) =~ s!.*[/\\]!!; + + run(cmd => ["cd $Self->{obj_dir} && gprof $Self->{VM_PREFIX} $gmon_base > gprof.out"], + check_finished => 0); +} + +1;