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
: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)
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("-freorder", FOnOff, &m_fReorder);
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("-fsubst", FOnOff, &m_fSubst);
DECL_OPTION("-fsubst-const", FOnOff, &m_fSubstConst);
DECL_OPTION("-ftable", FOnOff, &m_fTable);
DECL_OPTION("-ftaskify-all-forked", FOnOff, &m_fTaskifyAll).undocumented(); // Debug
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("-gate-stmts", Set, &m_gateStmts);
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_fReorder; // main switch: -fno-reorder: reorder assignments in blocks
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_fSubst; // main switch: -fno-subst: substitute expression temp values
bool m_fSubstConst; // main switch: -fno-subst-const: final constant substitution
bool m_fTable; // main switch: -fno-table: lookup table creation
bool m_fTaskifyAll = false; // main switch: --ftaskify-all-forked
bool m_fVarSplit; // main switch: -fno-var-split: automatic variable splitting
int m_fSliceOptLimit = 256; // main switch: --fslice-opt-limit
// clang-format on
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 fReorder() const { return m_fReorder; }
bool fSlice() const { return m_fSlice; }
int fSliceElementLimit() const { return m_fSliceElementLimit; }
bool fSplit() const { return m_fSplit; }
bool fSubst() const { return m_fSubst; }
bool fSubstConst() const { return m_fSubstConst; }
bool fTable() const { return m_fTable; }
bool fTaskifyAll() const { return m_fTaskifyAll; }
bool fVarSplit() const { return m_fVarSplit; }
int fSliceOptLimit() const { return m_fSliceOptLimit; }
std::string traceClassBase() 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
VDouble0 m_statAssigns; // Statistic tracking
VDouble0 m_statSliceLimitSkips; // Statistic tracking
VDouble0 m_statSliceElementSkips; // Statistic tracking
// STATE - for current visit position (use VL_RESTORER)
AstNode* m_assignp = nullptr; // Assignment we are under
@ -251,8 +251,9 @@ class SliceVisitor final : public VNVisitor {
// Skip optimization if array is too large
const int elements = arrayp->rangep()->elementsConst();
if (elements > v3Global.opt.fSliceOptLimit()) {
++m_statSliceLimitSkips;
const int elementLimit = v3Global.opt.fSliceElementLimit();
if (elements > elementLimit && elementLimit > 0) {
++m_statSliceElementSkips;
return false;
}
@ -390,7 +391,7 @@ public:
explicit SliceVisitor(AstNetlist* nodep) { iterate(nodep); }
~SliceVisitor() override {
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.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.passes()
test.passes()

View File

@ -17,4 +17,4 @@ module t (
$write("*-* All Finished *-*\n");
$finish;
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.top_filename = "t/t_opt_slice_limit.v"
test.top_filename = "t/t_opt_slice_element_limit.v"
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.top_filename = "t/t_opt_slice_limit.v"
test.top_filename = "t/t_opt_slice_element_limit.v"
test.compile(verilator_flags2=['--stats'])
test.file_grep(test.stats, r'Optimizations, Slice array skips due to size limit\s+(\d+)', 1)
test.passes()
test.passes()