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:
parent
7ad29c6329
commit
8b77379e2c
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
138
src/V3Ast.h
138
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++; }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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*) {
|
||||
|
|
|
|||
|
|
@ -163,7 +163,6 @@ public:
|
|||
m_depth=0;
|
||||
m_maxdepth=0;
|
||||
//
|
||||
AstNode::userClearTree(); // userp() used on entire tree
|
||||
nodep->accept(*this);
|
||||
}
|
||||
virtual ~DepthVisitor() {}
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -905,7 +905,6 @@ public:
|
|||
}
|
||||
virtual ~ExpandVisitor() {}
|
||||
void main(AstNode* nodep) {
|
||||
AstNode::userClearTree(); // userp() used on entire tree
|
||||
nodep->accept(*this);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@
|
|||
// Structure for global state
|
||||
|
||||
class LifeState {
|
||||
// NODE STATE
|
||||
// See below
|
||||
AstUserInUse m_inuse1;
|
||||
|
||||
// STATE
|
||||
public:
|
||||
V3Double0 m_statAssnDel; // Statistic tracking
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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#.
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@
|
|||
class TraceDeclVisitor : public EmitCBaseVisitor {
|
||||
private:
|
||||
// NODE STATE
|
||||
// Cleared entire netlist
|
||||
|
||||
// STATE
|
||||
AstModule* m_modp; // Current module
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue