diff --git a/src/V3ActiveTop.cpp b/src/V3ActiveTop.cpp index 35996c5c3..c38da6405 100644 --- a/src/V3ActiveTop.cpp +++ b/src/V3ActiveTop.cpp @@ -48,6 +48,8 @@ private: // NODE STATE // Entire netlist // AstNode::user() bool. True if processed + AstUserInUse m_inuse1; + // STATE AstTopScope* m_topscopep; // Top scope for adding sentrees under SenTreeFinder m_finder; // Find global sentree's and add them @@ -135,7 +137,6 @@ public: // CONSTUCTORS ActiveTopVisitor(AstNetlist* nodep) { m_topscopep = NULL; - AstNode::userClearTree(); nodep->accept(*this); } virtual ~ActiveTopVisitor() {} diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index 860afa4fa..3f59cd52a 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -40,6 +40,7 @@ private: // NODE STATE/TYPES // Cleared on netlist // AstNode::user() -> bool. True if processed + AstUserInUse m_inuse1; // STATE AstModule* m_modp; // Last module @@ -288,7 +289,6 @@ public: m_beginp = NULL; m_modp = NULL; // Process - AstNode::userClearTree(); // userp() used on entire tree nodep->accept(*this); } virtual ~AssertVisitor() { diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 79c1c4206..159ec6ab3 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -39,11 +39,17 @@ vluint64_t AstNode::s_editCntLast=0; // along with each userp, and thus by bumping this count we can make it look // as if we iterated across the entire tree to set all the userp's to null. int AstNode::s_cloneCntGbl=0; -int AstNode::s_userCntGbl=0; -int AstNode::s_user2CntGbl=0; -int AstNode::s_user3CntGbl=0; -int AstNode::s_user4CntGbl=0; -int AstNode::s_user5CntGbl=0; +int AstUserInUse::s_userCntGbl=0; // Hot cache line, leave adjacent +int AstUser2InUse::s_userCntGbl=0; // Hot cache line, leave adjacent +int AstUser3InUse::s_userCntGbl=0; // Hot cache line, leave adjacent +int AstUser4InUse::s_userCntGbl=0; // Hot cache line, leave adjacent +int AstUser5InUse::s_userCntGbl=0; // Hot cache line, leave adjacent + +bool AstUserInUse::s_userBusy=false; +bool AstUser2InUse::s_userBusy=false; +bool AstUser3InUse::s_userBusy=false; +bool AstUser4InUse::s_userBusy=false; +bool AstUser5InUse::s_userBusy=false; //###################################################################### // V3AstType diff --git a/src/V3Ast.h b/src/V3Ast.h index 7299ea8ef..e4533aa00 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -362,6 +362,93 @@ struct AstNUser { } }; +//###################################################################### +// AstUserResource - Generic pointer base class for tracking usage of user() +// +// Where AstNode->user2() is going to be used, for example, you write: +// +// AstUser2InUse m_userres; +// +// This will clear the tree, and prevent another visitor from clobering +// user2. When the member goes out of scope it will be automagically +// freed up. + +class AstUserInUseBase { +protected: + static void allocate(int& cntGblRef, bool& userBusyRef) { + // Perhaps there's still a AstUserInUse in scope for this? + UASSERT_STATIC(!userBusyRef, "Conflicting user use; AstUser*InUse request when under another AstUserInUse"); + userBusyRef = true; + clearcnt(cntGblRef, userBusyRef); + } + static void free(int& cntGblRef, bool& userBusyRef) { + UASSERT_STATIC(userBusyRef, "Free of User*() not under AstUserInUse"); + clearcnt(cntGblRef, userBusyRef); // Includes a checkUse for us + userBusyRef = false; + } + static void clearcnt(int& cntGblRef, bool& userBusyRef) { + UASSERT_STATIC(userBusyRef, "Clear of User*() not under AstUserInUse"); + // If this really fires and is real (after 2^32 edits???) + // we could just walk the tree and clear manually + ++cntGblRef; + UASSERT_STATIC(cntGblRef, "User*() overflowed!"); + } +}; + +// For each user() declare the in use structure +// We let AstNode peek into here, because when under low optimization even +// an accessor would be way too slow. +class AstUserInUse : AstUserInUseBase { +protected: + friend class AstNode; + static int s_userCntGbl; // Count of which usage of userp() this is + static bool s_userBusy; // Count is in use +public: + AstUserInUse() { allocate(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + ~AstUserInUse() { free (s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + static void clear() { clearcnt(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } +}; +class AstUser2InUse : AstUserInUseBase { +protected: + friend class AstNode; + static int s_userCntGbl; // Count of which usage of userp() this is + static bool s_userBusy; // Count is in use +public: + AstUser2InUse() { allocate(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + ~AstUser2InUse() { free (s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + static void clear() { clearcnt(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } +}; +class AstUser3InUse : AstUserInUseBase { +protected: + friend class AstNode; + static int s_userCntGbl; // Count of which usage of userp() this is + static bool s_userBusy; // Count is in use +public: + AstUser3InUse() { allocate(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + ~AstUser3InUse() { free (s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + static void clear() { clearcnt(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } +}; +class AstUser4InUse : AstUserInUseBase { +protected: + friend class AstNode; + static int s_userCntGbl; // Count of which usage of userp() this is + static bool s_userBusy; // Count is in use +public: + AstUser4InUse() { allocate(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + ~AstUser4InUse() { free (s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + static void clear() { clearcnt(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } +}; +class AstUser5InUse : AstUserInUseBase { +protected: + friend class AstNode; + static int s_userCntGbl; // Count of which usage of userp() this is + static bool s_userBusy; // Count is in use +public: + AstUser5InUse() { allocate(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + ~AstUser5InUse() { free (s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + static void clear() { clearcnt(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } +}; + //###################################################################### // AstNVisitor -- Allows new functions to be called on each node // type without changing the base classes. See "Modern C++ Design". @@ -480,19 +567,14 @@ private: int m_widthMin; // If unsized, bitwidth of minimum implementation AstNUser* m_userp; // Pointer to any information the user iteration routine wants int m_userCnt; // Mark of when userp was set - static int s_userCntGbl; // Count of which userp is set AstNUser* m_user2p; // Pointer to any information the user iteration routine wants int m_user2Cnt; // Mark of when userp was set - static int s_user2CntGbl; // Count of which userp is set AstNUser* m_user3p; // Pointer to any information the user iteration routine wants int m_user3Cnt; // Mark of when userp was set - static int s_user3CntGbl; // Count of which userp is set AstNUser* m_user4p; // Pointer to any information the user iteration routine wants int m_user4Cnt; // Mark of when userp was set - static int s_user4CntGbl; // Count of which userp is set AstNUser* m_user5p; // Pointer to any information the user iteration routine wants int m_user5Cnt; // Mark of when userp was set - static int s_user5CntGbl; // Count of which userp is set // METHODS void op1p(AstNode* nodep) { m_op1p = nodep; if (nodep) nodep->m_backp = this; } @@ -600,31 +682,47 @@ public: bool isQuad() const { return (width()>VL_WORDSIZE && width()<=VL_QUADSIZE); } bool isWide() const { return (width()>VL_QUADSIZE); } + AstNUser* userp() const { + // Slows things down measurably, so disabled by default + //UASSERT_STATIC(AstUserInUse::s_userBusy, "userp set w/o busy"); + return ((m_userCnt==AstUserInUse::s_userCntGbl)?m_userp:NULL); + } + void userp(void* userp) { m_userp=(AstNUser*)(userp); m_userCnt=AstUserInUse::s_userCntGbl; } int user() const { return userp()->castInt(); } - AstNUser* userp() const { return ((m_userCnt==s_userCntGbl)?m_userp:NULL); } - void userp(void* userp) { m_userp=(AstNUser*)(userp); m_userCnt=s_userCntGbl; } void user(int val) { userp(AstNUser::fromInt(val)); } - static void userClearTree() { s_userCntGbl++; UASSERT_STATIC(s_userCntGbl,"Rollover"); } // Clear userp()'s across the entire tree + static void userClearTree() { AstUserInUse::clear(); } // Clear userp()'s across the entire tree + + AstNUser* user2p() const { + //UASSERT_STATIC(AstUser2InUse::s_userBusy, "user2p set w/o busy"); + return ((m_user2Cnt==AstUser2InUse::s_userCntGbl)?m_user2p:NULL); } + void user2p(void* userp) { m_user2p=(AstNUser*)(userp); m_user2Cnt=AstUser2InUse::s_userCntGbl; } int user2() const { return user2p()->castInt(); } - AstNUser* user2p() const { return ((m_user2Cnt==s_user2CntGbl)?m_user2p:NULL); } - void user2p(void* userp) { m_user2p=(AstNUser*)(userp); m_user2Cnt=s_user2CntGbl; } void user2(int val) { user2p(AstNUser::fromInt(val)); } - static void user2ClearTree() { s_user2CntGbl++; } // Clear userp()'s across the entire tree + static void user2ClearTree() { AstUser2InUse::clear(); } + + AstNUser* user3p() const { + //UASSERT_STATIC(AstUser3InUse::s_userBusy, "user3p set w/o busy"); + return ((m_user3Cnt==AstUser3InUse::s_userCntGbl)?m_user3p:NULL); } + void user3p(void* userp) { m_user3p=(AstNUser*)(userp); m_user3Cnt=AstUser3InUse::s_userCntGbl; } int user3() const { return user3p()->castInt(); } - AstNUser* user3p() const { return ((m_user3Cnt==s_user3CntGbl)?m_user3p:NULL); } - void user3p(void* userp) { m_user3p=(AstNUser*)(userp); m_user3Cnt=s_user3CntGbl; } void user3(int val) { user3p(AstNUser::fromInt(val)); } - static void user3ClearTree() { s_user3CntGbl++; } // Clear userp()'s across the entire tree + static void user3ClearTree() { AstUser3InUse::clear(); } + + AstNUser* user4p() const { + //UASSERT_STATIC(AstUser4InUse::s_userBusy, "user4p set w/o busy"); + return ((m_user4Cnt==AstUser4InUse::s_userCntGbl)?m_user4p:NULL); } + void user4p(void* userp) { m_user4p=(AstNUser*)(userp); m_user4Cnt=AstUser4InUse::s_userCntGbl; } int user4() const { return user4p()->castInt(); } - AstNUser* user4p() const { return ((m_user4Cnt==s_user4CntGbl)?m_user4p:NULL); } - void user4p(void* userp) { m_user4p=(AstNUser*)(userp); m_user4Cnt=s_user4CntGbl; } void user4(int val) { user4p(AstNUser::fromInt(val)); } - static void user4ClearTree() { s_user4CntGbl++; } // Clear userp()'s across the entire tree + static void user4ClearTree() { AstUser4InUse::clear(); } + + AstNUser* user5p() const { + //UASSERT_STATIC(AstUser5InUse::s_userBusy, "user5p set w/o busy"); + return ((m_user5Cnt==AstUser5InUse::s_userCntGbl)?m_user5p:NULL); } + void user5p(void* userp) { m_user5p=(AstNUser*)(userp); m_user5Cnt=AstUser5InUse::s_userCntGbl; } int user5() const { return user5p()->castInt(); } - AstNUser* user5p() const { return ((m_user5Cnt==s_user5CntGbl)?m_user5p:NULL); } - void user5p(void* userp) { m_user5p=(AstNUser*)(userp); m_user5Cnt=s_user5CntGbl; } void user5(int val) { user5p(AstNUser::fromInt(val)); } - static void user5ClearTree() { s_user5CntGbl++; } // Clear userp()'s across the entire tree + static void user5ClearTree() { AstUser5InUse::clear(); } vluint64_t editCount() const { return m_editCount; } void editCountInc() { m_editCount = s_editCntGbl++; } diff --git a/src/V3Case.cpp b/src/V3Case.cpp index e8b9c2413..60895386f 100644 --- a/src/V3Case.cpp +++ b/src/V3Case.cpp @@ -118,6 +118,7 @@ private: // NODE STATE // Cleared each Case // AstIf::user3() -> bool. Set true to indicate clone not needed + AstUser3InUse m_inuse3; // STATE V3Double0 m_statCaseFast; // Statistic tracking diff --git a/src/V3Cast.cpp b/src/V3Cast.cpp index 5c1c2d243..3e21a0041 100644 --- a/src/V3Cast.cpp +++ b/src/V3Cast.cpp @@ -60,6 +60,7 @@ private: // NODE STATE // Entire netlist: // AstNode::user() // bool. Indicates node is of known size + AstUserInUse m_inuse1; // STATE //int debug() { return 9; } @@ -171,7 +172,6 @@ private: public: // CONSTUCTORS CastVisitor(AstNetlist* nodep) { - AstNode::userClearTree(); nodep->accept(*this); } virtual ~CastVisitor() {} diff --git a/src/V3Changed.cpp b/src/V3Changed.cpp index 1fa5b1fb6..3a111a8c0 100644 --- a/src/V3Changed.cpp +++ b/src/V3Changed.cpp @@ -51,6 +51,8 @@ private: // NODE STATE // Entire netlist: // AstVarScope::user() -> bool. True indicates processed + AstUserInUse m_inuse1; + // STATE AstModule* m_topModp; // Top module AstScope* m_scopetopp; // Scope under TOPSCOPE diff --git a/src/V3Clean.cpp b/src/V3Clean.cpp index 8d5fbcf50..9e55b073d 100644 --- a/src/V3Clean.cpp +++ b/src/V3Clean.cpp @@ -47,6 +47,8 @@ private: // Entire netlist: // AstNode::user() -> CleanState. For this node, 0==UNKNOWN // AstNode::user2() -> bool. True indicates minWidth has been propagated + AstUserInUse m_inuse1; + AstUser2InUse m_inuse2; // STATE AstModule* m_modp; @@ -257,8 +259,6 @@ public: CleanVisitor() {} virtual ~CleanVisitor() {} void main(AstNetlist* nodep) { - AstNode::userClearTree(); // userp() used on entire tree - AstNode::user2ClearTree(); // userp() used on entire tree nodep->accept(*this); } }; diff --git a/src/V3Clock.cpp b/src/V3Clock.cpp index a568bc535..0e93a74de 100644 --- a/src/V3Clock.cpp +++ b/src/V3Clock.cpp @@ -52,6 +52,8 @@ private: // Cleared each Module: // AstVarScope::userp() -> AstVarScope*. Temporary signal that was created. // AstVarScope::user2p() -> AstVarScope*. Temporary signal for change detects + AstUserInUse m_inuse1; + AstUser2InUse m_inuse2; // TYPES enum { DOUBLE_OR_RATE = 10 }; // How many | per ||, Determined experimentally as best diff --git a/src/V3Combine.cpp b/src/V3Combine.cpp index c2ea0d10e..37e94f64a 100644 --- a/src/V3Combine.cpp +++ b/src/V3Combine.cpp @@ -174,6 +174,9 @@ private: // AstCFunc::user3p() -> AstCFunc*, If set, replace ccalls to this func with new func // AstNodeStmt::user3() -> AstNode*. True if to ignore this cell // AstNodeStmt::user4() -> V3Hashed::V3Hash. Hash value of this node (hash of 0 is illegal) + AstUserInUse m_inuse1; + AstUser3InUse m_inuse3; + //AstUser4InUse part of V3Hashed // STATE typedef enum {STATE_IDLE, STATE_HASH, STATE_DUP} CombineState; diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 29edbb469..e059678ee 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -671,6 +671,7 @@ private: else if (!m_cpp && nodep->lhsp()->castConcat()) { bool need_temp = false; if (m_warn && !nodep->castAssignDly()) { // Is same var on LHS and RHS? + AstUserInUse m_inuse1; ConstVarMarkVisitor mark(nodep->lhsp()); ConstVarFindVisitor find(nodep->rhsp()); if (find.found()) need_temp = true; diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index 81f16ab63..d01d928eb 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -70,6 +70,7 @@ private: // AstModule::user() -> int. Count of number of cells referencing this module. // AstVar::user() -> int. Count of number of references // AstVarScope::user() -> int. Count of number of references + AstUserInUse m_inuse1; // TYPES typedef multimap AssignMap; @@ -188,7 +189,6 @@ public: m_elimUserVars = elimUserVars; m_sideEffect = false; // Operate on whole netlist - AstNode::userClearTree(); // userp() used on entire tree nodep->accept(*this); deadCheckVar(); // Modules after vars, because might be vars we delete inside a mod we delete diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 6156b9705..bb0d35da7 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -83,6 +83,11 @@ private: // Cleared each scope: // AstAssignDly::user5() -> AstVarScope*. __Vdlyvset__ created for this assign // AstAlwaysPost::user5() -> AstVarScope*. __Vdlyvset__ last referenced in IF + AstUserInUse m_inuse1; + AstUser2InUse m_inuse2; + AstUser3InUse m_inuse3; + AstUser4InUse m_inuse4; + AstUser5InUse m_inuse5; enum VarUsage { VU_NONE=0, VU_DLY=1, VU_NONDLY=2 }; @@ -297,10 +302,6 @@ private: virtual void visit(AstNetlist* nodep, AstNUser*) { //VV***** We reset all userp() on the netlist m_modVarMap.clear(); - AstNode::userClearTree(); - AstNode::user2ClearTree(); - AstNode::user3ClearTree(); - AstNode::user4ClearTree(); nodep->iterateChildren(*this); } virtual void visit(AstScope* nodep, AstNUser*) { diff --git a/src/V3Depth.cpp b/src/V3Depth.cpp index ff16e96ab..edaa9e327 100644 --- a/src/V3Depth.cpp +++ b/src/V3Depth.cpp @@ -163,7 +163,6 @@ public: m_depth=0; m_maxdepth=0; // - AstNode::userClearTree(); // userp() used on entire tree nodep->accept(*this); } virtual ~DepthVisitor() {} diff --git a/src/V3Descope.cpp b/src/V3Descope.cpp index 44200097a..02fca7f41 100644 --- a/src/V3Descope.cpp +++ b/src/V3Descope.cpp @@ -45,6 +45,7 @@ private: // NODE STATE // Cleared entire netlist // AstCFunc::user() // bool. Indicates processing completed + AstUserInUse m_inuse1; // TYPES typedef multimap FuncMmap; @@ -245,7 +246,6 @@ public: m_modp = NULL; m_scopep = NULL; m_needThis = false; - AstNode::userClearTree(); nodep->accept(*this); } virtual ~DescopeVisitor() {} diff --git a/src/V3Expand.cpp b/src/V3Expand.cpp index 85fa041bc..1b2c0b633 100644 --- a/src/V3Expand.cpp +++ b/src/V3Expand.cpp @@ -905,7 +905,6 @@ public: } virtual ~ExpandVisitor() {} void main(AstNode* nodep) { - AstNode::userClearTree(); // userp() used on entire tree nodep->accept(*this); } }; diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp index 768e7f646..f2f37116b 100644 --- a/src/V3Gate.cpp +++ b/src/V3Gate.cpp @@ -231,6 +231,7 @@ private: //Entire netlist: // AstVarScope::userp -> GateVarVertex* for usage var, 0=not set yet // {statement}Node::userp -> GateLogicVertex* for this statement + AstUserInUse m_inuse1; // STATE V3Graph m_graph; // Scoreboard of var usages/dependencies @@ -294,7 +295,6 @@ private: // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { //VV***** We reset userp() and user2p - AstNode::userClearTree(); nodep->iterateChildren(*this); //if (debug()>6) m_graph.dump(); if (debug()>6) m_graph.dumpDotFilePrefixed("gate_pre"); diff --git a/src/V3GenClk.cpp b/src/V3GenClk.cpp index 677a21597..177b9a45c 100644 --- a/src/V3GenClk.cpp +++ b/src/V3GenClk.cpp @@ -50,6 +50,8 @@ private: // Cleared on top scope // AstVarScope::user2() -> AstVarScope*. Signal replacing activation with // AstVarRef::user3() -> bool. Signal is replaced activation (already done) + AstUser2InUse m_inuse2; + AstUser3InUse m_inuse3; // STATE AstActive* m_activep; // Inside activate statement @@ -140,6 +142,7 @@ private: // NODE STATE // Cleared on top scope // AstVarScope::user() -> bool. Set when the var has been used as clock + AstUserInUse m_inuse1; // STATE AstActive* m_activep; // Inside activate statement diff --git a/src/V3Hashed.cpp b/src/V3Hashed.cpp index 9c174b380..e533909f7 100644 --- a/src/V3Hashed.cpp +++ b/src/V3Hashed.cpp @@ -47,6 +47,7 @@ private: // NODE STATE // Entire netlist: // AstNodeStmt::user4() -> V3Hash. Hash value of this node (hash of 0 is illegal) + //AstUser4InUse in V3Hashed.h // STATE V3Hash m_lowerHash; // Hash of the statement we're building diff --git a/src/V3Hashed.h b/src/V3Hashed.h index d6bbb9864..4403cbe0c 100644 --- a/src/V3Hashed.h +++ b/src/V3Hashed.h @@ -33,6 +33,7 @@ class V3Hashed { // NODE STATE // AstNode::user4() -> V3Hash. Hash value of this node (hash of 0 is illegal) + AstUser4InUse m_inuse4; // TYPES typedef multimap HashMmap; diff --git a/src/V3Inline.cpp b/src/V3Inline.cpp index 575a5ec95..5a3524760 100644 --- a/src/V3Inline.cpp +++ b/src/V3Inline.cpp @@ -52,6 +52,7 @@ class InlineVisitor : public AstNVisitor { private: // NODE STATE // Cleared entire netlist + // Input: // AstModule::userp() // bool. True to inline this module (from InlineMarkVisitor) // Cleared each cell // AstVar::user2p() // AstVarRef*/AstConst* Points to signal this is a direct connect to @@ -284,6 +285,9 @@ private: // AstModule::user() // OUTPUT: bool. User request to inline this module // AstModule::user2() // bool. Allowed to automatically inline module // AstModule::user3() // int. Number of cells referencing this module + AstUserInUse m_inuse1; + AstUser2InUse m_inuse2; + AstUser3InUse m_inuse3; // STATE AstModule* m_modp; // Current module diff --git a/src/V3Inst.cpp b/src/V3Inst.cpp index 3b45e8f21..d7ff762db 100644 --- a/src/V3Inst.cpp +++ b/src/V3Inst.cpp @@ -47,6 +47,7 @@ private: // AstVar::userp() -> AstNode*. Expression connected to given pin // AstVarRef::userp() -> bool. True if created senitem for parent's connected signal // AstPin::userp() -> bool. True if created assignment already + AstUserInUse m_inuse1; // STATE AstModule* m_modp; // Current module diff --git a/src/V3Life.cpp b/src/V3Life.cpp index f3f53191b..5ebe61d2a 100644 --- a/src/V3Life.cpp +++ b/src/V3Life.cpp @@ -44,6 +44,10 @@ // Structure for global state class LifeState { + // NODE STATE + // See below + AstUserInUse m_inuse1; + // STATE public: V3Double0 m_statAssnDel; // Statistic tracking diff --git a/src/V3LifePost.cpp b/src/V3LifePost.cpp index d9e5d75c6..c14c93a21 100644 --- a/src/V3LifePost.cpp +++ b/src/V3LifePost.cpp @@ -98,6 +98,9 @@ private: // AstVarScope::user() -> Sequence # of first virtex setting this var. // AstVarScope::user2() -> Sequence # of last consumption of this var // AstVarScope::user4() -> AstVarScope*: Passed to LifePostElim to substitute this var + AstUserInUse m_inuse1; + AstUser2InUse m_inuse2; + AstUser4InUse m_inuse4; // STATE uint32_t m_sequence; // Sequence number of assignments/varrefs @@ -107,7 +110,6 @@ private: virtual void visit(AstTopScope* nodep, AstNUser*) { AstNode::userClearTree(); // userp() used on entire tree AstNode::user2ClearTree(); // userp() used on entire tree - AstNode::user3ClearTree(); // userp() used on entire tree AstNode::user4ClearTree(); // userp() used on entire tree m_sequence = 0; nodep->iterateChildren(*this); diff --git a/src/V3Link.cpp b/src/V3Link.cpp index 896fb9713..fd04e732c 100644 --- a/src/V3Link.cpp +++ b/src/V3Link.cpp @@ -51,6 +51,8 @@ private: // AstBegin::userp() // V3SymTable* Local Symbol table // AstVar::userp() // V3SymTable* Table used to create this variable // AstVar::user2p() // bool True if port set for this variable + AstUserInUse m_inuse1; + AstUser2InUse m_inuse2; // ENUMS enum IdState { // Which loop through the tree @@ -107,8 +109,6 @@ private: // VISITs virtual void visit(AstNetlist* nodep, AstNUser*) { - AstNode::userClearTree(); - AstNode::user2ClearTree(); // Look at all modules, and store pointers to all module names for (AstModule* modp = v3Global.rootp()->modulesp(); modp; modp=modp->nextp()->castModule()) { V3SymTable* symp = new V3SymTable(NULL); diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index 4975a541c..8431587eb 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -87,6 +87,7 @@ private: // NODE STATE // Entire netlist: // AstModule::userp() // V3GraphVertex* Vertex describing this module + AstUserInUse m_inuse1; // STATE // Below state needs to be preserved between each module call. diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 55ad781ca..bfda8bf31 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -175,6 +175,8 @@ private: // Cleared on Netlist // AstModule::userp() -> LinkDotCellVertex*. Last cell that uses this module // AstVarScope::user2p() -> AstVarScope*. Base alias for this signal + AstUserInUse m_inuse1; + AstUser2InUse m_inuse2; // TYPES typedef std::multimap NameScopeMap; diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 18b0daf8e..8bee243a0 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -47,6 +47,7 @@ private: // NODE STATE // Cleared on netlist // AstNode::user() -> bool. True if processed + AstUserInUse m_inuse1; // STATE string m_dotText; // Dotted module text we are building for a dotted node, passed up @@ -231,7 +232,6 @@ public: m_inModDot = false; m_exp = AstParseRefExp::NONE; m_baseTextp = NULL; - AstNode::userClearTree(); // userp() used on entire tree rootp->accept(*this); } virtual ~LinkParseVisitor() {} diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 528588465..a81fd9aa2 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -48,6 +48,7 @@ private: // NODE STATE // Entire netlist: // AstCaseItem::user2() // bool Moved default caseitems + AstUser2InUse m_inuse2; // STATE // Below state needs to be preserved between each module call. @@ -59,12 +60,6 @@ private: // METHODS // VISITs - virtual void visit(AstNetlist* nodep, AstNUser*) { - AstNode::user2ClearTree(); - // And recurse... - nodep->iterateChildren(*this); - } - virtual void visit(AstModule* nodep, AstNUser*) { // Module: Create sim table for entire module and iterate UINFO(8,"MODULE "<iterateChildren(*this); moveVars(); diff --git a/src/V3Name.cpp b/src/V3Name.cpp index 2c26c19f3..477754fce 100644 --- a/src/V3Name.cpp +++ b/src/V3Name.cpp @@ -47,6 +47,8 @@ private: // // AstCell::user2() -> bool. Set true if was privitized // AstVar::user2() -> bool. Set true if was privitized + AstUserInUse m_inuse1; + AstUser2InUse m_inuse2; // STATE AstModule* m_modp; @@ -54,11 +56,6 @@ private: //int debug() { return 9; } // VISITORS - virtual void visit(AstNetlist* nodep, AstNUser*) { - AstNode::userClearTree(); - AstNode::user2ClearTree(); - nodep->iterateChildren(*this); - } virtual void visit(AstModule* nodep, AstNUser*) { m_modp = nodep; nodep->iterateChildren(*this); diff --git a/src/V3Order.cpp b/src/V3Order.cpp index b3423ece4..bceccec47 100644 --- a/src/V3Order.cpp +++ b/src/V3Order.cpp @@ -246,6 +246,11 @@ private: // Ordering (user3/4/5 cleared between forming and ordering) // AstScope::userp() -> AstModule*. Module this scope is under // AstModule::user3() -> Number of routines created + AstUserInUse m_inuse; + AstUser2InUse m_inuse2; + AstUser3InUse m_inuse3; + AstUser4InUse m_inuse4; + AstUser5InUse m_inuse5; //int debug() { return 9; } diff --git a/src/V3Param.cpp b/src/V3Param.cpp index 30f7fc241..e47a3dfa4 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -54,6 +54,8 @@ private: // NODE STATE // AstModule::user4() // bool True if parameters numbered // AstVar::user4() // int Global parameter number (for naming new module) + AstUser4InUse m_inuse4; + // STATE typedef std::map VarCloneMap; struct ModInfo { @@ -111,7 +113,6 @@ private: // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { - AstNode::user4ClearTree(); // Modules must be done in top-down-order nodep->iterateChildren(*this); } diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index 5898cf087..b16c0b8f2 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -49,6 +49,8 @@ private: // AstNodeMath::user() -> bool. True if iterated already // AstShiftL::user2() -> bool. True if converted to conditional // AstShiftR::user2() -> bool. True if converted to conditional + AstUserInUse m_inuse; + AstUser2InUse m_inuse2; // STATE AstModule* m_modp; // Current module @@ -306,8 +308,6 @@ public: } virtual ~PremitVisitor() {} void main(AstNode* nodep) { - AstNode::userClearTree(); // userp() used on entire tree - AstNode::user2ClearTree(); // user2p() used on entire tree nodep->accept(*this); } }; diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp index d8773defc..c62f09537 100644 --- a/src/V3Scope.cpp +++ b/src/V3Scope.cpp @@ -46,6 +46,8 @@ private: // NODE STATE // AstVar::userp -> AstVarScope replacement for this variable // AstVarRef::user2p -> bool. True indicates already processed + AstUserInUse m_inuse; + AstUser2InUse m_inuse2; // STATE, inside processing a single module AstModule* m_modp; // Current module diff --git a/src/V3Split.cpp b/src/V3Split.cpp index 91787a111..186bdfb4b 100644 --- a/src/V3Split.cpp +++ b/src/V3Split.cpp @@ -218,6 +218,10 @@ private: // AstVarScope::user2p -> Var SplitNodeVertex* for delayed assignment var, 0=not set yet // Ast*::user3p -> Statement SplitLogicVertex* (temporary only) // Ast*::user4 -> Current ordering number (reorderBlock usage) + AstUserInUse m_inuse; + AstUser2InUse m_inuse2; + AstUser3InUse m_inuse3; + AstUser4InUse m_inuse4; // TYPES typedef vector VStack; diff --git a/src/V3SplitAs.cpp b/src/V3SplitAs.cpp index af74a5ac9..a8dd573fb 100644 --- a/src/V3SplitAs.cpp +++ b/src/V3SplitAs.cpp @@ -138,6 +138,7 @@ class SplitAsVisitor : public SplitAsBaseVisitor { private: // NODE STATE // AstAlways::user() -> bool. True if already processed + AstUserInUse m_inuse; // STATE V3Double0 m_statSplits; // Statistic tracking diff --git a/src/V3Subst.cpp b/src/V3Subst.cpp index 1c35d589c..a5027bef7 100644 --- a/src/V3Subst.cpp +++ b/src/V3Subst.cpp @@ -230,7 +230,9 @@ private: // Passed to SubstUseVisitor // AstVar::userp -> SubstVar* for usage var, 0=not set yet // AstVar::user2 -> int step number for last assignment, 0=not set yet - // + AstUserInUse m_inuse; + AstUser2InUse m_inuse2; + // STATE vector m_entryps; // Nodes to delete when we are finished int m_ops; // Number of operators on assign rhs diff --git a/src/V3Table.cpp b/src/V3Table.cpp index 0d632a050..859a79106 100644 --- a/src/V3Table.cpp +++ b/src/V3Table.cpp @@ -368,6 +368,10 @@ class TableVisitor : public TableBaseVisitor { private: // NODE STATE // Cleared on each always/assignw + AstUserInUse m_inuse; + AstUser2InUse m_inuse2; + AstUser3InUse m_inuse3; + AstUser4InUse m_inuse4; // STATE double m_totalBytes; // Total bytes in tables created diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 8a053a366..5d02e938f 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -764,6 +764,11 @@ public: void V3Task::taskAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "< bool. Set true if already processed + AstUserInUse m_inuse; // STATE AstModule* m_modp; // Current module @@ -60,11 +61,6 @@ private: //int debug() { return 9; } // VISITORS - virtual void visit(AstNetlist* nodep, AstNUser*) { - //VV***** We reset all userp() on the netlist!!! - AstNode::userClearTree(); - nodep->iterateChildren(*this); - } virtual void visit(AstModule* nodep, AstNUser*) { UINFO(4," MOD "<