From 0a0581314972e52aa390b3665fba2105ea13ab3e Mon Sep 17 00:00:00 2001 From: Matthew Ballance Date: Wed, 25 Feb 2026 23:15:08 +0000 Subject: [PATCH] Adopt use of MemberMap Signed-off-by: Matthew Ballance --- src/V3Covergroup.cpp | 49 ++++++++++++++------------------------------ 1 file changed, 15 insertions(+), 34 deletions(-) diff --git a/src/V3Covergroup.cpp b/src/V3Covergroup.cpp index 6aeea2f67..c037efccd 100644 --- a/src/V3Covergroup.cpp +++ b/src/V3Covergroup.cpp @@ -25,6 +25,7 @@ #include "V3PchAstNoMT.h" // VL_MT_DISABLED_CODE_UNIT #include "V3Covergroup.h" +#include "V3MemberMap.h" VL_DEFINE_DEBUG_FUNCTIONS; @@ -63,6 +64,8 @@ class FunctionalCoverageVisitor final : public VNVisitor { // Key is bin pointer, value is state position variable std::map m_seqStateVars; // transition bin -> sequence state variable + VMemberMap m_memberMap; // Member names cached for fast lookup + // METHODS void clearBinInfos() { // Delete pseudo-bins created for cross coverage (they're never inserted into the AST) @@ -1515,25 +1518,15 @@ class FunctionalCoverageVisitor final : public VNVisitor { void generateCoverageComputationCode() { UINFO(4, " Generating coverage computation code" << endl); - // Find get_coverage() and get_inst_coverage() methods - AstFunc* getCoveragep = nullptr; - AstFunc* getInstCoveragep = nullptr; + // Invalidate cache: addMembersp() calls in generateCoverpointCode/generateCrossCode + // have added new members since the last scan, so clear before re-querying. + m_memberMap.clear(); - int memberCount = 0; - for (AstNode* itemp = m_covergroupp->membersp(); itemp; itemp = itemp->nextp()) { - if (++memberCount > 10000) { - m_covergroupp->v3error( - "Too many members or infinite loop in membersp iteration (1)"); - break; - } - if (AstFunc* funcp = VN_CAST(itemp, Func)) { - if (funcp->name() == "get_coverage") { - getCoveragep = funcp; - } else if (funcp->name() == "get_inst_coverage") { - getInstCoveragep = funcp; - } - } - } + // Find get_coverage() and get_inst_coverage() methods + AstFunc* const getCoveragep + = VN_CAST(m_memberMap.findMember(m_covergroupp, "get_coverage"), Func); + AstFunc* const getInstCoveragep + = VN_CAST(m_memberMap.findMember(m_covergroupp, "get_inst_coverage"), Func); if (!getCoveragep || !getInstCoveragep) { UINFO(4, " Warning: Could not find get_coverage methods" << endl); @@ -1839,22 +1832,10 @@ class FunctionalCoverageVisitor final : public VNVisitor { if (hasUnsupportedEvent) return; // Find the sample() method and constructor - int findCount = 0; - for (AstNode* itemp = nodep->membersp(); itemp; itemp = itemp->nextp()) { - if (++findCount > 10000) { - nodep->v3error("Too many members or infinite loop in membersp iteration (3)"); - break; - } - if (AstFunc* const funcp = VN_CAST(itemp, Func)) { - if (funcp->name() == "sample") { - m_sampleFuncp = funcp; - UINFO(9, "Found sample() method" << endl); - } else if (funcp->name() == "new") { - m_constructorp = funcp; - UINFO(9, "Found constructor" << endl); - } - } - } + m_sampleFuncp = VN_CAST(m_memberMap.findMember(nodep, "sample"), Func); + m_constructorp = VN_CAST(m_memberMap.findMember(nodep, "new"), Func); + UINFO(9, "Found sample() method: " << (m_sampleFuncp ? "yes" : "no") << endl); + UINFO(9, "Found constructor: " << (m_constructorp ? "yes" : "no") << endl); iterateChildren(nodep); processCovergroup();