diff --git a/src/V3InstrCount.cpp b/src/V3InstrCount.cpp index f65491113..1d0e75ff2 100644 --- a/src/V3InstrCount.cpp +++ b/src/V3InstrCount.cpp @@ -20,6 +20,7 @@ #include "V3InstrCount.h" #include +#include 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 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 { diff --git a/test_regress/t/t_uvm_hello_all_v2020_3_1_dpi.py b/test_regress/t/t_uvm_hello_all_v2020_3_1_dpi.py index 4da9b7de7..8637d786b 100755 --- a/test_regress/t/t_uvm_hello_all_v2020_3_1_dpi.py +++ b/test_regress/t/t_uvm_hello_all_v2020_3_1_dpi.py @@ -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