First rivision of PR #6638

This commit is contained in:
Jens Yuechao Liu 2025-11-05 03:11:50 +01:00
parent 86a17e5a38
commit 7810c52383
9 changed files with 41 additions and 21 deletions

View File

@ -719,7 +719,7 @@ Summary:
automatically. Variables explicitly annotated with automatically. Variables explicitly annotated with
:option:`/*verilator&32;split_var*/` are still split. :option:`/*verilator&32;split_var*/` are still split.
.. option:: --fslice-opt-limit .. option:: --fslice-element-limit
Rarely needed. Set the maximum array size (number of elements) Rarely needed. Set the maximum array size (number of elements)
for slice optimization to avoid excessive memory usage. for slice optimization to avoid excessive memory usage.

View File

@ -1458,17 +1458,16 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
DECL_OPTION("-freloop", FOnOff, &m_fReloop); DECL_OPTION("-freloop", FOnOff, &m_fReloop);
DECL_OPTION("-freorder", FOnOff, &m_fReorder); DECL_OPTION("-freorder", FOnOff, &m_fReorder);
DECL_OPTION("-fslice", FOnOff, &m_fSlice); DECL_OPTION("-fslice", FOnOff, &m_fSlice);
DECL_OPTION("-fslice-element-limit", CbVal, [this, fl](const char* valp) {
m_fSliceElementLimit = std::atoi(valp);
if (m_fSliceElementLimit < 0) fl->v3fatal("--fslice-element-limit must be >= 0: " << valp);
});
DECL_OPTION("-fsplit", FOnOff, &m_fSplit); DECL_OPTION("-fsplit", FOnOff, &m_fSplit);
DECL_OPTION("-fsubst", FOnOff, &m_fSubst); DECL_OPTION("-fsubst", FOnOff, &m_fSubst);
DECL_OPTION("-fsubst-const", FOnOff, &m_fSubstConst); DECL_OPTION("-fsubst-const", FOnOff, &m_fSubstConst);
DECL_OPTION("-ftable", FOnOff, &m_fTable); DECL_OPTION("-ftable", FOnOff, &m_fTable);
DECL_OPTION("-ftaskify-all-forked", FOnOff, &m_fTaskifyAll).undocumented(); // Debug DECL_OPTION("-ftaskify-all-forked", FOnOff, &m_fTaskifyAll).undocumented(); // Debug
DECL_OPTION("-fvar-split", FOnOff, &m_fVarSplit); DECL_OPTION("-fvar-split", FOnOff, &m_fVarSplit);
DECL_OPTION("-fslice-opt-limit", CbVal, [this, fl](const char* valp) {
m_fSliceOptLimit = std::atoi(valp);
if (m_fSliceOptLimit < 1) fl->v3fatal("--fslice-opt-limit must be >= 1: " << valp);
});
DECL_OPTION("-G", CbPartialMatch, [this](const char* optp) { addParameter(optp, false); }); DECL_OPTION("-G", CbPartialMatch, [this](const char* optp) { addParameter(optp, false); });
DECL_OPTION("-gate-stmts", Set, &m_gateStmts); DECL_OPTION("-gate-stmts", Set, &m_gateStmts);
DECL_OPTION("-gdb", CbCall, []() {}); // Processed only in bin/verilator shell DECL_OPTION("-gdb", CbCall, []() {}); // Processed only in bin/verilator shell

View File

@ -413,13 +413,13 @@ private:
bool m_fReloop; // main switch: -fno-reloop: reform loops bool m_fReloop; // main switch: -fno-reloop: reform loops
bool m_fReorder; // main switch: -fno-reorder: reorder assignments in blocks bool m_fReorder; // main switch: -fno-reorder: reorder assignments in blocks
bool m_fSlice = true; // main switch: -fno-slice: array assignment slicing bool m_fSlice = true; // main switch: -fno-slice: array assignment slicing
int m_fSliceElementLimit = 256; // main switch: --fslice-element-limit
bool m_fSplit; // main switch: -fno-split: always assignment splitting bool m_fSplit; // main switch: -fno-split: always assignment splitting
bool m_fSubst; // main switch: -fno-subst: substitute expression temp values bool m_fSubst; // main switch: -fno-subst: substitute expression temp values
bool m_fSubstConst; // main switch: -fno-subst-const: final constant substitution bool m_fSubstConst; // main switch: -fno-subst-const: final constant substitution
bool m_fTable; // main switch: -fno-table: lookup table creation bool m_fTable; // main switch: -fno-table: lookup table creation
bool m_fTaskifyAll = false; // main switch: --ftaskify-all-forked bool m_fTaskifyAll = false; // main switch: --ftaskify-all-forked
bool m_fVarSplit; // main switch: -fno-var-split: automatic variable splitting bool m_fVarSplit; // main switch: -fno-var-split: automatic variable splitting
int m_fSliceOptLimit = 256; // main switch: --fslice-opt-limit
// clang-format on // clang-format on
bool m_available = false; // Set to true at the end of option parsing bool m_available = false; // Set to true at the end of option parsing
@ -727,13 +727,13 @@ public:
bool fReloop() const { return m_fReloop; } bool fReloop() const { return m_fReloop; }
bool fReorder() const { return m_fReorder; } bool fReorder() const { return m_fReorder; }
bool fSlice() const { return m_fSlice; } bool fSlice() const { return m_fSlice; }
int fSliceElementLimit() const { return m_fSliceElementLimit; }
bool fSplit() const { return m_fSplit; } bool fSplit() const { return m_fSplit; }
bool fSubst() const { return m_fSubst; } bool fSubst() const { return m_fSubst; }
bool fSubstConst() const { return m_fSubstConst; } bool fSubstConst() const { return m_fSubstConst; }
bool fTable() const { return m_fTable; } bool fTable() const { return m_fTable; }
bool fTaskifyAll() const { return m_fTaskifyAll; } bool fTaskifyAll() const { return m_fTaskifyAll; }
bool fVarSplit() const { return m_fVarSplit; } bool fVarSplit() const { return m_fVarSplit; }
int fSliceOptLimit() const { return m_fSliceOptLimit; }
std::string traceClassBase() const VL_MT_SAFE; // Deprecated std::string traceClassBase() const VL_MT_SAFE; // Deprecated
std::string traceClassLang() const VL_MT_SAFE; // Deprecated std::string traceClassLang() const VL_MT_SAFE; // Deprecated

View File

@ -58,7 +58,7 @@ class SliceVisitor final : public VNVisitor {
// STATE - across all visitors // STATE - across all visitors
VDouble0 m_statAssigns; // Statistic tracking VDouble0 m_statAssigns; // Statistic tracking
VDouble0 m_statSliceLimitSkips; // Statistic tracking VDouble0 m_statSliceElementSkips; // Statistic tracking
// STATE - for current visit position (use VL_RESTORER) // STATE - for current visit position (use VL_RESTORER)
AstNode* m_assignp = nullptr; // Assignment we are under AstNode* m_assignp = nullptr; // Assignment we are under
@ -251,8 +251,9 @@ class SliceVisitor final : public VNVisitor {
// Skip optimization if array is too large // Skip optimization if array is too large
const int elements = arrayp->rangep()->elementsConst(); const int elements = arrayp->rangep()->elementsConst();
if (elements > v3Global.opt.fSliceOptLimit()) { const int elementLimit = v3Global.opt.fSliceElementLimit();
++m_statSliceLimitSkips; if (elements > elementLimit && elementLimit > 0) {
++m_statSliceElementSkips;
return false; return false;
} }
@ -390,7 +391,7 @@ public:
explicit SliceVisitor(AstNetlist* nodep) { iterate(nodep); } explicit SliceVisitor(AstNetlist* nodep) { iterate(nodep); }
~SliceVisitor() override { ~SliceVisitor() override {
V3Stats::addStat("Optimizations, Slice array assignments", m_statAssigns); V3Stats::addStat("Optimizations, Slice array assignments", m_statAssigns);
V3Stats::addStat("Optimizations, Slice array skips due to size limit", m_statSliceLimitSkips); V3Stats::addStat("Optimizations, Slice array skips due to size limit", m_statSliceElementSkips);
} }
}; };

View File

@ -11,10 +11,10 @@ import vltest_bootstrap
test.scenarios('simulator') test.scenarios('simulator')
test.top_filename = "t/t_opt_slice_limit.v" test.top_filename = "t/t_opt_slice_element_limit.v"
test.compile(verilator_flags2=['--stats', '--fslice-opt-limit', '10']) test.compile(verilator_flags2=['--stats', '--fslice-element-limit', '10'])
test.file_grep(test.stats, r'Optimizations, Slice array skips due to size limit\s+(\d+)', 4) test.file_grep(test.stats, r'Optimizations, Slice array skips due to size limit\s+(\d+)', 4)
test.passes() test.passes()

View File

@ -17,4 +17,4 @@ module t (
$write("*-* All Finished *-*\n"); $write("*-* All Finished *-*\n");
$finish; $finish;
end end
endmodule endmodule

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2024 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
import vltest_bootstrap
test.scenarios('simulator')
test.top_filename = "t/t_opt_slice_element_limit.v"
test.compile(verilator_flags2=['--stats', '--fslice-element-limit', '0'])
test.file_grep(test.stats, r'Optimizations, Slice array skips due to size limit\s+(\d+)', 0)
test.passes()

View File

@ -11,9 +11,9 @@ import vltest_bootstrap
test.scenarios('simulator') test.scenarios('simulator')
test.top_filename = "t/t_opt_slice_limit.v" test.top_filename = "t/t_opt_slice_element_limit.v"
test.lint(fails=True, test.lint(fails=True,
verilator_flags2=['--stats', '--fslice-opt-limit', '-100']) verilator_flags2=['--stats', '--fslice-element-limit', '-100'])
test.passes() test.passes()

View File

@ -11,10 +11,10 @@ import vltest_bootstrap
test.scenarios('simulator') test.scenarios('simulator')
test.top_filename = "t/t_opt_slice_limit.v" test.top_filename = "t/t_opt_slice_element_limit.v"
test.compile(verilator_flags2=['--stats']) test.compile(verilator_flags2=['--stats'])
test.file_grep(test.stats, r'Optimizations, Slice array skips due to size limit\s+(\d+)', 1) test.file_grep(test.stats, r'Optimizations, Slice array skips due to size limit\s+(\d+)', 1)
test.passes() test.passes()