From eb8bbcda058a83b29feeccc7a94f5e5614d96ccc Mon Sep 17 00:00:00 2001 From: Krzysztof Bieganski Date: Fri, 23 Aug 2024 13:57:57 +0200 Subject: [PATCH] Internals: Simplify `CaptureVisitor` in `V3Randomize` (#5397) --- src/V3Randomize.cpp | 84 ++++++++------------------------------------- 1 file changed, 15 insertions(+), 69 deletions(-) diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 4891ef279..de49768b1 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -122,6 +122,7 @@ class RandomizeMarkVisitor final : public VNVisitor { // randomized variable // AstVar::user1() -> bool. Set true to indicate needs rand_mode // AstVar::user2p() -> AstNodeModule*. Pointer to containing module + // AstNodeFTask::user2p() -> AstNodeModule*. Pointer to containing module const VNUser1InUse m_inuser1; const VNUser2InUse m_inuser2; @@ -432,6 +433,10 @@ class RandomizeMarkVisitor final : public VNVisitor { m_modp = nodep; iterateChildrenConst(nodep); } + void visit(AstNodeFTask* nodep) override { + nodep->user2p(m_modp); + iterateChildrenConst(nodep); + } void visit(AstVar* nodep) override { nodep->user2p(m_modp); iterateChildrenConst(nodep); @@ -770,63 +775,6 @@ public: } }; -class ClassLookupHelper final { - std::set m_visibleModules; // Modules directly reachable from our lookup point - std::map - m_classMap; // Memoized mapping between nodes and modules that define them - - // BFS search - template - static void foreachSuperClass(AstClass* classp, Action action) { - std::queue classes; - classes.push(classp); - while (!classes.empty()) { - classp = classes.front(); - classes.pop(); - for (AstClassExtends* extendsp = classp->extendsp(); extendsp; - extendsp = VN_AS(extendsp->nextp(), ClassExtends)) { - AstClass* const superClassp - = VN_AS(extendsp->childDTypep(), ClassRefDType)->classp(); - action(superClassp); - classes.push(superClassp); - } - } - } - - static std::set initVisibleModules(AstClass* classp) { - std::set visibleModules = {classp}; - std::vector symLookupOrder = {classp}; - foreachSuperClass(classp, - [&](AstClass* superclassp) { visibleModules.emplace(superclassp); }); - return visibleModules; - } - -public: - bool moduleInClassHierarchy(AstNodeModule* modp) const { - return m_visibleModules.count(modp) != 0; - } - - AstNodeModule* findDeclaringModule(AstNode* nodep, bool classHierarchyOnly = true) { - auto it = m_classMap.find(nodep); - if (it != m_classMap.end()) return it->second; - for (AstNode* backp = nodep; backp; backp = backp->backp()) { - AstNodeModule* const modp = VN_CAST(backp, NodeModule); - if (modp) { - m_classMap.emplace(nodep, modp); - if (classHierarchyOnly) - UASSERT_OBJ(moduleInClassHierarchy(modp), nodep, - "Node does not belong to class"); - return modp; - } - } - return nullptr; - } - - ClassLookupHelper(AstClass* classp) { - if (classp) m_visibleModules = initVisibleModules(classp); - } -}; - enum class CaptureMode : uint8_t { CAP_NO = 0x0, CAP_VALUE = 0x01, @@ -852,7 +800,6 @@ class CaptureVisitor final : public VNVisitor { AstClass* m_targetp; // Module of inner context (for symbol lookup) std::map m_varCloneMap; // Map original var nodes to their clones std::set m_ignore; // Nodes to ignore for capturing - ClassLookupHelper m_lookup; // Util for class lookup AstVar* m_thisp = nullptr; // Variable for outer context's object, if necessary // METHODS @@ -877,7 +824,7 @@ class CaptureVisitor final : public VNVisitor { template void fixupClassOrPackage(AstNode* memberp, NodeT refp) { - AstNodeModule* const declClassp = m_lookup.findDeclaringModule(memberp, false); + AstNodeModule* const declClassp = VN_AS(memberp->user2p(), NodeModule); if (declClassp != m_targetp) refp->classOrPackagep(declClassp); } @@ -907,20 +854,19 @@ class CaptureVisitor final : public VNVisitor { } CaptureMode getVarRefCaptureMode(AstNodeVarRef* varRefp) { - AstNodeModule* const modp = m_lookup.findDeclaringModule(varRefp->varp(), false); + AstNodeModule* const varModp = VN_AS(varRefp->varp()->user2p(), NodeModule); + AstClass* const varClassp = VN_CAST(varModp, Class); + AstClass* const callerClassp = VN_CAST(m_callerp, Class); - const bool callerIsClass = VN_IS(m_callerp, Class); + const bool callerIsClass = callerClassp; const bool refIsXref = VN_IS(varRefp, VarXRef); const bool varIsFuncLocal = varRefp->varp()->isFuncLocal(); const bool varHasAutomaticLifetime = varRefp->varp()->lifetime().isAutomatic(); - const bool varIsDeclaredInCaller = modp == m_callerp; - const bool varIsFieldOfCaller = modp ? m_lookup.moduleInClassHierarchy(modp) : false; - + const bool varIsFieldOfCaller = AstClass::isClassExtendedFrom(callerClassp, varClassp); if (refIsXref) return CaptureMode::CAP_VALUE | CaptureMode::CAP_F_XREF; if (varIsFuncLocal && varHasAutomaticLifetime) return CaptureMode::CAP_VALUE; // Static var in function (will not be inlined, because it's in class) if (callerIsClass && varIsFuncLocal) return CaptureMode::CAP_VALUE; - if (callerIsClass && varIsDeclaredInCaller) return CaptureMode::CAP_THIS; if (callerIsClass && varIsFieldOfCaller) return CaptureMode::CAP_THIS; UASSERT_OBJ(!callerIsClass, varRefp, "Invalid reference?"); return CaptureMode::CAP_VALUE; @@ -983,7 +929,7 @@ class CaptureVisitor final : public VNVisitor { iterateChildren(nodep); return; } - AstClass* classp = VN_CAST(m_lookup.findDeclaringModule(nodep->taskp(), false), Class); + AstClass* classp = VN_CAST(nodep->taskp()->user2p(), Class); if ((classp == m_callerp) && VN_IS(m_callerp, Class)) { AstNodeExpr* const pinsp = nodep->pinsp(); if (pinsp) pinsp->unlinkFrBack(); @@ -1040,8 +986,7 @@ public: explicit CaptureVisitor(AstNode* const nodep, AstNodeModule* callerp, AstClass* const targetp) : m_argsp(nullptr) , m_callerp(callerp) - , m_targetp(targetp) - , m_lookup(VN_CAST(callerp, Class)) { + , m_targetp(targetp) { iterateAndNextNull(nodep); } @@ -1072,7 +1017,8 @@ class RandomizeVisitor final : public VNVisitor { // NODE STATE // Cleared on Netlist // AstClass::user1() -> bool. Set true to indicate needs randomize processing - // AstVar::user2p() -> AstClass*. Pointer to containing class + // AstVar::user2p() -> AstNodeModule*. Pointer to containing module + // AstNodeFTask::user2p() -> AstNodeModule*. Pointer to containing module // AstEnumDType::user2() -> AstVar*. Pointer to table with enum values // AstConstraint::user2p() -> AstTask*. Pointer to constraint setup procedure // AstClass::user2p() -> AstVar*. Rand mode state variable