Internal coding: Assert that user#() don't overlap.

Any use of a user() must now be declared, generally in the Visitor class with
    AstUser#InUse   arbitrary_object
This lets the code track if there's another request for the same user(),
preventing nasty hard to debug cases where they overlap.  This will also
call user#ClearTree(), so a bunch of those were removed, though many
extranious ones still remain.
This commit is contained in:
Wilson Snyder 2008-11-21 15:50:33 -05:00
parent 7ad29c6329
commit 8b77379e2c
43 changed files with 214 additions and 68 deletions

View File

@ -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() {}

View File

@ -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() {

View File

@ -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

View File

@ -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++; }

View File

@ -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

View File

@ -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() {}

View File

@ -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

View File

@ -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);
}
};

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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<AstVarScope*,AstNodeAssign*> 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

View File

@ -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*) {

View File

@ -163,7 +163,6 @@ public:
m_depth=0;
m_maxdepth=0;
//
AstNode::userClearTree(); // userp() used on entire tree
nodep->accept(*this);
}
virtual ~DepthVisitor() {}

View File

@ -45,6 +45,7 @@ private:
// NODE STATE
// Cleared entire netlist
// AstCFunc::user() // bool. Indicates processing completed
AstUserInUse m_inuse1;
// TYPES
typedef multimap<string,AstCFunc*> FuncMmap;
@ -245,7 +246,6 @@ public:
m_modp = NULL;
m_scopep = NULL;
m_needThis = false;
AstNode::userClearTree();
nodep->accept(*this);
}
virtual ~DescopeVisitor() {}

View File

@ -905,7 +905,6 @@ public:
}
virtual ~ExpandVisitor() {}
void main(AstNode* nodep) {
AstNode::userClearTree(); // userp() used on entire tree
nodep->accept(*this);
}
};

View File

@ -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");

View File

@ -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

View File

@ -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

View File

@ -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<V3Hash,AstNode*> HashMmap;

View File

@ -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

View File

@ -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

View File

@ -44,6 +44,10 @@
// Structure for global state
class LifeState {
// NODE STATE
// See below
AstUserInUse m_inuse1;
// STATE
public:
V3Double0 m_statAssnDel; // Statistic tracking

View File

@ -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);

View File

@ -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);

View File

@ -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.

View File

@ -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<string,LinkDotCellVertex*> NameScopeMap;

View File

@ -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() {}

View File

@ -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 "<<nodep<<endl);

View File

@ -101,6 +101,9 @@ class LocalizeVisitor : public LocalizeBaseVisitor {
private:
// NODE STATE/TYPES
// See above
AstUserInUse m_inuse1;
AstUser2InUse m_inuse2;
AstUser4InUse m_inuse4;
// STATE
V3Double0 m_statLocVars; // Statistic tracking
@ -150,7 +153,6 @@ private:
virtual void visit(AstNetlist* 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
nodep->iterateChildren(*this);
moveVars();

View File

@ -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);

View File

@ -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; }

View File

@ -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<AstVar*,AstVar*> 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);
}

View File

@ -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);
}
};

View File

@ -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

View File

@ -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<SplitLogicVertex*> VStack;

View File

@ -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

View File

@ -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<SubstVarEntry*> m_entryps; // Nodes to delete when we are finished
int m_ops; // Number of operators on assign rhs

View File

@ -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

View File

@ -764,6 +764,11 @@ public:
void V3Task::taskAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
AstUserInUse m_inuse;
AstUser2InUse m_inuse2;
AstUser3InUse m_inuse3;
AstUser4InUse m_inuse4;
AstUser5InUse m_inuse5;
TaskStateVisitor visitors (nodep);
TaskVisitor visitor (nodep, &visitors);
}

View File

@ -160,6 +160,10 @@ private:
// AstVarScope::user() // V3GraphVertex* for this node
// AstCCall::user2() // bool; walked next list for other ccalls
// Ast*::user3() // TraceActivityVertex* for this node
AstUserInUse m_inuse;
AstUser2InUse m_inuse2;
AstUser3InUse m_inuse3;
//AstUser4InUse In V3Hashed
// STATE
AstModule* m_topModp; // Module to add variables to
@ -548,9 +552,6 @@ private:
// VISITORS
virtual void visit(AstNetlist* nodep, AstNUser*) {
AstNode::userClearTree();
AstNode::user2ClearTree();
AstNode::user3ClearTree();
m_code = 1; // Multiple TopScopes will require fixing how code#s
// are assigned as duplicate varscopes must result in the same tracing code#.

View File

@ -41,7 +41,6 @@
class TraceDeclVisitor : public EmitCBaseVisitor {
private:
// NODE STATE
// Cleared entire netlist
// STATE
AstModule* m_modp; // Current module

View File

@ -51,6 +51,7 @@ private:
// NODE STATE
// Cleared on Netlist
// AstArraySel::user() -> 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 "<<nodep<<endl);
m_modp = nodep;