From 72858175a29afe54d005c78eccaacfbbed68fa6f Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Mon, 25 May 2020 21:12:34 +0100 Subject: [PATCH] Only emit VM_PARALLEL_BUILDS=1 iff --output-split caused a split. Previously we set VM_PARALLEL_BUILDS=1 if the --output-split option was provided. Now we only do it iff it actually causes a split. --- src/V3EmitC.cpp | 4 ++ src/V3EmitCSyms.cpp | 3 + src/V3EmitMk.cpp | 2 +- src/V3Global.h | 6 +- test_regress/driver.pl | 9 +++ test_regress/t/t_flag_csplit.pl | 21 +++---- test_regress/t/t_flag_csplit_off.pl | 88 +++++++++++++++++++++++++++++ 7 files changed, 121 insertions(+), 12 deletions(-) create mode 100755 test_regress/t/t_flag_csplit_off.pl diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index b8cf6c46b..95bfea103 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -3234,6 +3234,8 @@ void EmitCImp::emitImp(AstNodeModule* modp) { void EmitCImp::maybeSplit(AstNodeModule* fileModp) { if (splitNeeded()) { + // Splitting file, so using parallel build. + v3Global.useParallelBuild(true); // Close old file VL_DO_CLEAR(delete m_ofp, m_ofp = NULL); // Open a new file @@ -3652,6 +3654,8 @@ class EmitCTrace : EmitCStmts { m_funcp = nodep; if (splitNeeded()) { + // Splitting file, so using parallel build. + v3Global.useParallelBuild(true); // Close old file VL_DO_CLEAR(delete m_ofp, m_ofp = NULL); // Open a new file diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 7baaccfa9..dc069f92b 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -521,6 +521,9 @@ void EmitCSyms::checkSplit(bool usesVfinal) { return; } + // Splitting file, so using parallel build. + v3Global.useParallelBuild(true); + m_numStmts = 0; string filename = v3Global.opt.makeDir() + "/" + symClassName() + "__" + cvtToStr(++m_funcNum) + ".cpp"; diff --git a/src/V3EmitMk.cpp b/src/V3EmitMk.cpp index 19816a465..40887aa93 100644 --- a/src/V3EmitMk.cpp +++ b/src/V3EmitMk.cpp @@ -57,7 +57,7 @@ public: of.puts("\n"); of.puts("# Parallel builds? 0/1 (from --output-split)\n"); of.puts("VM_PARALLEL_BUILDS = "); - of.puts(v3Global.opt.outputSplit() ? "1" : "0"); + of.puts(v3Global.useParallelBuild() ? "1" : "0"); of.puts("\n"); of.puts("# Threaded output mode? 0/1/N threads (from --threads)\n"); of.puts("VM_THREADS = "); diff --git a/src/V3Global.h b/src/V3Global.h index 49ccd2363..bc7fe5454 100644 --- a/src/V3Global.h +++ b/src/V3Global.h @@ -77,6 +77,7 @@ class V3Global { bool m_needHeavy; // Need verilated_heavy.h include bool m_needTraceDumper; // Need __Vm_dumperp in symbols bool m_dpi; // Need __Dpi include files + bool m_useParallelBuild; // Use parallel build for model public: // Options @@ -93,7 +94,8 @@ public: , m_needC11(false) , m_needHeavy(false) , m_needTraceDumper(false) - , m_dpi(false) {} + , m_dpi(false) + , m_useParallelBuild(false) {} AstNetlist* makeNetlist(); void boot() { UASSERT(!m_rootp, "call once"); @@ -129,6 +131,8 @@ public: void needTraceDumper(bool flag) { m_needTraceDumper = flag; } bool dpi() const { return m_dpi; } void dpi(bool flag) { m_dpi = flag; } + void useParallelBuild(bool flag) { m_useParallelBuild = flag; } + bool useParallelBuild() const { return m_useParallelBuild; } }; extern V3Global v3Global; diff --git a/test_regress/driver.pl b/test_regress/driver.pl index b9b220158..570a9ecaa 100755 --- a/test_regress/driver.pl +++ b/test_regress/driver.pl @@ -1416,6 +1416,15 @@ sub have_sc { return 0; } +sub make_version { + my $ver = `make --version`; + if ($ver =~ /make ([0-9]+\.[0-9]+)/i) { + return $1; + } else { + return -1; + } +} + sub have_cmake { return cmake_version() >= version->declare("3.8"); } diff --git a/test_regress/t/t_flag_csplit.pl b/test_regress/t/t_flag_csplit.pl index d6a536347..8ca9c6f43 100755 --- a/test_regress/t/t_flag_csplit.pl +++ b/test_regress/t/t_flag_csplit.pl @@ -32,7 +32,6 @@ while (1) { "-C ".$Self->{obj_dir}, "-f $Self->{VM_PREFIX}.mk", "-j 4", - #"VM_PARALLEL_BUILDS=1", # Check is set by makefile "VM_PREFIX=$Self->{VM_PREFIX}", "TEST_OBJ_DIR=$Self->{obj_dir}", "CPPFLAGS_DRIVER=-D".uc($Self->{name}), @@ -46,7 +45,10 @@ while (1) { check_finished => 1, ); + # Splitting should set VM_PARALLEL_BUILDS to 1 by default + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}_classes.mk", qr/VM_PARALLEL_BUILDS\s*=\s*1/); check_splits(); + check_no_all_file(); check_gcc_flags("$Self->{obj_dir}/vlt_gcc.log"); ok(1); @@ -54,15 +56,6 @@ while (1) { } 1; -sub make_version { - my $ver = `make --version`; - if ($ver =~ /make ([0-9]+\.[0-9]+)/i) { - return $1; - } else { - return -1; - } -} - sub check_splits { my $got1; my $gotSyms1; @@ -78,6 +71,14 @@ sub check_splits { $gotSyms1 or error("No Syms__1 split file found"); } +sub check_no_all_file { + foreach my $file (glob("$Self->{obj_dir}/*.cpp")) { + if ($file =~ qr/__ALL.cpp/) { + error("__ALL.cpp file found: $file"); + } + } +} + sub check_cpp { my $filename = shift; my $size = -s $filename; diff --git a/test_regress/t/t_flag_csplit_off.pl b/test_regress/t/t_flag_csplit_off.pl new file mode 100755 index 000000000..3f1169630 --- /dev/null +++ b/test_regress/t/t_flag_csplit_off.pl @@ -0,0 +1,88 @@ +#!/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_all => 1); + +top_filename("t/t_flag_csplit.v"); + +while (1) { + # Thi rule requires GNU make > 4.1 (or so, known broken in 3.81) + #%__Slow.o: %__Slow.cpp + # $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $< + if (make_version() < 4.1) { + skip("Test requires GNU Make version >= 4.1"); + last; + } + + compile( + v_flags2 => ["--trace --output-split 0 --exe ../$Self->{main_filename}"], + verilator_make_gmake => 0, + ); + + # We don't use the standard test_regress rules, as want to test the rules + # properly build + run(logfile => "$Self->{obj_dir}/vlt_gcc.log", + tee => $self->{verbose}, + cmd=>["make", + "-C ".$Self->{obj_dir}, + "-f $Self->{VM_PREFIX}.mk", + "-j 4", + "VM_PREFIX=$Self->{VM_PREFIX}", + "TEST_OBJ_DIR=$Self->{obj_dir}", + "CPPFLAGS_DRIVER=-D".uc($Self->{name}), + ($opt_verbose ? "CPPFLAGS_DRIVER2=-DTEST_VERBOSE=1":""), + "OPT_FAST=-O2", + "OPT_SLOW=-O0", + ($param{make_flags}||""), + ]); + + execute( + check_finished => 1, + ); + + # Never spliting, so should set VM_PARALLEL_BUILDS to 0 by default + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}_classes.mk", qr/VM_PARALLEL_BUILDS\s*=\s*0/); + check_no_splits(); + check_all_file(); + check_gcc_flags("$Self->{obj_dir}/vlt_gcc.log"); + + ok(1); + last; +} +1; + +sub check_no_splits { + foreach my $file (glob("$Self->{obj_dir}/*.cpp")) { + if ($file =~ qr/__\d/) { + error("Split file found: $file"); + } + } +} + +sub check_all_file { + foreach my $file (glob("$Self->{obj_dir}/*.cpp")) { + if ($file =~ qr/__ALL.cpp/) { + return; + } + } + error("__ALL.cpp file not found"); +} + +sub check_gcc_flags { + my $filename = shift; + my $fh = IO::File->new("<$filename") or error("$! $filenme"); + while (defined (my $line = $fh->getline)) { + chomp $line; + print ":log: $line\n" if $Self->{verbose}; + if ($line =~ /\.cpp/ && $line =~ qr/-O0/) { + error("File built as slow (should be in __ALL.cpp) : $line"); + } + } +}