From 1a6c2fc55d206649d44e7c90f99fdcc4549a3615 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 10 Apr 2020 21:10:21 -0400 Subject: [PATCH] Fix class members getting misoptimized away. --- src/V3Ast.h | 7 ++++--- src/V3AstNodes.cpp | 1 - src/V3AstNodes.h | 5 +---- src/V3Dead.cpp | 1 + src/V3EmitC.cpp | 3 ++- src/V3LinkResolve.cpp | 2 +- src/V3Localize.cpp | 1 + 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/V3Ast.h b/src/V3Ast.h index 254935322..26c3d7d91 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -597,7 +597,8 @@ public: MODULETEMP, STMTTEMP, XTEMP, - IFACEREF // Used to link Interfaces between modules + IFACEREF, // Used to link Interfaces between modules + MEMBER }; enum en m_e; inline AstVarType() : m_e(UNKNOWN) {} @@ -612,7 +613,7 @@ public: "TRIWIRE", "TRI0", "TRI1", "PORT", "BLOCKTEMP", "MODULETEMP", "STMTTEMP", "XTEMP", - "IFACEREF"}; + "IFACEREF", "MEMBER"}; return names[m_e]; } bool isSignal() const { return (m_e==WIRE || m_e==WREAL || m_e==IMPLICITWIRE @@ -632,7 +633,7 @@ public: return (m_e==GPARAM || m_e==LPARAM || m_e==GENVAR || m_e==VAR || m_e==BLOCKTEMP || m_e==MODULETEMP || m_e==STMTTEMP - || m_e==XTEMP || m_e==IFACEREF); + || m_e==XTEMP || m_e==IFACEREF || m_e==MEMBER); } bool isTemp() const { return (m_e==BLOCKTEMP || m_e==MODULETEMP || m_e==STMTTEMP || m_e==XTEMP); diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 0aa52a399..a46a7258d 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -1307,7 +1307,6 @@ void AstVar::dump(std::ostream& str) const { if (attrClockEn()) str<<" [aCLKEN]"; if (attrIsolateAssign()) str<<" [aISO]"; if (attrFileDescr()) str<<" [aFD]"; - if (isClassMember()) str<<" [MEMBER]"; if (isFuncReturn()) str<<" [FUNCRTN]"; else if (isFuncLocal()) str<<" [FUNC]"; if (isDpiOpenArray()) str<<" [DPIOPENA]"; diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 1e7118ad2..2ad684e6b 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -1575,7 +1575,6 @@ private: bool m_usedClock:1; // Signal used as a clock bool m_usedParam:1; // Parameter is referenced (on link; later signals not setup) bool m_usedLoopIdx:1; // Variable subject of for unrolling - bool m_classMember:1; // Member variable for a class bool m_funcLocal:1; // Local variable for a function bool m_funcReturn:1; // Return variable for a function bool m_attrClockEn:1;// User clock enable attribute @@ -1603,7 +1602,6 @@ private: m_usedClock = false; m_usedParam = false; m_usedLoopIdx = false; m_sigPublic = false; m_sigModPublic = false; m_sigUserRdPublic = false; m_sigUserRWPublic = false; - m_classMember = false; m_funcLocal = false; m_funcReturn = false; m_attrClockEn = false; m_attrScBv = false; m_attrIsolateAssign = false; m_attrSFormat = false; m_attrSplitVar = false; @@ -1724,7 +1722,6 @@ public: void isConst(bool flag) { m_isConst = flag; } void isStatic(bool flag) { m_isStatic = flag; } void isIfaceParent(bool flag) { m_isIfaceParent = flag; } - void classMember(bool flag) { m_classMember = flag; } void funcLocal(bool flag) { m_funcLocal = flag; } void funcReturn(bool flag) { m_funcReturn = flag; } void isDpiOpenArray(bool flag) { m_isDpiOpenArray = flag; } @@ -1756,6 +1753,7 @@ public: && (isIO() || isBitLogic()) // Wrapper would otherwise duplicate wrapped module's coverage && !isSc() && !isPrimaryIO() && !isConst()); } + bool isClassMember() const { return varType() == AstVarType::MEMBER; } bool isStatementTemp() const { return (varType()==AstVarType::STMTTEMP); } bool isMovableToBlock() const { return (varType()==AstVarType::BLOCKTEMP || isFuncLocal()); } bool isXTemp() const { return (varType()==AstVarType::XTEMP); } @@ -1779,7 +1777,6 @@ public: bool isTrace() const { return m_trace; } bool isConst() const { return m_isConst; } bool isStatic() const { return m_isStatic; } - bool isClassMember() const { return m_classMember; } bool isFuncLocal() const { return m_funcLocal; } bool isFuncReturn() const { return m_funcReturn; } bool isPullup() const { return m_isPullup; } diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index 6b8e4de49..c90249700 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -328,6 +328,7 @@ private: bool mightElimVar(AstVar* nodep) { return (!nodep->isSigPublic() // Can't elim publics! && !nodep->isIO() + && !nodep->isClassMember() && ((nodep->isTemp() && !nodep->isTrace()) || (nodep->isParam() && !nodep->isTrace() && !v3Global.opt.xmlOnly()) || m_elimUserVars)); // Post-Trace can kill most anything diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 2e98bc6a4..dd59d233b 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -2513,7 +2513,8 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref bool doit = true; switch (which) { case EVL_CLASS_IO: doit = varp->isIO(); break; - case EVL_CLASS_SIG: doit = (varp->isSignal() && !varp->isIO()); break; + case EVL_CLASS_SIG: + doit = ((varp->isSignal() || varp->isClassMember()) && !varp->isIO()); break; case EVL_CLASS_TEMP: doit = (varp->isTemp() && !varp->isIO()); break; case EVL_CLASS_PAR: doit = (varp->isParam() && !VN_IS(varp->valuep(), Const)); break; case EVL_CLASS_ALL: doit = true; break; diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 3f5765881..6bea4587c 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -100,7 +100,7 @@ private: } virtual void visit(AstVar* nodep) VL_OVERRIDE { iterateChildren(nodep); - if (m_classp) nodep->classMember(true); + if (m_classp) nodep->varType(AstVarType::MEMBER); if (m_ftaskp) nodep->funcLocal(true); if (nodep->isSigModPublic()) { nodep->sigModPublic(false); // We're done with this attribute diff --git a/src/V3Localize.cpp b/src/V3Localize.cpp index 870c1f3fa..197a4b2fe 100644 --- a/src/V3Localize.cpp +++ b/src/V3Localize.cpp @@ -129,6 +129,7 @@ private: if ((nodep->isMovableToBlock() // Blocktemp || !flags.m_notStd) // Or used only in block && !flags.m_notOpt // Optimizable + && !nodep->isClassMember() && nodep->user1p()) { // Single cfunc // We don't need to test for tracing; it would be in the tracefunc if it was needed UINFO(4," ModVar->BlkVar "<