Fix V3InstrCount with recursive functions (#8361)

Fixes #8327
This commit is contained in:
Geza Lore
2026-09-15 18:30:16 +01:00
committed by GitHub
parent 0f3a84643b
commit 3343f4d6c8
2 changed files with 22 additions and 4 deletions
+21 -4
View File
@@ -20,6 +20,7 @@
#include "V3InstrCount.h"
#include <iomanip>
#include <unordered_map>
VL_DEFINE_DEBUG_FUNCTIONS;
@@ -43,6 +44,7 @@ class InstrCountVisitor final : public VNVisitorConst {
bool m_ignoreRemaining = false; // Ignore remaining statements in the block
const bool m_assertNoDups; // Check for duplicates
const std::ostream* const m_osp; // Dump file
std::unordered_map<const AstCFunc*, uint32_t> m_funcCosts; // Cost of each function
// TYPES
// Little class to cleanly call startVisitBase/endVisitBase
@@ -255,9 +257,15 @@ private:
if (m_ignoreRemaining) return;
const VisitBase vb{this, nodep};
iterateChildrenConst(nodep);
m_tracingCall = true;
iterateConst(nodep->funcp());
UASSERT_OBJ(!m_tracingCall, nodep, "visit(AstCFunc) should have cleared m_tracingCall.");
const auto it = m_funcCosts.find(nodep->funcp());
if (it == m_funcCosts.end()) {
m_tracingCall = true;
iterateConst(nodep->funcp());
UASSERT_OBJ(!m_tracingCall, nodep,
"visit(AstCFunc) should have cleared m_tracingCall.");
} else {
m_instrCount += it->second; // This guards and adds zero cost on recursive calls
}
}
void visit(AstCFunc* nodep) override {
// Don't count a CFunc other than by tracing a call or counting it
@@ -265,13 +273,22 @@ private:
UASSERT_OBJ(m_tracingCall || nodep == m_startNodep, nodep,
"AstCFunc not under AstCCall, or not start node");
UASSERT_OBJ(!m_ignoreRemaining, nodep, "Should not be ignoring at the start of a CFunc");
const auto emplacePair = m_funcCosts.emplace(nodep, 0);
UASSERT_OBJ(emplacePair.second, nodep, "Should visit every CFunc at most once");
uint32_t& funcCostr = emplacePair.first->second;
m_tracingCall = false;
VL_RESTORER(m_inCFunc);
const uint32_t savedCount = m_instrCount;
reset();
{
VL_RESTORER(m_inCFunc);
m_inCFunc = true;
const VisitBase vb{this, nodep};
iterateChildrenConst(nodep);
}
funcCostr = m_instrCount;
m_instrCount += savedCount;
m_ignoreRemaining = false;
}
void visit(AstNode* nodep) override {
@@ -23,6 +23,7 @@ test.compile(v_flags2=[
"--vpi",
"--CFLAGS -O0",
"-Wall",
"--stats",
"+incdir+t/uvm", #
"t/uvm/uvm_pkg_all_v2020_3_1_dpi.svh",
test.pli_filename