Internals: Rename AstNode::userp to user1p for easier searching
and to disambiguate from the vertex/edge-> userp.
This commit is contained in:
parent
5563c9666c
commit
5bdb8674ed
|
|
@ -34,10 +34,10 @@ that visitor class. For example:
|
|||
|
||||
// NODE STATE
|
||||
// Cleared entire netlist
|
||||
// AstModule::userp() // bool. True to inline this module
|
||||
// AstModule::user1p() // bool. True to inline this module
|
||||
|
||||
This says that at the AstNetlist userClearTree() is called. Each
|
||||
AstModule's is user() is used to indicate if we're going to inline it.
|
||||
This says that at the AstNetlist user1ClearTree() is called. Each
|
||||
AstModule's is user1() is used to indicate if we're going to inline it.
|
||||
|
||||
These comments are important to make sure a user#() on a given AstNode type
|
||||
is never being used for two different purposes.
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ private:
|
|||
// NODE STATE
|
||||
// Entire netlist
|
||||
// AstNode::user() bool. True if processed
|
||||
AstUserInUse m_inuse1;
|
||||
AstUser1InUse m_inuser1;
|
||||
|
||||
// STATE
|
||||
AstTopScope* m_topscopep; // Top scope for adding sentrees under
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ private:
|
|||
// NODE STATE/TYPES
|
||||
// Cleared on netlist
|
||||
// AstNode::user() -> bool. True if processed
|
||||
AstUserInUse m_inuse1;
|
||||
AstUser1InUse m_inuser1;
|
||||
|
||||
// STATE
|
||||
AstModule* m_modp; // Last module
|
||||
|
|
@ -176,8 +176,8 @@ private:
|
|||
// VISITORS //========== Case assertions
|
||||
virtual void visit(AstCase* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (!nodep->user()) {
|
||||
nodep->user(true);
|
||||
if (!nodep->user1()) {
|
||||
nodep->user1(true);
|
||||
bool has_default=false;
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
if (itemp->isDefault()) has_default=true;
|
||||
|
|
|
|||
|
|
@ -39,12 +39,12 @@ 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;
|
||||
uint32_t AstUserInUse::s_userCntGbl=0; // Hot cache line, leave adjacent
|
||||
uint32_t AstUser1InUse::s_userCntGbl=0; // Hot cache line, leave adjacent
|
||||
uint32_t AstUser2InUse::s_userCntGbl=0; // Hot cache line, leave adjacent
|
||||
uint32_t AstUser3InUse::s_userCntGbl=0; // Hot cache line, leave adjacent
|
||||
uint32_t AstUser4InUse::s_userCntGbl=0; // Hot cache line, leave adjacent
|
||||
|
||||
bool AstUserInUse::s_userBusy=false;
|
||||
bool AstUser1InUse::s_userBusy=false;
|
||||
bool AstUser2InUse::s_userBusy=false;
|
||||
bool AstUser3InUse::s_userBusy=false;
|
||||
bool AstUser4InUse::s_userBusy=false;
|
||||
|
|
@ -74,8 +74,8 @@ void AstNode::init() {
|
|||
m_signed = false;
|
||||
m_width = 0;
|
||||
m_widthMin = 0;
|
||||
m_userp = NULL;
|
||||
m_userCnt = 0;
|
||||
m_user1p = NULL;
|
||||
m_user1Cnt = 0;
|
||||
m_user2p = NULL;
|
||||
m_user2Cnt = 0;
|
||||
m_user3p = NULL;
|
||||
|
|
@ -847,7 +847,10 @@ void AstNode::dumpPtrs(ostream& os) {
|
|||
if (op2p()) os<<" op2p="<<(void*)op2p();
|
||||
if (op3p()) os<<" op3p="<<(void*)op3p();
|
||||
if (op4p()) os<<" op4p="<<(void*)op4p();
|
||||
if (userp()) os<<" user="<<(void*)userp();
|
||||
if (user1p()) os<<" user1p="<<(void*)user1p();
|
||||
if (user2p()) os<<" user2p="<<(void*)user2p();
|
||||
if (user3p()) os<<" user3p="<<(void*)user3p();
|
||||
if (user4p()) os<<" user4p="<<(void*)user4p();
|
||||
if (m_iterpp) {
|
||||
os<<" iterpp="<<(void*)m_iterpp;
|
||||
os<<"*="<<(void*)*m_iterpp;
|
||||
|
|
|
|||
24
src/V3Ast.h
24
src/V3Ast.h
|
|
@ -398,14 +398,14 @@ protected:
|
|||
// 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 {
|
||||
class AstUser1InUse : AstUserInUseBase {
|
||||
protected:
|
||||
friend class AstNode;
|
||||
static uint32_t 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*/); }
|
||||
AstUser1InUse() { allocate(s_userCntGbl/*ref*/, s_userBusy/*ref*/); }
|
||||
~AstUser1InUse() { free (s_userCntGbl/*ref*/, s_userBusy/*ref*/); }
|
||||
static void clear() { clearcnt(s_userCntGbl/*ref*/, s_userBusy/*ref*/); }
|
||||
};
|
||||
class AstUser2InUse : AstUserInUseBase {
|
||||
|
|
@ -563,8 +563,8 @@ class AstNode {
|
|||
int m_width; // Bit width of operation
|
||||
int m_widthMin; // If unsized, bitwidth of minimum implementation
|
||||
// This member ordering both allows 64 bit alignment and puts associated data together
|
||||
AstNUser* m_userp; // Pointer to any information the user iteration routine wants
|
||||
uint32_t m_userCnt; // Mark of when userp was set
|
||||
AstNUser* m_user1p; // Pointer to any information the user iteration routine wants
|
||||
uint32_t m_user1Cnt; // Mark of when userp was set
|
||||
uint32_t m_user2Cnt; // Mark of when userp was set
|
||||
AstNUser* m_user2p; // Pointer to any information the user iteration routine wants
|
||||
AstNUser* m_user3p; // Pointer to any information the user iteration routine wants
|
||||
|
|
@ -678,15 +678,15 @@ public:
|
|||
bool isQuad() const { return (width()>VL_WORDSIZE && width()<=VL_QUADSIZE); }
|
||||
bool isWide() const { return (width()>VL_QUADSIZE); }
|
||||
|
||||
AstNUser* userp() const {
|
||||
AstNUser* user1p() 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);
|
||||
//UASSERT_STATIC(AstUser1InUse::s_userBusy, "userp set w/o busy");
|
||||
return ((m_user1Cnt==AstUser1InUse::s_userCntGbl)?m_user1p:NULL);
|
||||
}
|
||||
void userp(void* userp) { m_userp=(AstNUser*)(userp); m_userCnt=AstUserInUse::s_userCntGbl; }
|
||||
int user() const { return userp()->castInt(); }
|
||||
void user(int val) { userp(AstNUser::fromInt(val)); }
|
||||
static void userClearTree() { AstUserInUse::clear(); } // Clear userp()'s across the entire tree
|
||||
void user1p(void* userp) { m_user1p=(AstNUser*)(userp); m_user1Cnt=AstUser1InUse::s_userCntGbl; }
|
||||
int user1() const { return user1p()->castInt(); }
|
||||
void user1(int val) { user1p(AstNUser::fromInt(val)); }
|
||||
static void user1ClearTree() { AstUser1InUse::clear(); } // Clear userp()'s across the entire tree
|
||||
|
||||
AstNUser* user2p() const {
|
||||
//UASSERT_STATIC(AstUser2InUse::s_userBusy, "user2p set w/o busy");
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ private:
|
|||
// NODE STATE
|
||||
// Cleared each Case
|
||||
// AstIf::user3() -> bool. Set true to indicate clone not needed
|
||||
AstUser3InUse m_inuse3;
|
||||
AstUser3InUse m_inuser3;
|
||||
|
||||
// STATE
|
||||
V3Double0 m_statCaseFast; // Statistic tracking
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ private:
|
|||
// NODE STATE
|
||||
// Entire netlist:
|
||||
// AstNode::user() // bool. Indicates node is of known size
|
||||
AstUserInUse m_inuse1;
|
||||
AstUser1InUse m_inuser1;
|
||||
|
||||
// STATE
|
||||
//int debug() { return 9; }
|
||||
|
|
@ -77,7 +77,7 @@ private:
|
|||
//if (debug()>8) castp->dumpTree(cout,"-castins: ");
|
||||
//
|
||||
insureLower32Cast(castp);
|
||||
nodep->user(1); // Now must be of known size
|
||||
nodep->user1(1); // Now must be of known size
|
||||
}
|
||||
int castSize (AstNode* nodep) {
|
||||
if (nodep->isQuad()) return VL_QUADSIZE;
|
||||
|
|
@ -87,7 +87,7 @@ private:
|
|||
}
|
||||
void insureCast(AstNode* nodep) {
|
||||
if (castSize(nodep->backp()) != castSize(nodep)
|
||||
|| !nodep->user()) {
|
||||
|| !nodep->user1()) {
|
||||
insertCast(nodep, castSize(nodep->backp()));
|
||||
}
|
||||
}
|
||||
|
|
@ -105,21 +105,21 @@ private:
|
|||
// VISITORS
|
||||
virtual void visit(AstNodeUniop* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->user(nodep->lhsp()->user());
|
||||
nodep->user1(nodep->lhsp()->user1());
|
||||
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
|
||||
}
|
||||
virtual void visit(AstNodeBiop* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->user(nodep->lhsp()->user()
|
||||
| nodep->rhsp()->user());
|
||||
nodep->user1(nodep->lhsp()->user1()
|
||||
| nodep->rhsp()->user1());
|
||||
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
|
||||
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
|
||||
}
|
||||
virtual void visit(AstNodeTriop* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->user(nodep->lhsp()->user()
|
||||
| nodep->rhsp()->user()
|
||||
| nodep->thsp()->user());
|
||||
nodep->user1(nodep->lhsp()->user1()
|
||||
| nodep->rhsp()->user1()
|
||||
| nodep->thsp()->user1());
|
||||
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
|
||||
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
|
||||
if (nodep->sizeMattersThs()) insureCast(nodep->thsp());
|
||||
|
|
@ -127,11 +127,11 @@ private:
|
|||
virtual void visit(AstCast* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
insureLower32Cast(nodep);
|
||||
nodep->user(1);
|
||||
nodep->user1(1);
|
||||
}
|
||||
virtual void visit(AstUnaryMin* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->user(nodep->lhsp()->user());
|
||||
nodep->user1(nodep->lhsp()->user1());
|
||||
if (nodep->lhsp()->widthMin()==1) {
|
||||
// We want to avoid a GCC "converting of negative value" warning
|
||||
// from our expansion of
|
||||
|
|
@ -151,13 +151,13 @@ private:
|
|||
// CData x=3; out = (QData)(x<<30);
|
||||
insertCast (nodep, castSize(nodep));
|
||||
}
|
||||
nodep->user(1);
|
||||
nodep->user1(1);
|
||||
}
|
||||
virtual void visit(AstConst* nodep, AstNUser*) {
|
||||
// Constants are of unknown size if smaller than 33 bits, becase
|
||||
// we're too lazy to wrap every constant in the universe in
|
||||
// ((IData)#).
|
||||
nodep->user(nodep->isQuad() || nodep->isWide());
|
||||
nodep->user1(nodep->isQuad() || nodep->isWide());
|
||||
}
|
||||
|
||||
// NOPs
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@ class ChangedVisitor : public AstNVisitor {
|
|||
private:
|
||||
// NODE STATE
|
||||
// Entire netlist:
|
||||
// AstVarScope::user() -> bool. True indicates processed
|
||||
AstUserInUse m_inuse1;
|
||||
// AstVarScope::user1() -> bool. True indicates processed
|
||||
AstUser1InUse m_inuser1;
|
||||
|
||||
// STATE
|
||||
AstModule* m_topModp; // Top module
|
||||
|
|
@ -103,7 +103,7 @@ private:
|
|||
virtual void visit(AstTopScope* nodep, AstNUser*) {
|
||||
UINFO(4," TS "<<nodep<<endl);
|
||||
// Clearing
|
||||
AstNode::userClearTree();
|
||||
AstNode::user1ClearTree();
|
||||
// Create the change detection function
|
||||
AstScope* scopep = nodep->scopep();
|
||||
if (!scopep) nodep->v3fatalSrc("No scope found on top level, perhaps you have no statements?\n");
|
||||
|
|
@ -122,8 +122,8 @@ private:
|
|||
virtual void visit(AstVarScope* nodep, AstNUser*) {
|
||||
if (nodep->isCircular()) {
|
||||
UINFO(8," CIRC "<<nodep<<endl);
|
||||
if (!nodep->user()) {
|
||||
nodep->user(true);
|
||||
if (!nodep->user1()) {
|
||||
nodep->user1(true);
|
||||
genChangeDet(nodep);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,8 +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;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
|
||||
// STATE
|
||||
AstModule* m_modp;
|
||||
|
|
@ -80,10 +80,10 @@ private:
|
|||
|
||||
// Store the clean state in the userp on each node
|
||||
void setCleanState(AstNode* nodep, CleanState clean) {
|
||||
nodep->user(clean);
|
||||
nodep->user1(clean);
|
||||
}
|
||||
CleanState getCleanState(AstNode* nodep) {
|
||||
return ((CleanState)nodep->user());
|
||||
return ((CleanState)nodep->user1());
|
||||
}
|
||||
bool isClean(AstNode* nodep) {
|
||||
CleanState clstate = getCleanState(nodep);
|
||||
|
|
|
|||
|
|
@ -50,10 +50,10 @@ class ClockVisitor : public AstNVisitor {
|
|||
private:
|
||||
// NODE STATE
|
||||
// Cleared each Module:
|
||||
// AstVarScope::userp() -> AstVarScope*. Temporary signal that was created.
|
||||
// AstVarScope::user1p() -> AstVarScope*. Temporary signal that was created.
|
||||
// AstVarScope::user2p() -> AstVarScope*. Temporary signal for change detects
|
||||
AstUserInUse m_inuse1;
|
||||
AstUser2InUse m_inuse2;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
|
||||
// TYPES
|
||||
enum { DOUBLE_OR_RATE = 10 }; // How many | per ||, Determined experimentally as best
|
||||
|
|
@ -75,7 +75,7 @@ private:
|
|||
|
||||
// METHODS
|
||||
AstVarScope* getCreateLastClk(AstVarScope* vscp) {
|
||||
if (vscp->userp()) return ((AstVarScope*)vscp->userp());
|
||||
if (vscp->user1p()) return ((AstVarScope*)vscp->user1p());
|
||||
AstVar* varp = vscp->varp();
|
||||
if (varp->width()!=1) varp->v3error("Unsupported: Clock edge on non-single bit signal: "<<varp->prettyName());
|
||||
string newvarname = ((string)"__Vclklast__"+vscp->scopep()->nameDotless()+"__"+varp->shortName());
|
||||
|
|
@ -84,7 +84,7 @@ private:
|
|||
newvarp->width(1,1);
|
||||
m_modp->addStmtp(newvarp);
|
||||
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp);
|
||||
vscp->userp(newvscp);
|
||||
vscp->user1p(newvscp);
|
||||
m_scopep->addVarp(newvscp);
|
||||
// At bottom, assign them
|
||||
AstAssign* finalp
|
||||
|
|
@ -187,8 +187,8 @@ private:
|
|||
m_topScopep=nodep;
|
||||
m_scopep = nodep->scopep();
|
||||
if (!m_scopep) nodep->v3fatalSrc("No scope found on top level, perhaps you have no statements?\n");
|
||||
//VV***** We reset all userp()
|
||||
AstNode::userClearTree();
|
||||
//VV***** We reset all user1p()
|
||||
AstNode::user1ClearTree();
|
||||
// Make top functions
|
||||
{
|
||||
AstCFunc* funcp = new AstCFunc(nodep->fileline(), "_eval", m_scopep);
|
||||
|
|
|
|||
|
|
@ -174,8 +174,8 @@ 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;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser3InUse m_inuser3;
|
||||
//AstUser4InUse part of V3Hashed
|
||||
|
||||
// STATE
|
||||
|
|
@ -282,7 +282,7 @@ private:
|
|||
if (node1p==node2p) continue;
|
||||
//
|
||||
// We need to mark iteration to prevent matching code inside code (abab matching in ababab)
|
||||
AstNode::userClearTree(); // userp() used on entire tree
|
||||
AstNode::user1ClearTree(); // user1p() used on entire tree
|
||||
m_walkLast1p = NULL;
|
||||
m_walkLast2p = NULL;
|
||||
int depth = walkDupCodeNext(node1p, node2p, 1);
|
||||
|
|
@ -308,7 +308,7 @@ private:
|
|||
|
||||
int walkDupCodeNext(AstNode* node1p, AstNode* node2p, int level) {
|
||||
// Find number of common statements between the two node1p_nextp's...
|
||||
if (node1p->userp() || node2p->userp()) return 0; // Already iterated
|
||||
if (node1p->user1p() || node2p->user1p()) return 0; // Already iterated
|
||||
if (node1p->user3p() || node2p->user3p()) return 0; // Already merged
|
||||
if (!m_hashed.sameNodes(node1p,node2p)) return 0; // walk of tree has same comparison
|
||||
V3Hash hashval(node1p->user4p());
|
||||
|
|
@ -316,8 +316,8 @@ private:
|
|||
//UINFO(9," wdup2 "<<level<<" "<<V3Hash(node2p->user4p())<<" "<<node2p<<endl);
|
||||
m_walkLast1p = node1p;
|
||||
m_walkLast2p = node2p;
|
||||
node1p->user(true);
|
||||
node2p->user(true);
|
||||
node1p->user1(true);
|
||||
node2p->user1(true);
|
||||
if (node1p->nextp() && node2p->nextp()) {
|
||||
return hashval.depth()+walkDupCodeNext(node1p->nextp(), node2p->nextp(), level+1);
|
||||
}
|
||||
|
|
@ -381,8 +381,7 @@ private:
|
|||
// Track all callers of each function
|
||||
m_call.main(nodep);
|
||||
//
|
||||
AstNode::user3ClearTree(); // userp() used on entire tree
|
||||
//In V3Hashed AstNode::user4ClearTree(); // userp() used on entire tree
|
||||
//In V3Hashed AstNode::user4ClearTree(); // user4p() used on entire tree
|
||||
// Iterate modules backwards, in bottom-up order.
|
||||
// Required so that a module instantiating another can benefit from collapsing.
|
||||
nodep->iterateChildrenBackwards(*this);
|
||||
|
|
|
|||
|
|
@ -673,7 +673,7 @@ private:
|
|||
if (m_warn && !nodep->castAssignDly()) { // Is same var on LHS and RHS?
|
||||
// Note only do this (need user4) when m_warn, which is
|
||||
// done as unique visitor
|
||||
AstUser4InUse m_inuse4;
|
||||
AstUser4InUse m_inuser4;
|
||||
ConstVarMarkVisitor mark(nodep->lhsp());
|
||||
ConstVarFindVisitor find(nodep->rhsp());
|
||||
if (find.found()) need_temp = true;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ private:
|
|||
// VISITORS
|
||||
virtual void visit(AstCell* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->modp()->user(nodep->modp()->user() - 1);
|
||||
nodep->modp()->user1(nodep->modp()->user1() - 1);
|
||||
}
|
||||
//-----
|
||||
virtual void visit(AstNodeMath* nodep, AstNUser*) {} // Accelerate
|
||||
|
|
@ -70,7 +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;
|
||||
AstUser1InUse m_inuser1;
|
||||
|
||||
// TYPES
|
||||
typedef multimap<AstVarScope*,AstNodeAssign*> AssignMap;
|
||||
|
|
@ -88,16 +88,16 @@ private:
|
|||
// VISITORS
|
||||
virtual void visit(AstCell* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->modp()->user(nodep->modp()->user() + 1);
|
||||
nodep->modp()->user1(nodep->modp()->user1() + 1);
|
||||
}
|
||||
virtual void visit(AstNodeVarRef* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (nodep->varScopep()) {
|
||||
nodep->varScopep()->user(nodep->varScopep()->user() + 1);
|
||||
nodep->varScopep()->varp()->user(nodep->varScopep()->varp()->user() + 1);
|
||||
nodep->varScopep()->user1(nodep->varScopep()->user1() + 1);
|
||||
nodep->varScopep()->varp()->user1(nodep->varScopep()->varp()->user1() + 1);
|
||||
}
|
||||
if (nodep->varp()) {
|
||||
nodep->varp()->user(nodep->varp()->user() + 1);
|
||||
nodep->varp()->user1(nodep->varp()->user1() + 1);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVarScope* nodep, AstNUser*) {
|
||||
|
|
@ -143,7 +143,7 @@ private:
|
|||
AstModule* nextmodp;
|
||||
for (AstModule* modp = v3Global.rootp()->modulesp(); modp; modp=nextmodp) {
|
||||
nextmodp = modp->nextp()->castModule();
|
||||
if (modp->level()>2 && modp->user()==0) {
|
||||
if (modp->level()>2 && modp->user1()==0) {
|
||||
// > 2 because L1 is the wrapper, L2 is the top user module
|
||||
UINFO(4," Dead module "<<modp<<endl);
|
||||
// And its children may now be killable too; correct counts
|
||||
|
|
@ -164,7 +164,7 @@ private:
|
|||
// Delete any unused varscopes
|
||||
for (vector<AstVarScope*>::iterator it = m_vscsp.begin(); it!=m_vscsp.end(); ++it) {
|
||||
AstVarScope* vscp = *it;
|
||||
if (vscp->user() == 0 && canElim(vscp->varp())) {
|
||||
if (vscp->user1() == 0 && canElim(vscp->varp())) {
|
||||
UINFO(4," Dead "<<vscp<<endl);
|
||||
pair <AssignMap::iterator,AssignMap::iterator> eqrange = m_assignMap.equal_range(vscp);
|
||||
for (AssignMap::iterator it = eqrange.first; it != eqrange.second; ++it) {
|
||||
|
|
@ -176,7 +176,7 @@ private:
|
|||
}
|
||||
}
|
||||
for (vector<AstVar*>::iterator it = m_varsp.begin(); it!=m_varsp.end(); ++it) {
|
||||
if ((*it)->user() == 0 && canElim((*it))) {
|
||||
if ((*it)->user1() == 0 && canElim((*it))) {
|
||||
UINFO(4," Dead "<<(*it)<<endl);
|
||||
(*it)->unlinkFrBack()->deleteTree(); (*it)=NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,10 +72,10 @@ class DelayedVisitor : public AstNVisitor {
|
|||
private:
|
||||
// NODE STATE
|
||||
// Cleared each module:
|
||||
// AstVarScope::userp() -> AstVarScope*. Points to temp var created.
|
||||
// AstVarScope::user1p() -> AstVarScope*. Points to temp var created.
|
||||
// AstVarScope::user2p() -> AstActive*. Points to activity block of signal
|
||||
// AstVarScope::user4p() -> AstAlwaysPost*. Post block for this variable
|
||||
// AstVar::user() -> VarUsage. Tracks delayed vs non-delayed usage
|
||||
// AstVar::user1() -> VarUsage. Tracks delayed vs non-delayed usage
|
||||
// AstVar::user2() -> bool. Set true if already made warning
|
||||
// AstVar::user4() -> int. Vector number, for assignment creation
|
||||
// AstVarRef::user2() -> bool. Set true if already processed
|
||||
|
|
@ -83,10 +83,10 @@ private:
|
|||
// Cleared each scope:
|
||||
// AstAssignDly::user3() -> AstVarScope*. __Vdlyvset__ created for this assign
|
||||
// AstAlwaysPost::user3() -> AstVarScope*. __Vdlyvset__ last referenced in IF
|
||||
AstUserInUse m_inuse1;
|
||||
AstUser2InUse m_inuse2;
|
||||
AstUser3InUse m_inuse3;
|
||||
AstUser4InUse m_inuse4;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
AstUser3InUse m_inuser3;
|
||||
AstUser4InUse m_inuser4;
|
||||
|
||||
enum VarUsage { VU_NONE=0, VU_DLY=1, VU_NONDLY=2 };
|
||||
|
||||
|
|
@ -106,8 +106,8 @@ private:
|
|||
// METHODS
|
||||
void markVarUsage(AstVar* nodep, uint32_t flags) {
|
||||
//UINFO(4," MVU "<<flags<<" "<<nodep<<endl);
|
||||
nodep->user( nodep->user() | flags );
|
||||
if ((nodep->user() & VU_DLY) && (nodep->user() & VU_NONDLY)) {
|
||||
nodep->user1( nodep->user1() | flags );
|
||||
if ((nodep->user1() & VU_DLY) && (nodep->user1() & VU_NONDLY)) {
|
||||
nodep->v3warn(BLKANDNBLK,"Unsupported: Blocked and non-blocking assignments to same variable: "<<nodep->prettyName());
|
||||
}
|
||||
}
|
||||
|
|
@ -354,7 +354,7 @@ private:
|
|||
if (!m_activep->hasClocked()) nodep->v3error("Internal: Blocking <= assignment in non-clocked block, should have converted in V3Active");
|
||||
AstVarScope* oldvscp = nodep->varScopep();
|
||||
if (!oldvscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n");
|
||||
AstVarScope* dlyvscp = oldvscp->userp()->castNode()->castVarScope();
|
||||
AstVarScope* dlyvscp = oldvscp->user1p()->castNode()->castVarScope();
|
||||
if (dlyvscp) { // Multiple use of delayed variable
|
||||
AstActive* oldactivep = dlyvscp->user2p()->castNode()->castActive();
|
||||
if (!oldactivep) nodep->v3fatalSrc("<= old dly assignment not put under sensitivity block");
|
||||
|
|
@ -394,7 +394,7 @@ private:
|
|||
new AstVarRef(nodep->fileline(), oldvscp, true),
|
||||
new AstVarRef(nodep->fileline(), dlyvscp, false));
|
||||
postp->lhsp()->user2(true); // Don't detect this assignment
|
||||
oldvscp->userp(dlyvscp); // So we can find it later
|
||||
oldvscp->user1p(dlyvscp); // So we can find it later
|
||||
// Make new ACTIVE with identical sensitivity tree
|
||||
AstActive* newactp = new AstActive (nodep->fileline(), "sequentdly",
|
||||
m_activep->sensesp());
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ private:
|
|||
// NODE STATE
|
||||
// Cleared entire netlist
|
||||
// AstCFunc::user() // bool. Indicates processing completed
|
||||
AstUserInUse m_inuse1;
|
||||
AstUser1InUse m_inuser1;
|
||||
|
||||
// TYPES
|
||||
typedef multimap<string,AstCFunc*> FuncMmap;
|
||||
|
|
@ -211,10 +211,10 @@ private:
|
|||
// nodep->funcp()->scopep(NULL);
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep, AstNUser*) {
|
||||
if (!nodep->user()) {
|
||||
if (!nodep->user1()) {
|
||||
m_needThis = false;
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->user(true);
|
||||
nodep->user1(true);
|
||||
if (m_needThis) {
|
||||
nodep->v3fatalSrc("old code");
|
||||
// Really we should have more node types for backend optimization of this stuff
|
||||
|
|
|
|||
|
|
@ -229,9 +229,9 @@ class GateVisitor : public GateBaseVisitor {
|
|||
private:
|
||||
// NODE STATE
|
||||
//Entire netlist:
|
||||
// AstVarScope::userp -> GateVarVertex* for usage var, 0=not set yet
|
||||
// {statement}Node::userp -> GateLogicVertex* for this statement
|
||||
AstUserInUse m_inuse1;
|
||||
// AstVarScope::user1p -> GateVarVertex* for usage var, 0=not set yet
|
||||
// {statement}Node::user1p -> GateLogicVertex* for this statement
|
||||
AstUser1InUse m_inuser1;
|
||||
|
||||
// STATE
|
||||
V3Graph m_graph; // Scoreboard of var usages/dependencies
|
||||
|
|
@ -263,11 +263,11 @@ private:
|
|||
}
|
||||
|
||||
GateVarVertex* makeVarVertex(AstVarScope* varscp) {
|
||||
GateVarVertex* vertexp = (GateVarVertex*)(varscp->userp());
|
||||
GateVarVertex* vertexp = (GateVarVertex*)(varscp->user1p());
|
||||
if (!vertexp) {
|
||||
UINFO(6,"New vertex "<<varscp<<endl);
|
||||
vertexp = new GateVarVertex(&m_graph, m_scopep, varscp);
|
||||
varscp->userp(vertexp);
|
||||
varscp->user1p(vertexp);
|
||||
if (varscp->varp()->isSigPublic()) {
|
||||
// Public signals shouldn't be changed, pli code might be messing with them
|
||||
vertexp->clearReducible("SigPublic");
|
||||
|
|
@ -294,7 +294,6 @@ private:
|
|||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
//VV***** We reset userp() and user2p
|
||||
nodep->iterateChildren(*this);
|
||||
//if (debug()>6) m_graph.dump();
|
||||
if (debug()>6) m_graph.dumpDotFilePrefixed("gate_pre");
|
||||
|
|
|
|||
|
|
@ -50,8 +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;
|
||||
AstUser2InUse m_inuser2;
|
||||
AstUser3InUse m_inuser3;
|
||||
|
||||
// STATE
|
||||
AstActive* m_activep; // Inside activate statement
|
||||
|
|
@ -84,7 +84,7 @@ private:
|
|||
|
||||
// VISITORS
|
||||
virtual void visit(AstTopScope* nodep, AstNUser*) {
|
||||
AstNode::user2ClearTree(); // userp() used on entire tree
|
||||
AstNode::user2ClearTree(); // user2p() used on entire tree
|
||||
|
||||
AstScope* scopep = nodep->scopep();
|
||||
if (!scopep) nodep->v3fatalSrc("No scope found on top level");
|
||||
|
|
@ -142,7 +142,7 @@ private:
|
|||
// NODE STATE
|
||||
// Cleared on top scope
|
||||
// AstVarScope::user() -> bool. Set when the var has been used as clock
|
||||
AstUserInUse m_inuse1;
|
||||
AstUser1InUse m_inuser1;
|
||||
|
||||
// STATE
|
||||
AstActive* m_activep; // Inside activate statement
|
||||
|
|
@ -151,7 +151,7 @@ private:
|
|||
|
||||
// VISITORS
|
||||
virtual void visit(AstTopScope* nodep, AstNUser*) {
|
||||
AstNode::userClearTree(); // userp() used on entire tree
|
||||
AstNode::user1ClearTree(); // user1p() used on entire tree
|
||||
nodep->iterateChildren(*this);
|
||||
{
|
||||
// Make the new clock signals and replace any activate references
|
||||
|
|
@ -179,9 +179,9 @@ private:
|
|||
if (!vscp) nodep->v3fatalSrc("Scope not assigned");
|
||||
if (m_activep) {
|
||||
UINFO(8," VarAct "<<nodep<<endl);
|
||||
vscp->user(true);
|
||||
vscp->user1(true);
|
||||
}
|
||||
if (m_assignp && nodep->lvalue() && vscp->user()) {
|
||||
if (m_assignp && nodep->lvalue() && vscp->user1()) {
|
||||
// Variable was previously used as a clock, and is now being set
|
||||
// Thus a unordered generated clock...
|
||||
UINFO(8," VarSetAct "<<nodep<<endl);
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ public:
|
|||
// Hashed class functions
|
||||
|
||||
V3Hashed::V3Hashed() {
|
||||
AstNode::user4ClearTree(); // userp() used on entire tree
|
||||
AstNode::user4ClearTree(); // user4p() used on entire tree
|
||||
}
|
||||
|
||||
void V3Hashed::hashAndInsert(AstNode* nodep) {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
class V3Hashed {
|
||||
// NODE STATE
|
||||
// AstNode::user4() -> V3Hash. Hash value of this node (hash of 0 is illegal)
|
||||
AstUser4InUse m_inuse4;
|
||||
AstUser4InUse m_inuser4;
|
||||
|
||||
// TYPES
|
||||
typedef multimap<V3Hash,AstNode*> HashMmap;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ private:
|
|||
// NODE STATE
|
||||
// Cleared entire netlist
|
||||
// Input:
|
||||
// AstModule::userp() // bool. True to inline this module (from InlineMarkVisitor)
|
||||
// AstModule::user1p() // bool. True to inline this module (from InlineMarkVisitor)
|
||||
// Cleared each cell
|
||||
// AstVar::user2p() // AstVarRef*/AstConst* Points to signal this is a direct connect to
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ private:
|
|||
nodep->name(name);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
if (nodep->modp()->userp()) { // Marked with inline request
|
||||
if (nodep->modp()->user1p()) { // Marked with inline request
|
||||
if (m_cellp) nodep->v3error("Cloning should have already been done bottom-up");
|
||||
UINFO(5," Inline CELL "<<nodep<<endl);
|
||||
UINFO(5," To MOD "<<m_modp<<endl);
|
||||
|
|
@ -282,12 +282,12 @@ class InlineMarkVisitor : public AstNVisitor {
|
|||
private:
|
||||
// NODE STATE
|
||||
// Entire netlist
|
||||
// AstModule::user() // OUTPUT: bool. User request to inline this module
|
||||
// AstModule::user1() // 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;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
AstUser3InUse m_inuser3;
|
||||
|
||||
// STATE
|
||||
AstModule* m_modp; // Current module
|
||||
|
|
@ -310,7 +310,7 @@ private:
|
|||
//
|
||||
nodep->iterateChildren(*this);
|
||||
//
|
||||
bool userinline = nodep->user();
|
||||
bool userinline = nodep->user1();
|
||||
bool allowed = nodep->user2();
|
||||
int refs = nodep->user3();
|
||||
// Should we automatically inline this module?
|
||||
|
|
@ -323,7 +323,7 @@ private:
|
|||
<<" "<<nodep<<endl);
|
||||
if (doit) {
|
||||
UINFO(4," AutoInline "<<nodep<<endl);
|
||||
nodep->user(true);
|
||||
nodep->user1(true);
|
||||
}
|
||||
m_modp = NULL;
|
||||
}
|
||||
|
|
@ -337,7 +337,7 @@ private:
|
|||
if (!m_modp) {
|
||||
nodep->v3error("Inline pragma not under a module");
|
||||
} else {
|
||||
m_modp->user(1);
|
||||
m_modp->user1(1);
|
||||
}
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL; // Remove so don't propagate to upper cell...
|
||||
} else if (nodep->pragType() == AstPragmaType::NO_INLINE_MODULE) {
|
||||
|
|
@ -385,7 +385,7 @@ public:
|
|||
m_modp = NULL;
|
||||
m_stmtCnt = 0;
|
||||
//VV***** We reset all userp() on the whole netlist!!!
|
||||
AstNode::userClearTree();
|
||||
AstNode::user1ClearTree();
|
||||
AstNode::user2ClearTree();
|
||||
AstNode::user3ClearTree();
|
||||
nodep->accept(*this);
|
||||
|
|
@ -406,7 +406,7 @@ void V3Inline::inlineAll(AstNetlist* nodep) {
|
|||
AstModule* nextmodp;
|
||||
for (AstModule* modp = v3Global.rootp()->modulesp(); modp; modp=nextmodp) {
|
||||
nextmodp = modp->nextp()->castModule();
|
||||
if (modp->userp()) { // Was inlined
|
||||
if (modp->user1p()) { // Was inlined
|
||||
modp->unlinkFrBack()->deleteTree(); modp=NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,10 +44,10 @@ class InstVisitor : public AstNVisitor {
|
|||
private:
|
||||
// NODE STATE
|
||||
// Cleared each Cell:
|
||||
// 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;
|
||||
// AstVar::user1p() -> AstNode*. Expression connected to given pin
|
||||
// AstVarRef::user1p() -> bool. True if created senitem for parent's connected signal
|
||||
// AstPin::user1p() -> bool. True if created assignment already
|
||||
AstUser1InUse m_inuser1;
|
||||
|
||||
// STATE
|
||||
AstModule* m_modp; // Current module
|
||||
|
|
@ -67,11 +67,11 @@ private:
|
|||
virtual void visit(AstCell* nodep, AstNUser*) {
|
||||
UINFO(4," CELL "<<nodep<<endl);
|
||||
m_cellp = nodep;
|
||||
//VV***** We reset userp() on each cell!!!
|
||||
AstNode::userClearTree();
|
||||
// Collect pin expressions, so submod->varp->userp() points to expression it connects to
|
||||
//VV***** We reset user1p() on each cell!!!
|
||||
AstNode::user1ClearTree();
|
||||
// Collect pin expressions, so submod->varp->user1p() points to expression it connects to
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||
pinp->modVarp()->userp(pinp->exprp());
|
||||
pinp->modVarp()->user1p(pinp->exprp());
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
m_cellp = NULL;
|
||||
|
|
@ -83,9 +83,9 @@ private:
|
|||
if (debug()>=9) nodep->dumpTree(cout," Pin_oldb: ");
|
||||
if (nodep->modVarp()->isOutOnly() && nodep->exprp()->castConst())
|
||||
nodep->v3error("Output pin is assigned to a constant, electrical short");
|
||||
// Use userp on the PIN to indicate we created an assign for this pin
|
||||
if (!nodep->user()) {
|
||||
nodep->user(1);
|
||||
// Use user1p on the PIN to indicate we created an assign for this pin
|
||||
if (!nodep->user1()) {
|
||||
nodep->user1(1);
|
||||
// Simplify it
|
||||
V3Inst::pinReconnectSimple(nodep, m_cellp, m_modp);
|
||||
// Make a ASSIGNW (expr, pin)
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
class LifeState {
|
||||
// NODE STATE
|
||||
// See below
|
||||
AstUserInUse m_inuse1;
|
||||
AstUser1InUse m_inuser1;
|
||||
|
||||
// STATE
|
||||
public:
|
||||
|
|
@ -117,7 +117,7 @@ public:
|
|||
class LifeBlock {
|
||||
// NODE STATE
|
||||
// Cleared each AstIf:
|
||||
// AstVarScope::user() -> int. Used in combining to detect duplicates
|
||||
// AstVarScope::user1() -> int. Used in combining to detect duplicates
|
||||
|
||||
// LIFE MAP
|
||||
// For each basic block, we'll make a new map of what variables that if/else is changing
|
||||
|
|
@ -229,15 +229,15 @@ public:
|
|||
// Find any common sets on both branches of IF and propagate upwards
|
||||
//life1p->lifeDump();
|
||||
//life2p->lifeDump();
|
||||
AstNode::userClearTree(); // userp() used on entire tree
|
||||
AstNode::user1ClearTree(); // user1p() used on entire tree
|
||||
for (LifeMap::iterator it = life1p->m_map.begin(); it!=life1p->m_map.end(); ++it) {
|
||||
// When the if branch sets a var before it's used, mark that variable
|
||||
if (it->second.setBeforeUse()) it->first->user(1);
|
||||
if (it->second.setBeforeUse()) it->first->user1(1);
|
||||
}
|
||||
for (LifeMap::iterator it = life2p->m_map.begin(); it!=life2p->m_map.end(); ++it) {
|
||||
// When the else branch sets a var before it's used
|
||||
AstVarScope* nodep = it->first;
|
||||
if (it->second.setBeforeUse() && nodep->user()) {
|
||||
if (it->second.setBeforeUse() && nodep->user1()) {
|
||||
// Both branches set the var, we can remove the assignment before the IF.
|
||||
UINFO(4,"DUALBRANCH "<<nodep<<endl);
|
||||
LifeMap::iterator itab = m_map.find(nodep);
|
||||
|
|
|
|||
|
|
@ -98,9 +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;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
AstUser4InUse m_inuser4;
|
||||
|
||||
// STATE
|
||||
uint32_t m_sequence; // Sequence number of assignments/varrefs
|
||||
|
|
@ -108,9 +108,9 @@ private:
|
|||
|
||||
// VISITORS
|
||||
virtual void visit(AstTopScope* nodep, AstNUser*) {
|
||||
AstNode::userClearTree(); // userp() used on entire tree
|
||||
AstNode::user2ClearTree(); // userp() used on entire tree
|
||||
AstNode::user4ClearTree(); // userp() used on entire tree
|
||||
AstNode::user1ClearTree(); // user1p() used on entire tree
|
||||
AstNode::user2ClearTree(); // user2p() used on entire tree
|
||||
AstNode::user4ClearTree(); // user4p() used on entire tree
|
||||
m_sequence = 0;
|
||||
nodep->iterateChildren(*this);
|
||||
|
||||
|
|
@ -125,7 +125,7 @@ private:
|
|||
m_sequence++;
|
||||
if (nodep->lvalue()) {
|
||||
// First generator
|
||||
if (!vscp->user()) vscp->user(m_sequence);
|
||||
if (!vscp->user1()) vscp->user1(m_sequence);
|
||||
} else {
|
||||
// Last consumer
|
||||
vscp->user2(m_sequence);
|
||||
|
|
@ -142,7 +142,7 @@ private:
|
|||
UINFO(9," POST "<<nodep<<endl);
|
||||
UINFO(9," lhs "<<lhsp<<endl);
|
||||
UINFO(9," rhs "<<rhsp<<endl);
|
||||
uint32_t firstWrite = rhsp->varScopep()->user();
|
||||
uint32_t firstWrite = rhsp->varScopep()->user1();
|
||||
uint32_t lastRead = rhsp->varScopep()->user2();
|
||||
uint32_t lastRead2 = lhsp->varScopep()->user2();
|
||||
UINFO(9," first "<<firstWrite<<" last "<<lastRead<<" "<<lastRead2<<endl);
|
||||
|
|
|
|||
|
|
@ -46,13 +46,13 @@ class LinkVisitor : public AstNVisitor {
|
|||
private:
|
||||
// NODE STATE
|
||||
// Entire netlist:
|
||||
// AstModule::userp() // V3SymTable* Module's Symbol table
|
||||
// AstNodeFTask::userp() // V3SymTable* Local Symbol table
|
||||
// AstBegin::userp() // V3SymTable* Local Symbol table
|
||||
// AstVar::userp() // V3SymTable* Table used to create this variable
|
||||
// AstModule::user1p() // V3SymTable* Module's Symbol table
|
||||
// AstNodeFTask::user1p() // V3SymTable* Local Symbol table
|
||||
// AstBegin::user1p() // V3SymTable* Local Symbol table
|
||||
// AstVar::user1p() // V3SymTable* Table used to create this variable
|
||||
// AstVar::user2p() // bool True if port set for this variable
|
||||
AstUserInUse m_inuse1;
|
||||
AstUser2InUse m_inuse2;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
|
||||
// ENUMS
|
||||
enum IdState { // Which loop through the tree
|
||||
|
|
@ -113,7 +113,7 @@ private:
|
|||
for (AstModule* modp = v3Global.rootp()->modulesp(); modp; modp=modp->nextp()->castModule()) {
|
||||
V3SymTable* symp = new V3SymTable(NULL);
|
||||
m_delSymps.push_back(symp);
|
||||
modp->userp(symp);
|
||||
modp->user1p(symp);
|
||||
}
|
||||
// And recurse...
|
||||
m_idState = ID_FIND;
|
||||
|
|
@ -130,7 +130,7 @@ private:
|
|||
UINFO(2,"Link Module: "<<nodep<<endl);
|
||||
m_modp = nodep;
|
||||
// This state must be save/restored in the cell visitor function
|
||||
m_curVarsp = nodep->userp()->castSymTable();
|
||||
m_curVarsp = nodep->user1p()->castSymTable();
|
||||
if (!m_curVarsp) nodep->v3fatalSrc("NULL");
|
||||
m_cellVarsp = NULL;
|
||||
m_paramNum = 0;
|
||||
|
|
@ -163,7 +163,7 @@ private:
|
|||
<<varTextType(findidp)<<": "<<nodep->prettyName());
|
||||
} else if (findvarp != nodep) {
|
||||
UINFO(4,"DupVar: "<<nodep<<" ;; "<<findvarp<<endl);
|
||||
if (findvarp->userp() == m_curVarsp) { // Only when on same level
|
||||
if (findvarp->user1p() == m_curVarsp) { // Only when on same level
|
||||
if ((findvarp->isIO() && nodep->isSignal())
|
||||
|| (findvarp->isSignal() && nodep->isIO())) {
|
||||
findvarp->combineType(nodep);
|
||||
|
|
@ -185,7 +185,7 @@ private:
|
|||
}
|
||||
if (ins) {
|
||||
m_curVarsp->insert(nodep->name(), nodep);
|
||||
nodep->userp(m_curVarsp);
|
||||
nodep->user1p(m_curVarsp);
|
||||
if (nodep->isGParam()) {
|
||||
m_paramNum++;
|
||||
m_curVarsp->insert("__paramNumber"+cvtToStr(m_paramNum), nodep);
|
||||
|
|
@ -220,12 +220,12 @@ private:
|
|||
V3SymTable* upperVarsp = m_curVarsp;
|
||||
{
|
||||
// Create symbol table for the task's vars
|
||||
if (V3SymTable* localVarsp = nodep->userp()->castSymTable()) {
|
||||
if (V3SymTable* localVarsp = nodep->user1p()->castSymTable()) {
|
||||
m_curVarsp = localVarsp;
|
||||
} else {
|
||||
m_curVarsp = new V3SymTable(upperVarsp);
|
||||
m_delSymps.push_back(m_curVarsp);
|
||||
nodep->userp(m_curVarsp);
|
||||
nodep->user1p(m_curVarsp);
|
||||
}
|
||||
// Convert the func's range to the output variable
|
||||
// This should probably be done in the Parser instead, as then we could
|
||||
|
|
@ -278,12 +278,12 @@ private:
|
|||
m_beginNum = 0;
|
||||
{
|
||||
// Create symbol table for the task's vars
|
||||
if (V3SymTable* localVarsp = nodep->userp()->castSymTable()) {
|
||||
if (V3SymTable* localVarsp = nodep->user1p()->castSymTable()) {
|
||||
m_curVarsp = localVarsp;
|
||||
} else {
|
||||
m_curVarsp = new V3SymTable(upperVarsp);
|
||||
m_delSymps.push_back(m_curVarsp);
|
||||
nodep->userp(m_curVarsp);
|
||||
nodep->user1p(m_curVarsp);
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
|
@ -322,7 +322,7 @@ private:
|
|||
}
|
||||
else {
|
||||
// Need to pass the module info to this cell, so we can link up the pin names
|
||||
m_cellVarsp = nodep->modp()->userp()->castSymTable();
|
||||
m_cellVarsp = nodep->modp()->user1p()->castSymTable();
|
||||
UINFO(4,"(Backto) Link Cell: "<<nodep<<endl);
|
||||
//if (debug()) { nodep->dumpTree(cout,"linkcell:"); }
|
||||
//if (debug()) { nodep->modp()->dumpTree(cout,"linkcemd:"); }
|
||||
|
|
|
|||
|
|
@ -86,8 +86,8 @@ class LinkCellsVisitor : public AstNVisitor {
|
|||
private:
|
||||
// NODE STATE
|
||||
// Entire netlist:
|
||||
// AstModule::userp() // V3GraphVertex* Vertex describing this module
|
||||
AstUserInUse m_inuse1;
|
||||
// AstModule::user1p() // V3GraphVertex* Vertex describing this module
|
||||
AstUser1InUse m_inuser1;
|
||||
|
||||
// STATE
|
||||
// Below state needs to be preserved between each module call.
|
||||
|
|
@ -101,15 +101,15 @@ private:
|
|||
// METHODS
|
||||
V3GraphVertex* vertex(AstModule* nodep) {
|
||||
// Return corresponding vertex for this module
|
||||
if (!nodep->userp()) {
|
||||
nodep->userp(new LinkCellsVertex(&m_graph, nodep));
|
||||
if (!nodep->user1p()) {
|
||||
nodep->user1p(new LinkCellsVertex(&m_graph, nodep));
|
||||
}
|
||||
return (nodep->userp()->castGraphVertex());
|
||||
return (nodep->user1p()->castGraphVertex());
|
||||
}
|
||||
|
||||
// VISITs
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
AstNode::userClearTree();
|
||||
AstNode::user1ClearTree();
|
||||
readModNames();
|
||||
nodep->iterateChildren(*this);
|
||||
// Find levels in graph
|
||||
|
|
|
|||
|
|
@ -173,10 +173,10 @@ class LinkDotState {
|
|||
private:
|
||||
// NODE STATE
|
||||
// Cleared on Netlist
|
||||
// AstModule::userp() -> LinkDotCellVertex*. Last cell that uses this module
|
||||
// AstModule::user1p() -> LinkDotCellVertex*. Last cell that uses this module
|
||||
// AstVarScope::user2p() -> AstVarScope*. Base alias for this signal
|
||||
AstUserInUse m_inuse1;
|
||||
AstUser2InUse m_inuse2;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
|
||||
// TYPES
|
||||
typedef std::multimap<string,LinkDotCellVertex*> NameScopeMap;
|
||||
|
|
@ -195,7 +195,7 @@ public:
|
|||
m_forPrearray = forPrearray;
|
||||
m_forScopeCreation = forScopeCreation;
|
||||
//VV***** We reset all userp() on each netlist!!!
|
||||
AstNode::userClearTree();
|
||||
AstNode::user1ClearTree();
|
||||
AstNode::user2ClearTree();
|
||||
}
|
||||
~LinkDotState() {}
|
||||
|
|
@ -207,7 +207,7 @@ public:
|
|||
LinkDotCellVertex* insertTopCell(AstModule* nodep, const string& scopename) {
|
||||
UINFO(9," INSERTcell "<<scopename<<" "<<nodep<<endl);
|
||||
LinkDotCellVertex* vxp = new LinkDotCellVertex(&m_graph, nodep);
|
||||
nodep->userp(vxp);
|
||||
nodep->user1p(vxp);
|
||||
if (forScopeCreation()) m_nameScopeMap.insert(make_pair(scopename, vxp));
|
||||
return vxp;
|
||||
}
|
||||
|
|
@ -215,7 +215,7 @@ public:
|
|||
AstCell* nodep, const string& scopename) {
|
||||
UINFO(9," INSERTcell "<<scopename<<" "<<nodep<<endl);
|
||||
LinkDotCellVertex* vxp = new LinkDotCellVertex(&m_graph, nodep);
|
||||
if (nodep->modp()) nodep->modp()->userp(vxp);
|
||||
if (nodep->modp()) nodep->modp()->user1p(vxp);
|
||||
new V3GraphEdge(&m_graph, abovep, vxp, 1, false);
|
||||
abovep->insertSubcellName(nodep->origName(), vxp);
|
||||
if (abovep != cellVxp) {
|
||||
|
|
@ -250,10 +250,10 @@ public:
|
|||
abovep->syms().insert(name, nodep);
|
||||
}
|
||||
bool existsModScope(AstModule* nodep) {
|
||||
return nodep->userp()!=NULL;
|
||||
return nodep->user1p()!=NULL;
|
||||
}
|
||||
LinkDotCellVertex* findModScope(AstModule* nodep) {
|
||||
LinkDotCellVertex* vxp = (LinkDotCellVertex*)(nodep->userp());
|
||||
LinkDotCellVertex* vxp = (LinkDotCellVertex*)(nodep->user1p());
|
||||
if (!vxp) nodep->v3fatalSrc("Module never assigned a vertex");
|
||||
return vxp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ private:
|
|||
// NODE STATE
|
||||
// Cleared on netlist
|
||||
// AstNode::user() -> bool. True if processed
|
||||
AstUserInUse m_inuse1;
|
||||
AstUser1InUse m_inuser1;
|
||||
|
||||
// STATE
|
||||
string m_dotText; // Dotted module text we are building for a dotted node, passed up
|
||||
|
|
@ -67,8 +67,8 @@ private:
|
|||
|
||||
// VISITs
|
||||
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
|
||||
if (!nodep->user()) {
|
||||
nodep->user(true); // Process only once.
|
||||
if (!nodep->user1()) {
|
||||
nodep->user1(true); // Process only once.
|
||||
UINFO(5," "<<nodep<<endl);
|
||||
checkExpected(nodep);
|
||||
// Due to a need to get the arguments, the ParseRefs are under here,
|
||||
|
|
@ -155,8 +155,8 @@ private:
|
|||
}
|
||||
}
|
||||
virtual void visit(AstSelBit* nodep, AstNUser*) {
|
||||
if (!nodep->user()) {
|
||||
nodep->user(true); // Process only once.
|
||||
if (!nodep->user1()) {
|
||||
nodep->user1(true); // Process only once.
|
||||
if (m_inModDot) { // Already under dot, so this is {modulepart} DOT {modulepart}
|
||||
m_dotText = "";
|
||||
nodep->lhsp()->iterateAndNext(*this);
|
||||
|
|
@ -184,8 +184,8 @@ private:
|
|||
}
|
||||
virtual void visit(AstNodePreSel* nodep, AstNUser*) {
|
||||
// Excludes simple AstSel, see above
|
||||
if (!nodep->user()) {
|
||||
nodep->user(true); // Process only once.
|
||||
if (!nodep->user1()) {
|
||||
nodep->user1(true); // Process only once.
|
||||
if (m_inModDot) { // Already under dot, so this is {modulepart} DOT {modulepart}
|
||||
nodep->v3error("Syntax Error: Range ':', '+:' etc are not allowed in the cell part of a dotted reference");
|
||||
} else if (m_exp==AstParseRefExp::FUNC) {
|
||||
|
|
@ -207,8 +207,8 @@ private:
|
|||
}
|
||||
}
|
||||
virtual void visit(AstText* nodep, AstNUser*) {
|
||||
if (!nodep->user()) {
|
||||
nodep->user(true); // Process only once.
|
||||
if (!nodep->user1()) {
|
||||
nodep->user1(true); // Process only once.
|
||||
if (m_exp != AstParseRefExp::NONE) {
|
||||
UINFO(7," "<<nodep<<endl);
|
||||
if (m_inModDot) { // Dotted part, just pass up
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ private:
|
|||
// NODE STATE
|
||||
// Entire netlist:
|
||||
// AstCaseItem::user2() // bool Moved default caseitems
|
||||
AstUser2InUse m_inuse2;
|
||||
AstUser2InUse m_inuser2;
|
||||
|
||||
// STATE
|
||||
// Below state needs to be preserved between each module call.
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class LocalizeBaseVisitor : public AstNVisitor {
|
|||
protected:
|
||||
// NODE STATE
|
||||
// Cleared on entire tree
|
||||
// AstVar::userp() -> CFunc which references the variable
|
||||
// AstVar::user1p() -> CFunc which references the variable
|
||||
// AstVar::user2() -> VarFlags. Flag state
|
||||
// AstVar::user4() -> AstVarRef*. First place signal set; must be first assignment
|
||||
|
||||
|
|
@ -101,9 +101,9 @@ class LocalizeVisitor : public LocalizeBaseVisitor {
|
|||
private:
|
||||
// NODE STATE/TYPES
|
||||
// See above
|
||||
AstUserInUse m_inuse1;
|
||||
AstUser2InUse m_inuse2;
|
||||
AstUser4InUse m_inuse4;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
AstUser4InUse m_inuser4;
|
||||
|
||||
// STATE
|
||||
V3Double0 m_statLocVars; // Statistic tracking
|
||||
|
|
@ -132,11 +132,11 @@ private:
|
|||
if ((nodep->isMovableToBlock() // Blocktemp
|
||||
|| !flags.m_notStd) // Or used only in block
|
||||
&& !flags.m_notOpt // Optimizable
|
||||
&& nodep->userp()) { // Single cfunc
|
||||
&& 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 "<<nodep<<endl);
|
||||
m_statLocVars++;
|
||||
AstCFunc* newfuncp = nodep->userp()->castNode()->castCFunc();
|
||||
AstCFunc* newfuncp = nodep->user1p()->castNode()->castCFunc();
|
||||
nodep->unlinkFrBack();
|
||||
newfuncp->addInitsp(nodep);
|
||||
// Done
|
||||
|
|
@ -151,9 +151,6 @@ private:
|
|||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
AstNode::userClearTree(); // userp() used on entire tree
|
||||
AstNode::user2ClearTree(); // userp() used on entire tree
|
||||
AstNode::user4ClearTree(); // userp() used on entire tree
|
||||
nodep->iterateChildren(*this);
|
||||
moveVars();
|
||||
}
|
||||
|
|
@ -210,10 +207,10 @@ private:
|
|||
// If we're scoping down to it, it isn't really in the same block
|
||||
if (!nodep->hierThis()) clearOptimizable(nodep->varp(),"HierRef");
|
||||
// Allow a variable to appear in only a single function
|
||||
AstNode* oldfunc = nodep->varp()->userp()->castNode();
|
||||
AstNode* oldfunc = nodep->varp()->user1p()->castNode();
|
||||
if (!oldfunc) {
|
||||
UINFO(4," BVnewref "<<nodep<<endl);
|
||||
nodep->varp()->userp(m_cfuncp); // Remember where it was used
|
||||
nodep->varp()->user1p(m_cfuncp); // Remember where it was used
|
||||
} else if (m_cfuncp == oldfunc) {
|
||||
// Same usage
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -41,14 +41,14 @@ class NameVisitor : public AstNVisitor {
|
|||
private:
|
||||
// NODE STATE
|
||||
// Cleared on Netlist
|
||||
// AstCell::user() -> bool. Set true if already processed
|
||||
// AstScope::user() -> bool. Set true if already processed
|
||||
// AstVar::user() -> bool. Set true if already processed
|
||||
// AstCell::user1() -> bool. Set true if already processed
|
||||
// AstScope::user1() -> bool. Set true if already processed
|
||||
// AstVar::user1() -> bool. Set true if already processed
|
||||
//
|
||||
// AstCell::user2() -> bool. Set true if was privitized
|
||||
// AstVar::user2() -> bool. Set true if was privitized
|
||||
AstUserInUse m_inuse1;
|
||||
AstUser2InUse m_inuse2;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
|
||||
// STATE
|
||||
AstModule* m_modp;
|
||||
|
|
@ -64,14 +64,14 @@ private:
|
|||
// Add __PVT__ to names of local signals
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {
|
||||
// Don't iterate... Don't need temps for RANGES under the Var.
|
||||
if (!nodep->user()
|
||||
if (!nodep->user1()
|
||||
&& !m_modp->isTop()
|
||||
&& !nodep->isSigPublic()
|
||||
&& !nodep->isTemp()) { // Don't bother to rename internal signals
|
||||
// Change the name to something private...
|
||||
string newname = (string)"__PVT__"+nodep->name();
|
||||
nodep->name(newname);
|
||||
nodep->user(1);
|
||||
nodep->user1(1);
|
||||
nodep->user2(1);
|
||||
}
|
||||
}
|
||||
|
|
@ -82,25 +82,25 @@ private:
|
|||
}
|
||||
}
|
||||
virtual void visit(AstCell* nodep, AstNUser*) {
|
||||
if (!nodep->user()
|
||||
if (!nodep->user1()
|
||||
&& !nodep->modp()->modPublic()) {
|
||||
// Change the name to something private...
|
||||
string newname = (string)"__PVT__"+nodep->name();
|
||||
nodep->name(newname);
|
||||
nodep->user(1);
|
||||
nodep->user1(1);
|
||||
nodep->user2(1);
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||
if (!nodep->user()) {
|
||||
if (!nodep->user1()) {
|
||||
if (nodep->aboveScopep()) nodep->aboveScopep()->iterateChildren(*this);
|
||||
nodep->aboveCellp()->iterateChildren(*this);
|
||||
// Always recompute name (as many level above scope may have changed)
|
||||
// Same formula as V3Scope
|
||||
nodep->name(nodep->isTop() ? "TOP"
|
||||
: (nodep->aboveScopep()->name()+"."+nodep->aboveCellp()->name()));
|
||||
nodep->user(1);
|
||||
nodep->user1(1);
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -188,14 +188,14 @@ inline ostream& operator<< (ostream& lhs, const OrderMoveDomScope& rhs) {
|
|||
}
|
||||
|
||||
//######################################################################
|
||||
// Order information stored under each AstNode::userp()...
|
||||
// Order information stored under each AstNode::user1p()...
|
||||
|
||||
// Types of vertex we can create
|
||||
enum WhichVertex { WV_STD, WV_PRE, WV_PORD, WV_POST, WV_SETL,
|
||||
WV_MAX};
|
||||
|
||||
class OrderUser {
|
||||
// Stored in AstVarScope::userp, a list of all the various vertices
|
||||
// Stored in AstVarScope::user1p, a list of all the various vertices
|
||||
// that can exist for one given variable
|
||||
private:
|
||||
OrderVarVertex* m_vertexp[WV_MAX]; // Vertex of each type (if non NULL)
|
||||
|
|
@ -239,17 +239,17 @@ private:
|
|||
// NODE STATE
|
||||
// Forming graph:
|
||||
// Entire Netlist:
|
||||
// AstVarScope::userp -> OrderUser* for usage var
|
||||
// {statement}Node::userp-> AstModule* statement is under
|
||||
// AstVarScope::user1p -> OrderUser* for usage var
|
||||
// {statement}Node::user1p-> AstModule* statement is under
|
||||
// USER4 Cleared on each Logic stmt
|
||||
// AstVarScope::user4() -> VarUsage(gen/con/both). Where already encountered signal
|
||||
// Ordering (user3/4/5 cleared between forming and ordering)
|
||||
// AstScope::userp() -> AstModule*. Module this scope is under
|
||||
// AstScope::user1p() -> AstModule*. Module this scope is under
|
||||
// AstModule::user3() -> Number of routines created
|
||||
AstUserInUse m_inuse;
|
||||
AstUser2InUse m_inuse2;
|
||||
AstUser3InUse m_inuse3;
|
||||
AstUser4InUse m_inuse4;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
AstUser3InUse m_inuser3;
|
||||
AstUser4InUse m_inuser4;
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
|
|
@ -308,19 +308,19 @@ private:
|
|||
// Add edge logic_sensitive_vertex->logic_vertex
|
||||
new OrderEdge(&m_graph, m_activeSenVxp, m_logicVxp, WEIGHT_NORMAL);
|
||||
}
|
||||
nodep->userp(m_modp);
|
||||
nodep->user1p(m_modp);
|
||||
nodep->iterateChildren(*this);
|
||||
m_logicVxp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
OrderVarVertex* newVarUserVertex(AstVarScope* varscp, WhichVertex type, bool* createdp=NULL) {
|
||||
if (!varscp->userp()) {
|
||||
if (!varscp->user1p()) {
|
||||
OrderUser* newup = new OrderUser();
|
||||
m_orderUserps.push_back(newup);
|
||||
varscp->userp(newup);
|
||||
varscp->user1p(newup);
|
||||
}
|
||||
OrderUser* up = (OrderUser*)(varscp->userp());
|
||||
OrderUser* up = (OrderUser*)(varscp->user1p());
|
||||
return up->newVarUserVertex(&m_graph, m_scopep, varscp, type, createdp);
|
||||
}
|
||||
|
||||
|
|
@ -424,7 +424,7 @@ private:
|
|||
if (m_topScopep) { process(); m_topScopep=NULL; }
|
||||
UINFO(2," Loading tree...\n");
|
||||
//VV***** We reset userp()
|
||||
AstNode::userClearTree();
|
||||
AstNode::user1ClearTree();
|
||||
AstNode::user3ClearTree();
|
||||
m_graph.clear();
|
||||
m_activep = NULL;
|
||||
|
|
@ -458,7 +458,7 @@ private:
|
|||
//
|
||||
nodep->iterateChildren(*this);
|
||||
// Done topscope, erase extra user information
|
||||
// userp passed to next process() operation
|
||||
// user1p passed to next process() operation
|
||||
AstNode::user3ClearTree();
|
||||
AstNode::user4ClearTree();
|
||||
}
|
||||
|
|
@ -472,7 +472,7 @@ private:
|
|||
m_scopep = nodep;
|
||||
m_logicVxp = NULL;
|
||||
m_activeSenVxp = NULL;
|
||||
nodep->userp(m_modp);
|
||||
nodep->user1p(m_modp);
|
||||
// Iterate
|
||||
nodep->iterateChildren(*this);
|
||||
m_scopep = NULL;
|
||||
|
|
@ -1372,7 +1372,7 @@ void OrderVisitor::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* d
|
|||
<<" s="<<(void*)(scopep)<<" "<<lvertexp<<endl);
|
||||
AstSenTree* domainp = lvertexp->domainp();
|
||||
AstNode* nodep = lvertexp->nodep();
|
||||
AstModule* modp = scopep->userp()->castNode()->castModule(); UASSERT(modp,"NULL"); // Stashed by visitor func
|
||||
AstModule* modp = scopep->user1p()->castNode()->castModule(); UASSERT(modp,"NULL"); // Stashed by visitor func
|
||||
if (nodep->castUntilStable()) {
|
||||
#ifdef NEW_ORDERING
|
||||
// Beginning of loop.
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ private:
|
|||
// NODE STATE
|
||||
// AstModule::user4() // bool True if parameters numbered
|
||||
// AstVar::user4() // int Global parameter number (for naming new module)
|
||||
AstUser4InUse m_inuse4;
|
||||
AstUser4InUse m_inuser4;
|
||||
|
||||
// STATE
|
||||
typedef std::map<AstVar*,AstVar*> VarCloneMap;
|
||||
|
|
|
|||
|
|
@ -49,8 +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;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
|
||||
// STATE
|
||||
AstModule* m_modp; // Current module
|
||||
|
|
@ -76,9 +76,9 @@ private:
|
|||
// ARRAYSEL(*here*, ...) (No wides can be in any argument but first, so we don't check which arg is wide)
|
||||
// ASSIGN(x, SEL*HERE*(ARRAYSEL()...) (m_assignLhs==true handles this.)
|
||||
//UINFO(9, " Check: "<<nodep<<endl);
|
||||
//UINFO(9, " Detail stmtp="<<(m_stmtp?"Y":"N")<<" U="<<(nodep->user()?"Y":"N")<<" IW "<<(nodep->isWide()?"Y":"N")<<endl);
|
||||
//UINFO(9, " Detail stmtp="<<(m_stmtp?"Y":"N")<<" U="<<(nodep->user1()?"Y":"N")<<" IW "<<(nodep->isWide()?"Y":"N")<<endl);
|
||||
if (m_stmtp
|
||||
&& !nodep->user()) { // Not already done
|
||||
&& !nodep->user1()) { // Not already done
|
||||
if (nodep->isWide()) { // Else might be cell interconnect or something
|
||||
if (m_assignLhs) {
|
||||
} else if (nodep->firstAbovep()
|
||||
|
|
@ -135,7 +135,7 @@ private:
|
|||
nodep);
|
||||
insertBeforeStmt(assp);
|
||||
if (debug()>8) assp->dumpTree(cout,"deepou:");
|
||||
nodep->user(true); // Don't add another assignment
|
||||
nodep->user1(true); // Don't add another assignment
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
|
|
|
|||
|
|
@ -44,10 +44,10 @@
|
|||
class ScopeVisitor : public AstNVisitor {
|
||||
private:
|
||||
// NODE STATE
|
||||
// AstVar::userp -> AstVarScope replacement for this variable
|
||||
// AstVar::user1p -> AstVarScope replacement for this variable
|
||||
// AstVarRef::user2p -> bool. True indicates already processed
|
||||
AstUserInUse m_inuse;
|
||||
AstUser2InUse m_inuse2;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
|
||||
// STATE, inside processing a single module
|
||||
AstModule* m_modp; // Current module
|
||||
|
|
@ -74,7 +74,7 @@ private:
|
|||
: (m_aboveScopep->name()+"."+m_aboveCellp->name()));
|
||||
|
||||
UINFO(4," MOD AT "<<scopename<<" "<<nodep<<endl);
|
||||
AstNode::userClearTree();
|
||||
AstNode::user1ClearTree();
|
||||
|
||||
m_scopep = new AstScope((m_aboveCellp?(AstNode*)m_aboveCellp:(AstNode*)nodep)->fileline(),
|
||||
nodep, scopename, m_aboveScopep, m_aboveCellp);
|
||||
|
|
@ -101,7 +101,7 @@ private:
|
|||
|
||||
// Create scope for the current usage of this module
|
||||
UINFO(4," back AT "<<scopename<<" "<<nodep<<endl);
|
||||
AstNode::userClearTree();
|
||||
AstNode::user1ClearTree();
|
||||
m_modp = nodep;
|
||||
if (m_modp->isTop()) {
|
||||
AstTopScope* topscp = new AstTopScope(nodep->fileline(), m_scopep);
|
||||
|
|
@ -173,19 +173,19 @@ private:
|
|||
}
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {
|
||||
// Make new scope variable
|
||||
if (!nodep->userp()) {
|
||||
if (!nodep->user1p()) {
|
||||
AstVarScope* varscp = new AstVarScope(nodep->fileline(), m_scopep, nodep);
|
||||
UINFO(6," New scope "<<varscp<<endl);
|
||||
nodep->userp(varscp);
|
||||
nodep->user1p(varscp);
|
||||
m_scopep->addVarp(varscp);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
// VarRef needs to point to VarScope
|
||||
// Make sure variable has made userp.
|
||||
// Make sure variable has made user1p.
|
||||
if (!nodep->user2()) {
|
||||
nodep->varp()->accept(*this);
|
||||
AstVarScope* varscp = (AstVarScope*)nodep->varp()->userp();
|
||||
AstVarScope* varscp = (AstVarScope*)nodep->varp()->user1p();
|
||||
if (!varscp) nodep->v3fatalSrc("Can't locate varref scope");
|
||||
nodep->varScopep(varscp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -214,14 +214,14 @@ public:
|
|||
class SplitVisitor : public AstNVisitor {
|
||||
private:
|
||||
// NODE STATE
|
||||
// AstVarScope::userp -> Var SplitNodeVertex* for usage var, 0=not set yet
|
||||
// AstVarScope::user1p -> Var SplitNodeVertex* for usage var, 0=not set yet
|
||||
// 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;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
AstUser3InUse m_inuser3;
|
||||
AstUser4InUse m_inuser4;
|
||||
|
||||
// TYPES
|
||||
typedef vector<SplitLogicVertex*> VStack;
|
||||
|
|
@ -239,12 +239,12 @@ private:
|
|||
|
||||
// METHODS
|
||||
void scoreboardClear() {
|
||||
//VV***** We reset userp() and user2p on each block!!!
|
||||
//VV***** We reset user1p() and user2p on each block!!!
|
||||
m_inDly = false;
|
||||
m_graph.clear();
|
||||
m_stmtStackps.clear();
|
||||
m_pliVertexp = NULL;
|
||||
AstNode::userClearTree();
|
||||
AstNode::user1ClearTree();
|
||||
AstNode::user2ClearTree();
|
||||
AstNode::user3ClearTree();
|
||||
AstNode::user4ClearTree();
|
||||
|
|
@ -492,11 +492,11 @@ private:
|
|||
}
|
||||
|
||||
// Create vertexes for variable
|
||||
if (!vscp->userp()) {
|
||||
if (!vscp->user1p()) {
|
||||
SplitVarStdVertex* vstdp = new SplitVarStdVertex(&m_graph, vscp);
|
||||
vscp->userp(vstdp);
|
||||
vscp->user1p(vstdp);
|
||||
}
|
||||
SplitVarStdVertex* vstdp = (SplitVarStdVertex*) vscp->userp();
|
||||
SplitVarStdVertex* vstdp = (SplitVarStdVertex*) vscp->user1p();
|
||||
|
||||
// SPEEDUP: We add duplicate edges, that should be fixed
|
||||
if (m_inDly && nodep->lvalue()) {
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ class SplitAsVisitor : public SplitAsBaseVisitor {
|
|||
private:
|
||||
// NODE STATE
|
||||
// AstAlways::user() -> bool. True if already processed
|
||||
AstUserInUse m_inuse;
|
||||
AstUser1InUse m_inuser1;
|
||||
|
||||
// STATE
|
||||
V3Double0 m_statSplits; // Statistic tracking
|
||||
|
|
@ -151,7 +151,7 @@ private:
|
|||
if (debug()>=9) nodep->dumpTree(cout,"-in : ");
|
||||
// Duplicate it and link in
|
||||
AstAlways* newp = nodep->cloneTree(false);
|
||||
newp->user(true); // So we don't clone it again
|
||||
newp->user1(true); // So we don't clone it again
|
||||
nodep->addNextHere(newp);
|
||||
{ // Delete stuff we don't want in old
|
||||
SplitAsCleanVisitor visitor (nodep, m_splitVscp, false);
|
||||
|
|
@ -167,7 +167,7 @@ private:
|
|||
// Are there any lvalue references below this?
|
||||
// There could be more than one. So, we process the first one found first.
|
||||
AstVarScope* lastSplitVscp = NULL;
|
||||
while (!nodep->user()) {
|
||||
while (!nodep->user1()) {
|
||||
// Find any splittable variables
|
||||
SplitAsFindVisitor visitor (nodep);
|
||||
m_splitVscp = visitor.splitVscp();
|
||||
|
|
@ -182,7 +182,7 @@ private:
|
|||
splitAlways(nodep);
|
||||
m_statSplits++;
|
||||
} else {
|
||||
nodep->user(true);
|
||||
nodep->user1(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -198,7 +198,7 @@ public:
|
|||
// CONSTUCTORS
|
||||
SplitAsVisitor(AstNetlist* nodep) {
|
||||
m_splitVscp = NULL;
|
||||
AstNode::userClearTree(); // userp() used on entire tree
|
||||
AstNode::user1ClearTree(); // user1p() used on entire tree
|
||||
nodep->accept(*this);
|
||||
}
|
||||
virtual ~SplitAsVisitor() {
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ private:
|
|||
|
||||
// METHODS
|
||||
SubstVarEntry* findEntryp(AstVarRef* nodep) {
|
||||
return (SubstVarEntry*)(nodep->varp()->userp()); // Might be NULL
|
||||
return (SubstVarEntry*)(nodep->varp()->user1p()); // Might be NULL
|
||||
}
|
||||
// VISITORS
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
|
|
@ -228,10 +228,10 @@ class SubstVisitor : public SubstBaseVisitor {
|
|||
private:
|
||||
// NODE STATE
|
||||
// Passed to SubstUseVisitor
|
||||
// AstVar::userp -> SubstVar* for usage var, 0=not set yet
|
||||
// AstVar::user1p -> 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;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
|
||||
// STATE
|
||||
vector<SubstVarEntry*> m_entryps; // Nodes to delete when we are finished
|
||||
|
|
@ -244,13 +244,13 @@ private:
|
|||
|
||||
// METHODS
|
||||
SubstVarEntry* getEntryp(AstVarRef* nodep) {
|
||||
if (!nodep->varp()->userp()) {
|
||||
if (!nodep->varp()->user1p()) {
|
||||
SubstVarEntry* entryp = new SubstVarEntry (nodep->varp());
|
||||
m_entryps.push_back(entryp);
|
||||
nodep->varp()->userp(entryp);
|
||||
nodep->varp()->user1p(entryp);
|
||||
return entryp;
|
||||
} else {
|
||||
SubstVarEntry* entryp = (SubstVarEntry*)(nodep->varp()->userp());
|
||||
SubstVarEntry* entryp = (SubstVarEntry*)(nodep->varp()->user1p());
|
||||
return entryp;
|
||||
}
|
||||
}
|
||||
|
|
@ -373,7 +373,7 @@ private:
|
|||
public:
|
||||
// CONSTUCTORS
|
||||
SubstVisitor(AstNode* nodep) {
|
||||
AstNode::userClearTree(); // userp() used on entire tree
|
||||
AstNode::user1ClearTree(); // user1p() used on entire tree
|
||||
AstNode::user2ClearTree(); // user2p() used on entire tree
|
||||
m_ops = 0;
|
||||
m_assignStep = 0;
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ private:
|
|||
// NODE STATE
|
||||
// Cleared on each always/assignw
|
||||
// Checking:
|
||||
// AstVarScope::user() -> VarUsage. Set true to indicate tracking as lvalue/rvalue
|
||||
// AstVarScope::user1() -> VarUsage. Set true to indicate tracking as lvalue/rvalue
|
||||
// Simulating:
|
||||
// AstVarScope::user3() -> V3Number*. Value of variable or node
|
||||
// AstVarScope::user4() -> V3Number*. Last value output was set to
|
||||
|
|
@ -178,21 +178,21 @@ private:
|
|||
if (nodep->varp()->arraysp()) clearOptimizable(nodep,"Array references");
|
||||
if (nodep->lvalue()) {
|
||||
if (m_inDlyAssign) {
|
||||
if (!(vscp->user() & VU_LVDLY)) {
|
||||
vscp->user( vscp->user() | VU_LVDLY);
|
||||
if (!(vscp->user1() & VU_LVDLY)) {
|
||||
vscp->user1( vscp->user1() | VU_LVDLY);
|
||||
varRefCb (nodep);
|
||||
}
|
||||
} else { // nondly asn
|
||||
if (!(vscp->user() & VU_LV)) {
|
||||
if (vscp->user() & VU_RV) clearOptimizable(nodep,"Var read & write");
|
||||
vscp->user( vscp->user() | VU_LV);
|
||||
if (!(vscp->user1() & VU_LV)) {
|
||||
if (vscp->user1() & VU_RV) clearOptimizable(nodep,"Var read & write");
|
||||
vscp->user1( vscp->user1() | VU_LV);
|
||||
varRefCb (nodep);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!(vscp->user() & VU_RV)) {
|
||||
if (vscp->user() & VU_LV) clearOptimizable(nodep,"Var write & read");
|
||||
vscp->user( vscp->user() | VU_RV);
|
||||
if (!(vscp->user1() & VU_RV)) {
|
||||
if (vscp->user1() & VU_LV) clearOptimizable(nodep,"Var write & read");
|
||||
vscp->user1( vscp->user1() | VU_RV);
|
||||
varRefCb (nodep);
|
||||
}
|
||||
}
|
||||
|
|
@ -341,7 +341,7 @@ public:
|
|||
m_instrCount = 0;
|
||||
m_dataCount = 0;
|
||||
|
||||
AstNode::userClearTree(); // userp() used on entire tree
|
||||
AstNode::user1ClearTree(); // user1p() used on entire tree
|
||||
AstNode::user3ClearTree(); // user3p() used on entire tree
|
||||
AstNode::user4ClearTree(); // user4p() used on entire tree
|
||||
|
||||
|
|
@ -368,10 +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;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
AstUser3InUse m_inuser3;
|
||||
AstUser4InUse m_inuser4;
|
||||
|
||||
// STATE
|
||||
double m_totalBytes; // Total bytes in tables created
|
||||
|
|
|
|||
|
|
@ -104,8 +104,8 @@ private:
|
|||
// AstNodeFTask::user4p // GraphFTaskVertex* this FTask is under
|
||||
// AstVar::user4p // GraphFTaskVertex* this variable is declared in
|
||||
|
||||
AstUser3InUse m_inuse3;
|
||||
AstUser4InUse m_inuse4;
|
||||
AstUser3InUse m_inuser3;
|
||||
AstUser4InUse m_inuser4;
|
||||
|
||||
// TYPES
|
||||
typedef std::map<pair<AstScope*,AstVar*>,AstVarScope*> VarToScopeMap;
|
||||
|
|
@ -297,8 +297,8 @@ private:
|
|||
// to TaskRelinkVisitor:
|
||||
// AstVar::user2p // AstVarScope* to replace varref with
|
||||
|
||||
AstUserInUse m_inuse;
|
||||
AstUser2InUse m_inuse2;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
|
||||
// TYPES
|
||||
enum InsertMode {
|
||||
|
|
@ -689,9 +689,9 @@ private:
|
|||
AstNode* prevInsStmtp = m_insStmtp;
|
||||
m_insMode = IM_BEFORE;
|
||||
m_insStmtp = nodep->stmtsp(); // Might be null if no statements, but we won't use it
|
||||
if (!nodep->user()) {
|
||||
if (!nodep->user1()) {
|
||||
// Expand functions in it
|
||||
nodep->user(true);
|
||||
nodep->user1(true);
|
||||
if (nodep->taskPublic()) {
|
||||
// Clone it first, because we may have later FTaskRef's that still need
|
||||
// the original version.
|
||||
|
|
@ -771,7 +771,7 @@ public:
|
|||
m_modp = NULL;
|
||||
m_scopep = NULL;
|
||||
m_insStmtp = NULL;
|
||||
AstNode::userClearTree();
|
||||
AstNode::user1ClearTree();
|
||||
nodep->accept(*this);
|
||||
}
|
||||
virtual ~TaskVisitor() {}
|
||||
|
|
|
|||
|
|
@ -155,14 +155,14 @@ private:
|
|||
// V3Hashed
|
||||
// Ast*::user4() // V3Hashed calculation
|
||||
// Cleared entire netlist
|
||||
// AstCFunc::user() // V3GraphVertex* for this node
|
||||
// AstTraceInc::user() // V3GraphVertex* for this node
|
||||
// AstVarScope::user() // V3GraphVertex* for this node
|
||||
// AstCFunc::user1() // V3GraphVertex* for this node
|
||||
// AstTraceInc::user1() // V3GraphVertex* for this node
|
||||
// AstVarScope::user1() // 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;
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
AstUser3InUse m_inuser3;
|
||||
//AstUser4InUse In V3Hashed
|
||||
|
||||
// STATE
|
||||
|
|
@ -216,7 +216,7 @@ private:
|
|||
if (dupit != hashed.end()) {
|
||||
AstTraceInc* dupincp = hashed.iteratorNodep(dupit)->backp()->castTraceInc();
|
||||
if (!dupincp) nodep->v3fatalSrc("Trace duplicate of wrong type");
|
||||
TraceTraceVertex* dupvertexp = dynamic_cast<TraceTraceVertex*>(dupincp->userp()->castGraphVertex());
|
||||
TraceTraceVertex* dupvertexp = dynamic_cast<TraceTraceVertex*>(dupincp->user1p()->castGraphVertex());
|
||||
UINFO(8," Orig "<<nodep<<endl);
|
||||
UINFO(8," dup "<<dupincp<<endl);
|
||||
// Mark the found node as a duplicate of the first node
|
||||
|
|
@ -533,10 +533,10 @@ private:
|
|||
}
|
||||
|
||||
TraceCFuncVertex* getCFuncVertexp(AstCFunc* nodep) {
|
||||
TraceCFuncVertex* vertexp = dynamic_cast<TraceCFuncVertex*>(nodep->userp()->castGraphVertex());
|
||||
TraceCFuncVertex* vertexp = dynamic_cast<TraceCFuncVertex*>(nodep->user1p()->castGraphVertex());
|
||||
if (!vertexp) {
|
||||
vertexp = new TraceCFuncVertex(&m_graph, nodep);
|
||||
nodep->userp(vertexp);
|
||||
nodep->user1p(vertexp);
|
||||
}
|
||||
return vertexp;
|
||||
}
|
||||
|
|
@ -635,7 +635,7 @@ private:
|
|||
nodep->unlinkFrBack();
|
||||
|
||||
V3GraphVertex* vertexp = new TraceTraceVertex(&m_graph, nodep);
|
||||
nodep->userp(vertexp);
|
||||
nodep->user1p(vertexp);
|
||||
|
||||
if (!m_funcp || (!m_chgFuncp || !m_fullFuncp)) nodep->v3fatalSrc("Trace not under func");
|
||||
m_tracep = nodep;
|
||||
|
|
@ -646,12 +646,12 @@ private:
|
|||
if (m_tracep) {
|
||||
if (!nodep->varScopep()) nodep->v3fatalSrc("No var scope?");
|
||||
if (nodep->lvalue()) nodep->v3fatalSrc("Lvalue in trace? Should be const.");
|
||||
V3GraphVertex* varVtxp = nodep->varScopep()->userp()->castGraphVertex();
|
||||
V3GraphVertex* varVtxp = nodep->varScopep()->user1p()->castGraphVertex();
|
||||
if (!varVtxp) {
|
||||
varVtxp = new TraceVarVertex(&m_graph, nodep->varScopep());
|
||||
nodep->varScopep()->userp(varVtxp);
|
||||
nodep->varScopep()->user1p(varVtxp);
|
||||
}
|
||||
V3GraphVertex* traceVtxp = m_tracep->userp()->castGraphVertex();
|
||||
V3GraphVertex* traceVtxp = m_tracep->user1p()->castGraphVertex();
|
||||
new V3GraphEdge(&m_graph, varVtxp, traceVtxp, 1);
|
||||
if (nodep->varp()->isPrimaryIn() // Always need to trace primary inputs
|
||||
|| nodep->varp()->isSigPublic()) { // Or ones user can change
|
||||
|
|
@ -661,7 +661,7 @@ private:
|
|||
else if (m_funcp && m_finding && nodep->lvalue()) {
|
||||
if (!nodep->varScopep()) nodep->v3fatalSrc("No var scope?");
|
||||
V3GraphVertex* funcVtxp = getCFuncVertexp(m_funcp);
|
||||
V3GraphVertex* varVtxp = nodep->varScopep()->userp()->castGraphVertex();
|
||||
V3GraphVertex* varVtxp = nodep->varScopep()->user1p()->castGraphVertex();
|
||||
if (varVtxp) { // else we're not tracing this signal
|
||||
new V3GraphEdge(&m_graph, funcVtxp, varVtxp, 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ private:
|
|||
// NODE STATE
|
||||
// Cleared on Netlist
|
||||
// AstArraySel::user() -> bool. Set true if already processed
|
||||
AstUserInUse m_inuse;
|
||||
AstUser1InUse m_inuser1;
|
||||
|
||||
// STATE
|
||||
AstModule* m_modp; // Current module
|
||||
|
|
@ -227,8 +227,8 @@ private:
|
|||
|
||||
void visit(AstSel* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (!nodep->user()) {
|
||||
nodep->user(1);
|
||||
if (!nodep->user1()) {
|
||||
nodep->user1(1);
|
||||
// Guard against reading/writing past end of bit vector array
|
||||
int maxmsb = 0;
|
||||
bool lvalue = false;
|
||||
|
|
@ -295,8 +295,8 @@ private:
|
|||
|
||||
virtual void visit(AstArraySel* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (!nodep->user()) {
|
||||
nodep->user(1);
|
||||
if (!nodep->user1()) {
|
||||
nodep->user1(1);
|
||||
// Guard against reading/writing past end of arrays
|
||||
AstNode* basefromp = AstArraySel::baseFromp(nodep->fromp());
|
||||
int dimension = AstArraySel::dimension(nodep->fromp());
|
||||
|
|
|
|||
Loading…
Reference in New Issue