Internals: Convert AstNUser to non-pointer to avoid NULL call. No functional change intended.

This commit is contained in:
Wilson Snyder 2016-11-27 09:40:12 -05:00
parent 7efa40966a
commit 2d0084308d
24 changed files with 187 additions and 164 deletions

View File

@ -80,15 +80,15 @@ void AstNode::init() {
// Attributes
m_didWidth = false;
m_doingWidth = false;
m_user1p = NULL;
m_user1u = VNUser(0);
m_user1Cnt = 0;
m_user2p = NULL;
m_user2u = VNUser(0);
m_user2Cnt = 0;
m_user3p = NULL;
m_user3u = VNUser(0);
m_user3Cnt = 0;
m_user4p = NULL;
m_user4u = VNUser(0);
m_user4Cnt = 0;
m_user5p = NULL;
m_user5u = VNUser(0);
m_user5Cnt = 0;
}

View File

@ -715,7 +715,7 @@ struct VBasicTypeKey {
};
//######################################################################
// AstNUser - Generic pointer base class for AST User nodes.
// AstNUser - Generic base class for AST User nodes.
// - Also used to allow parameter passing up/down iterate calls
class WidthVP;
@ -724,26 +724,30 @@ class OrderBlockNU;
class OrderVarNU;
class V3GraphVertex;
class VSymEnt;
struct AstNUser {
AstNUser* p() { return this; } // So can take address of temporary: iterate(...,AstNUser(args).p())
class VNUser {
union {
void* up;
int ui;
} m_u;
public:
VNUser() {}
VNUser(int i) { m_u.up = 0; m_u.ui = i; }
VNUser(void* p) { m_u.up = p; }
~VNUser() {}
// Casters
WidthVP* c() { return ((WidthVP*)this); }
LinkVP* castLinkVP() { return ((LinkVP*)this); }
VSymEnt* castSymEnt() { return ((VSymEnt*)this); }
AstNode* castNode() { return ((AstNode*)this); }
OrderBlockNU* castOrderBlock() { return ((OrderBlockNU*)this); }
OrderVarNU* castOrderVar() { return ((OrderVarNU*)this); }
V3GraphVertex* castGraphVertex() { return ((V3GraphVertex*)this); }
inline int castInt() {
union { AstNUser* up; int ui; } u;
u.up = this;
return u.ui;
}
static inline AstNUser* fromInt (int i) {
union { AstNUser* up; int ui; } u;
u.up=0; u.ui=i;
return u.up;
WidthVP* c() { return ((WidthVP*)m_u.up); }
LinkVP* toLinkVP() { return ((LinkVP*)m_u.up); }
VSymEnt* toSymEnt() { return ((VSymEnt*)m_u.up); }
AstNode* toNodep() { return ((AstNode*)m_u.up); }
OrderBlockNU* toOrderBlock() { return ((OrderBlockNU*)m_u.up); }
OrderVarNU* toOrderVar() { return ((OrderVarNU*)m_u.up); }
V3GraphVertex* toGraphVertex() { return ((V3GraphVertex*)m_u.up); }
inline int toInt() {
return m_u.ui;
}
static inline VNUser fromZero () { return VNUser(0); }
static inline VNUser fromInt (int i) { return VNUser(i); }
};
//######################################################################
@ -916,7 +920,7 @@ public:
class FullValue {}; // for creator type-overload selection
explicit V3Hash(Illegal) { m_both=0; }
// Saving and restoring inside a userp
explicit V3Hash(AstNUser* up) { m_both=up->castInt(); }
explicit V3Hash(VNUser u) { m_both=u.toInt(); }
V3Hash operator+= (const V3Hash& rh) {
setBoth(depth()+rh.depth(), (hshval()*31+rh.hshval()));
return *this; };
@ -975,15 +979,15 @@ class AstNode {
// // Space for more bools here
// This member ordering both allows 64 bit alignment and puts associated data together
AstNUser* m_user1p; // Pointer to any information the user iteration routine wants
VNUser m_user1u; // Contains 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
VNUser m_user2u; // Contains any information the user iteration routine wants
VNUser m_user3u; // Contains any information the user iteration routine wants
uint32_t m_user3Cnt; // Mark of when userp was set
uint32_t m_user4Cnt; // Mark of when userp was set
AstNUser* m_user4p; // Pointer to any information the user iteration routine wants
AstNUser* m_user5p; // Pointer to any information the user iteration routine wants
VNUser m_user4u; // Contains any information the user iteration routine wants
VNUser m_user5u; // Contains any information the user iteration routine wants
uint32_t m_user5Cnt; // Mark of when userp was set
// METHODS
@ -1111,57 +1115,75 @@ public:
bool isSigned() const;
bool isString() const;
AstNUser* user1p() const {
VNUser user1u() const {
// Slows things down measurably, so disabled by default
//UASSERT_STATIC(AstUser1InUse::s_userBusy, "userp set w/o busy");
return ((m_user1Cnt==AstUser1InUse::s_userCntGbl)?m_user1p:NULL);
return ((m_user1Cnt==AstUser1InUse::s_userCntGbl) ? m_user1u : VNUser(0));
}
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)); }
AstNode* user1p() const { return user1u().toNodep(); }
void user1u(const VNUser& user) { m_user1u=user; m_user1Cnt=AstUser1InUse::s_userCntGbl; }
void user1p(void* userp) { user1u(VNUser(userp)); }
int user1() const { return user1u().toInt(); }
void user1(int val) { user1u(VNUser(val)); }
int user1Inc(int val=1) { int v=user1(); user1(v+val); return v; }
int user1SetOnce() { int v=user1(); if (!v) user1(1); return v; } // Better for cache than user1Inc()
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");
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(); }
void user2(int val) { user2p(AstNUser::fromInt(val)); }
VNUser user2u() const {
// Slows things down measurably, so disabled by default
//UASSERT_STATIC(AstUser2InUse::s_userBusy, "userp set w/o busy");
return ((m_user2Cnt==AstUser2InUse::s_userCntGbl) ? m_user2u : VNUser(0));
}
AstNode* user2p() const { return user2u().toNodep(); }
void user2u(const VNUser& user) { m_user2u=user; m_user2Cnt=AstUser2InUse::s_userCntGbl; }
void user2p(void* userp) { user2u(VNUser(userp)); }
int user2() const { return user2u().toInt(); }
void user2(int val) { user2u(VNUser(val)); }
int user2Inc(int val=1) { int v=user2(); user2(v+val); return v; }
int user2SetOnce() { int v=user2(); if (!v) user2(1); return v; }
static void user2ClearTree() { AstUser2InUse::clear(); }
int user2SetOnce() { int v=user2(); if (!v) user2(1); return v; } // Better for cache than user2Inc()
static void user2ClearTree() { AstUser2InUse::clear(); } // Clear userp()'s across the entire tree
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(); }
void user3(int val) { user3p(AstNUser::fromInt(val)); }
VNUser user3u() const {
// Slows things down measurably, so disabled by default
//UASSERT_STATIC(AstUser3InUse::s_userBusy, "userp set w/o busy");
return ((m_user3Cnt==AstUser3InUse::s_userCntGbl) ? m_user3u : VNUser(0));
}
AstNode* user3p() const { return user3u().toNodep(); }
void user3u(const VNUser& user) { m_user3u=user; m_user3Cnt=AstUser3InUse::s_userCntGbl; }
void user3p(void* userp) { user3u(VNUser(userp)); }
int user3() const { return user3u().toInt(); }
void user3(int val) { user3u(VNUser(val)); }
int user3Inc(int val=1) { int v=user3(); user3(v+val); return v; }
int user3SetOnce() { int v=user3(); if (!v) user3(1); return v; }
static void user3ClearTree() { AstUser3InUse::clear(); }
int user3SetOnce() { int v=user3(); if (!v) user3(1); return v; } // Better for cache than user3Inc()
static void user3ClearTree() { AstUser3InUse::clear(); } // Clear userp()'s across the entire tree
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(); }
void user4(int val) { user4p(AstNUser::fromInt(val)); }
VNUser user4u() const {
// Slows things down measurably, so disabled by default
//UASSERT_STATIC(AstUser4InUse::s_userBusy, "userp set w/o busy");
return ((m_user4Cnt==AstUser4InUse::s_userCntGbl) ? m_user4u : VNUser(0));
}
AstNode* user4p() const { return user4u().toNodep(); }
void user4u(const VNUser& user) { m_user4u=user; m_user4Cnt=AstUser4InUse::s_userCntGbl; }
void user4p(void* userp) { user4u(VNUser(userp)); }
int user4() const { return user4u().toInt(); }
void user4(int val) { user4u(VNUser(val)); }
int user4Inc(int val=1) { int v=user4(); user4(v+val); return v; }
int user4SetOnce() { int v=user4(); if (!v) user4(1); return v; }
static void user4ClearTree() { AstUser4InUse::clear(); }
int user4SetOnce() { int v=user4(); if (!v) user4(1); return v; } // Better for cache than user4Inc()
static void user4ClearTree() { AstUser4InUse::clear(); } // Clear userp()'s across the entire tree
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(); }
void user5(int val) { user5p(AstNUser::fromInt(val)); }
VNUser user5u() const {
// Slows things down measurably, so disabled by default
//UASSERT_STATIC(AstUser5InUse::s_userBusy, "userp set w/o busy");
return ((m_user5Cnt==AstUser5InUse::s_userCntGbl) ? m_user5u : VNUser(0));
}
AstNode* user5p() const { return user5u().toNodep(); }
void user5u(const VNUser& user) { m_user5u=user; m_user5Cnt=AstUser5InUse::s_userCntGbl; }
void user5p(void* userp) { user5u(VNUser(userp)); }
int user5() const { return user5u().toInt(); }
void user5(int val) { user5u(VNUser(val)); }
int user5Inc(int val=1) { int v=user5(); user5(v+val); return v; }
int user5SetOnce() { int v=user5(); if (!v) user5(1); return v; }
static void user5ClearTree() { AstUser5InUse::clear(); }
int user5SetOnce() { int v=user5(); if (!v) user5(1); return v; } // Better for cache than user5Inc()
static void user5ClearTree() { AstUser5InUse::clear(); } // Clear userp()'s across the entire tree
vluint64_t editCount() const { return m_editCount; }
void editCountInc() { m_editCount = ++s_editCntGbl; } // Preincrement, so can "watch AstNode::s_editCntGbl=##"

View File

@ -78,7 +78,7 @@ private:
if (old_dtypep->width() != width) {
// Since any given dtype's cppWidth() is the same, we can just
// remember one convertion for each, and reuse it
if (AstNodeDType* new_dtypep = old_dtypep->user3p()->castNode()->castNodeDType()) {
if (AstNodeDType* new_dtypep = old_dtypep->user3p()->castNodeDType()) {
nodep->dtypep(new_dtypep);
} else {
nodep->dtypeChgWidth(width, nodep->widthMin());

View File

@ -251,7 +251,7 @@ class GaterBodyVisitor : public GaterBaseVisitor {
virtual void visit(AstVarRef* nodep) {
if (nodep->lvalue()) {
AstVarScope* vscp = nodep->varScopep();
if (vscp->user2p()->castNode() == m_exprp) {
if (vscp->user2p() == m_exprp) {
// This variable's block needs to move to the new always
if (m_original) {
UINFO(9," VARREF delete in old: "<<nodep<<endl);

View File

@ -268,7 +268,7 @@ private:
// then we told this nodep->user3 we can use its Vdlyvset rather than making a new one.
// This is good for code like:
// for (i=0; i<5; i++) vector[i] <= something;
setvscp = nodep->user3p()->castNode()->castVarScope();
setvscp = nodep->user3p()->castVarScope();
++m_statSharedSet;
} else { // Create new one
string setvarname = (string("__Vdlyvset__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
@ -303,9 +303,9 @@ private:
// Build "IF (changeit) ...
UINFO(9," For "<<setvscp<<endl);
UINFO(9," & "<<varrefp<<endl);
AstAlwaysPost* finalp = varrefp->varScopep()->user4p()->castNode()->castAlwaysPost();
AstAlwaysPost* finalp = varrefp->varScopep()->user4p()->castAlwaysPost();
if (finalp) {
AstActive* oldactivep = finalp->user2p()->castNode()->castActive();
AstActive* oldactivep = finalp->user2p()->castActive();
checkActivePost(varrefp, oldactivep);
if (setinitp) oldactivep->addStmtsp(setinitp);
} else { // first time we've dealt with this memory
@ -318,10 +318,10 @@ private:
if (setinitp) newactp->addStmtsp(setinitp);
}
AstIf* postLogicp;
if (finalp->user3p()->castNode() == setvscp) {
if (finalp->user3p() == setvscp) {
// Optimize as above; if sharing Vdlyvset *ON SAME VARIABLE*,
// we can share the IF statement too
postLogicp = finalp->user4p()->castNode()->castIf();
postLogicp = finalp->user4p()->castIf();
if (!postLogicp) nodep->v3fatalSrc("Delayed assignment misoptimized; prev var found w/o associated IF");
} else {
postLogicp = new AstIf (nodep->fileline(),
@ -394,9 +394,9 @@ 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->user1p()->castNode()->castVarScope();
AstVarScope* dlyvscp = oldvscp->user1p()->castVarScope();
if (dlyvscp) { // Multiple use of delayed variable
AstActive* oldactivep = dlyvscp->user2p()->castNode()->castActive();
AstActive* oldactivep = dlyvscp->user2p()->castActive();
checkActivePost(nodep, oldactivep);
}
if (!dlyvscp) { // First use of this delayed variable

View File

@ -65,8 +65,8 @@ class GateLogicVertex;
class GateVarVertex;
class GateGraphBaseVisitor {
public:
virtual AstNUser* visit(GateLogicVertex* vertexp, AstNUser* vup=NULL) =0;
virtual AstNUser* visit(GateVarVertex* vertexp, AstNUser* vup=NULL) =0;
virtual VNUser visit(GateLogicVertex* vertexp, VNUser vu=VNUser(0)) =0;
virtual VNUser visit(GateVarVertex* vertexp, VNUser vu=VNUser(0)) =0;
virtual ~GateGraphBaseVisitor() {}
};
@ -104,14 +104,14 @@ public:
clearReducible(nonReducibleReason);
clearDedupable(nonReducibleReason);
}
virtual AstNUser* accept(GateGraphBaseVisitor& v, AstNUser* vup=NULL) =0;
virtual VNUser accept(GateGraphBaseVisitor& v, VNUser vu=VNUser(0)) =0;
// Returns only the result from the LAST vertex iterated over
AstNUser* iterateInEdges(GateGraphBaseVisitor& v, AstNUser* vup=NULL) {
AstNUser* retp = NULL;
VNUser iterateInEdges(GateGraphBaseVisitor& v, VNUser vu=VNUser(0)) {
VNUser ret = VNUser(0);
for (V3GraphEdge* edgep = inBeginp(); edgep; edgep = edgep->inNextp()) {
retp = dynamic_cast<GateEitherVertex*>(edgep->fromp())->accept(v, vup);
ret = dynamic_cast<GateEitherVertex*>(edgep->fromp())->accept(v, vu);
}
return retp;
return ret;
}
};
@ -147,7 +147,7 @@ public:
setIsClock();
}
}
AstNUser* accept(GateGraphBaseVisitor& v, AstNUser* vup=NULL) { return v.visit(this,vup); }
VNUser accept(GateGraphBaseVisitor& v, VNUser vu=VNUser(0)) { return v.visit(this,vu); }
};
class GateLogicVertex : public GateEitherVertex {
@ -164,7 +164,7 @@ public:
AstNode* nodep() const { return m_nodep; }
AstActive* activep() const { return m_activep; }
bool slow() const { return m_slow; }
AstNUser* accept(GateGraphBaseVisitor& v, AstNUser* vup=NULL) { return v.visit(this,vup); }
VNUser accept(GateGraphBaseVisitor& v, VNUser vu=VNUser(0)) { return v.visit(this,vu); }
};
//######################################################################
@ -875,13 +875,13 @@ private:
&& !node2p->sameHash().isIllegal()
&& m_hashed.sameNodes(node1p,node2p));
}
bool same(AstNUser* node1p, AstNUser* node2p) {
return node1p == node2p || sameHash((AstNode*)node1p,(AstNode*)node2p);
bool same(AstNode* node1p, AstNode* node2p) {
return node1p == node2p || sameHash(node1p,node2p);
}
public:
bool check(AstNode* node1p,AstNode* node2p) {
return same(node1p->user3p(),node2p->user3p()) && same(node1p->user5p(),node2p->user5p())
&& node1p->user2p()->castNode()->type() == node2p->user2p()->castNode()->type()
&& node1p->user2p()->type() == node2p->user2p()->type()
;
}
@ -901,7 +901,7 @@ public:
// So dupit is either a different, duplicate rhsp, or the end of the hash.
if (dupit != m_hashed.end()) {
m_hashed.erase(inserted);
return m_hashed.iteratorNodep(dupit)->user2p()->castNode()->castNodeAssign();
return m_hashed.iteratorNodep(dupit)->user2p()->castNodeAssign();
}
return NULL;
}
@ -1012,15 +1012,15 @@ private:
GateDedupeVarVisitor m_varVisitor; // Looks for a dupe of the logic
int m_depth; // Iteration depth
virtual AstNUser* visit(GateVarVertex* vvertexp, AstNUser*) {
virtual VNUser visit(GateVarVertex* vvertexp, VNUser) {
// Check that we haven't been here before
if (m_depth > GATE_DEDUP_MAX_DEPTH) return NULL; // Break loops; before user2 set so hit this vertex later
if (vvertexp->varScp()->user2()) return NULL;
if (m_depth > GATE_DEDUP_MAX_DEPTH) return VNUser(0); // Break loops; before user2 set so hit this vertex later
if (vvertexp->varScp()->user2()) return VNUser(0);
vvertexp->varScp()->user2(true);
m_depth++;
if (vvertexp->inSize1()) {
AstNodeVarRef* dupVarRefp = (AstNodeVarRef*) vvertexp->iterateInEdges(*this, (AstNUser*) vvertexp);
AstNodeVarRef* dupVarRefp = (AstNodeVarRef*) vvertexp->iterateInEdges(*this, VNUser(vvertexp)).toNodep();
if (dupVarRefp) {
V3GraphEdge* edgep = vvertexp->inBeginp();
@ -1057,15 +1057,15 @@ private:
}
}
m_depth--;
return NULL;
return VNUser(0);
}
// Given iterated logic, starting at vup which was consumer's GateVarVertex
// Given iterated logic, starting at vu which was consumer's GateVarVertex
// Returns a varref that has the same logic input; or NULL if none
virtual AstNUser* visit(GateLogicVertex* lvertexp, AstNUser* vup) {
virtual VNUser visit(GateLogicVertex* lvertexp, VNUser vu) {
lvertexp->iterateInEdges(*this);
GateVarVertex* consumerVvertexpp = (GateVarVertex*) vup;
GateVarVertex* consumerVvertexpp = (GateVarVertex*) vu.toGraphVertex();
if (lvertexp->dedupable() && consumerVvertexpp->dedupable()) {
AstNode* nodep = lvertexp->nodep();
AstVarScope* consumerVarScopep = consumerVvertexpp->varScp();
@ -1074,9 +1074,9 @@ private:
// different generated clocks will never compare as equal, even if the
// generated clocks are deduped into one clock.
AstActive* activep = lvertexp->activep();
return (AstNUser*) m_varVisitor.findDupe(nodep, consumerVarScopep, activep);
return VNUser(m_varVisitor.findDupe(nodep, consumerVarScopep, activep));
}
return NULL;
return VNUser(0);
}
public:
@ -1142,7 +1142,7 @@ private:
else return NULL;
}
virtual AstNUser* visit(GateVarVertex *vvertexp, AstNUser*) {
virtual VNUser visit(GateVarVertex *vvertexp, VNUser) {
for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; ) {
V3GraphEdge* oldedgep = edgep;
edgep = edgep->inNextp(); // for recursive since the edge could be deleted
@ -1204,11 +1204,11 @@ private:
}
}
}
return NULL;
return VNUser(0);
}
virtual AstNUser* visit(GateLogicVertex* lvertexp, AstNUser* vup) {
return NULL;
virtual VNUser visit(GateLogicVertex* lvertexp, VNUser vu) {
return VNUser(0);
}
public:

View File

@ -65,7 +65,7 @@ private:
// METHODS
AstVarScope* genInpClk(AstVarScope* vscp) {
if (vscp->user2p()) {
return vscp->user2p()->castNode()->castVarScope();
return vscp->user2p()->castVarScope();
} else {
AstVar* varp = vscp->varp();
string newvarname = "__VinpClk__"+vscp->scopep()->nameDotless()+"__"+varp->name();

View File

@ -141,7 +141,7 @@ public:
//============================================================================
class V3GraphVertex : public AstNUser {
class V3GraphVertex {
// Vertices may be a 'gate'/wire statement OR a variable
protected:
friend class V3Graph; friend class V3GraphEdge;

View File

@ -194,7 +194,7 @@ private:
// Foreach input transition (on this nfaStatep)
for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep; nfaEdgep=nfaEdgep->outNextp()) {
DfaEdge* cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
if (cNfaEdgep->input() == input) {
if (cNfaEdgep->input().toNodep() == input.toNodep()) {
DfaVertex* nextStatep = static_cast<DfaVertex*>(cNfaEdgep->top());
if (unseenNfaThisStep(nextStatep)) { // Not processed?
nfasWithInput.push_back(nextStatep);
@ -275,7 +275,7 @@ private:
UINFO(9," On dfaState "<<dfaStatep<<endl);
// From this dfaState, what corresponding nfaStates have what inputs?
set<DfaInput> inputs;
set<int> inputs;
// Foreach NFA state (this DFA state was formed from)
for (V3GraphEdge* dfaEdgep = dfaStatep->outBeginp(); dfaEdgep; dfaEdgep=dfaEdgep->outNextp()) {
if (nfaState(dfaEdgep->top())) {
@ -284,9 +284,9 @@ private:
for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep; nfaEdgep=nfaEdgep->outNextp()) {
DfaEdge* cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
if (!cNfaEdgep->epsilon()) {
if (inputs.find(cNfaEdgep->input()) == inputs.end()) {
inputs.insert(cNfaEdgep->input());
UINFO(9," Input to "<<dfaStatep<<" is "<<(void*)(cNfaEdgep->input())<<" via "<<nfaStatep<<endl);
if (inputs.find(cNfaEdgep->input().toInt()) == inputs.end()) {
inputs.insert(cNfaEdgep->input().toInt());
UINFO(9," Input to "<<dfaStatep<<" is "<<(cNfaEdgep->input().toInt())<<" via "<<nfaStatep<<endl);
}
}
}
@ -294,10 +294,10 @@ private:
}
// Foreach input state (NFA inputs of this DFA state)
for (set<DfaInput>::const_iterator inIt=inputs.begin(); inIt!=inputs.end(); ++inIt) {
for (set<int>::const_iterator inIt=inputs.begin(); inIt!=inputs.end(); ++inIt) {
DfaInput input = *inIt;
UINFO(9," ==="<<++i<<"=======================\n");
UINFO(9," On input "<<(void*)(input)<<endl);
UINFO(9," On input "<<(void*)(input.toNodep())<<endl);
// Find all states reachable for given input
DfaStates nfasWithInput;

View File

@ -111,7 +111,8 @@ public:
//============================================================================
/// Abstract type indicating a specific "input" to the NFA
typedef AstNUser* DfaInput;
/// DFA assumes each .toInt() is unique
typedef VNUser DfaInput;
//============================================================================
// Edge types
@ -120,8 +121,8 @@ class DfaEdge : public V3GraphEdge {
DfaInput m_input;
bool m_complement; // Invert value when doing compare
public:
static DfaInput EPSILON() { return NULL; }
static DfaInput NA() { return AstNUser::fromInt(1); } // as in not-applicable
static DfaInput EPSILON() { return VNUser::fromInt(0); }
static DfaInput NA() { return VNUser::fromInt(1); } // as in not-applicable
// CONSTRUCTORS
DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, DfaInput input)
: V3GraphEdge(graphp, fromp, top, 1)
@ -138,11 +139,11 @@ public:
virtual string dotLabel() const {
return (na() ? ""
: epsilon() ? "e"
: complement() ? ("not "+cvtToStr((void*)(input())))
: cvtToStr((void*)(input()))); }
: complement() ? ("not "+cvtToStr(input().toInt()))
: cvtToStr(input().toInt())); }
virtual string dotStyle() const { return (na()||cutable())?"dashed":""; }
bool epsilon() const { return input()==EPSILON(); }
bool na() const { return input()==NA(); }
bool epsilon() const { return input().toInt()==EPSILON().toInt(); }
bool na() const { return input().toInt()==NA().toInt(); }
bool complement() const { return m_complement; }
void complement(bool value) { m_complement=value; }
DfaInput input() const { return m_input; }

View File

@ -292,9 +292,9 @@ public:
DfaTestVertex* sz = new DfaTestVertex(gp,"sZ");
DfaTestVertex* sac = new DfaTestVertex(gp,"*ACCEPT*"); sac->accepting(true);
AstNUser* L = AstNUser::fromInt(0xaa);
AstNUser* R = AstNUser::fromInt(0xbb);
AstNUser* Z = AstNUser::fromInt(0xcc);
VNUser L = VNUser::fromInt(0xaa);
VNUser R = VNUser::fromInt(0xbb);
VNUser Z = VNUser::fromInt(0xcc);
new DfaEdge(gp, st, sl, DfaEdge::EPSILON());
new DfaEdge(gp, sl, srs, L);

View File

@ -273,9 +273,9 @@ private:
if (nodep->user2p()) {
// Make an assignment, so we'll trace it properly
// user2p is either a const or a var.
AstConst* exprconstp = nodep->user2p()->castNode()->castConst();
AstVarRef* exprvarrefp = nodep->user2p()->castNode()->castVarRef();
UINFO(8,"connectto: "<<nodep->user2p()->castNode()<<endl);
AstConst* exprconstp = nodep->user2p()->castConst();
AstVarRef* exprvarrefp = nodep->user2p()->castVarRef();
UINFO(8,"connectto: "<<nodep->user2p()<<endl);
if (!exprconstp && !exprvarrefp) {
nodep->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up\n");
}
@ -319,7 +319,7 @@ private:
ifacerefp->addNextHere(newdp);
// Relink to point to newly cloned cell
if (newdp->cellp()) {
if (AstCell* newcellp = newdp->cellp()->user4p()->castNode()->castCell()) {
if (AstCell* newcellp = newdp->cellp()->user4p()->castCell()) {
newdp->cellp(newcellp);
newdp->cellName(newcellp->name());
// Tag the old ifacerefp to ensure it leaves no stale reference to the inlined cell.
@ -351,8 +351,8 @@ private:
if (nodep->varp()->user2p() // It's being converted to an alias.
&& !nodep->varp()->user3()
&& !nodep->backp()->castAssignAlias()) { // Don't constant propagate aliases (we just made)
AstConst* exprconstp = nodep->varp()->user2p()->castNode()->castConst();
AstVarRef* exprvarrefp = nodep->varp()->user2p()->castNode()->castVarRef();
AstConst* exprconstp = nodep->varp()->user2p()->castConst();
AstVarRef* exprvarrefp = nodep->varp()->user2p()->castVarRef();
if (exprconstp) {
nodep->replaceWith(exprconstp->cloneTree(true));
nodep->deleteTree(); VL_DANGLING(nodep);

View File

@ -119,7 +119,7 @@ private:
if (!nodep->user1p()) {
nodep->user1p(new LinkCellsVertex(&m_graph, nodep));
}
return (nodep->user1p()->castGraphVertex());
return (nodep->user1u().toGraphVertex());
}
AstNodeModule* findModuleSym(const string& modName) {

View File

@ -332,7 +332,7 @@ public:
}
static VSymEnt* getNodeSym(AstNode* nodep) {
// Don't use this in ResolveVisitor, as we need to pick up the proper reference under each SCOPE
VSymEnt* symp = nodep->user1p()->castSymEnt();
VSymEnt* symp = nodep->user1u().toSymEnt();
if (!symp) nodep->v3fatalSrc("Module/etc never assigned a symbol entry?");
return symp;
}
@ -1514,9 +1514,9 @@ private:
return varp;
}
void markAndCheckPinDup(AstNode* nodep, AstNode* refp, const char* whatp) {
if (refp->user5p() && refp->user5p()->castNode()!=nodep) {
if (refp->user5p() && refp->user5p()!=nodep) {
nodep->v3error("Duplicate "<<whatp<<" connection: "<<nodep->prettyName()<<endl
<<refp->user5p()->castNode()->warnMore()
<<refp->user5p()->warnMore()
<<"... Location of original "<<whatp<<" connection");
} else {
refp->user5p(nodep);
@ -1959,7 +1959,7 @@ private:
} else {
while (vscp->user2p()) { // If V3Inline aliased it, pick up the new signal
UINFO(7," Resolved pre-alias "<<vscp<<endl); // Also prints taskp
vscp = vscp->user2p()->castNode()->castVarScope();
vscp = vscp->user2p()->castVarScope();
}
// Convert the VarXRef to a VarRef, so we don't need later optimizations to deal with VarXRef.
nodep->varp(vscp->varp());

View File

@ -141,7 +141,7 @@ private:
// 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->user1p()->castNode()->castCFunc();
AstCFunc* newfuncp = nodep->user1p()->castCFunc();
nodep->unlinkFrBack();
newfuncp->addInitsp(nodep);
// Done
@ -208,7 +208,7 @@ 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()->user1p()->castNode();
AstNode* oldfunc = nodep->varp()->user1p();
if (!oldfunc) {
UINFO(4," BVnewref "<<nodep<<endl);
nodep->varp()->user1p(m_cfuncp); // Remember where it was used

View File

@ -1493,7 +1493,7 @@ void OrderVisitor::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* d
<<" s="<<(void*)(scopep)<<" "<<lvertexp<<endl);
AstSenTree* domainp = lvertexp->domainp();
AstNode* nodep = lvertexp->nodep();
AstNodeModule* modp = scopep->user1p()->castNode()->castNodeModule(); UASSERT(modp,"NULL"); // Stashed by visitor func
AstNodeModule* modp = scopep->user1p()->castNodeModule(); UASSERT(modp,"NULL"); // Stashed by visitor func
if (nodep->castUntilStable()) {
nodep->v3fatalSrc("Not implemented");
}

View File

@ -47,7 +47,7 @@ private:
// METHODS
static VSymEnt* getTable(AstNode* nodep) {
if (!nodep->user4p()) nodep->v3fatalSrc("Current symtable not found");
return nodep->user4p()->castSymEnt();
return nodep->user4u().toSymEnt();
}
public:

View File

@ -381,7 +381,7 @@ private:
if (nodep->packagep()) {
// Point to the clone
if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked");
AstNodeFTask* newp = nodep->taskp()->user2p()->castNode()->castNodeFTask();
AstNodeFTask* newp = nodep->taskp()->user2p()->castNodeFTask();
if (!newp) nodep->v3fatalSrc("No clone for package function");
nodep->taskp(newp);
UINFO(9," New pkg-taskref "<<nodep<<endl);

View File

@ -186,11 +186,11 @@ public:
private:
inline void setNumber(AstNode* nodep, const V3Number* nump) {
UINFO(9," set num "<<*nump<<" on "<<nodep<<endl);
nodep->user3p((AstNUser*)nump);
nodep->user3p((void*)nump);
}
inline void setOutNumber(AstNode* nodep, const V3Number* nump) {
UINFO(9," set num "<<*nump<<" on "<<nodep<<endl);
nodep->user2p((AstNUser*)nump);
nodep->user2p((void*)nump);
}
void checkNodeInfo(AstNode* nodep) {

View File

@ -71,7 +71,7 @@ class SliceCloneVisitor : public AstNVisitor {
virtual void visit(AstArraySel* nodep) {
if (!nodep->backp()->castArraySel()) {
// This is the top of an ArraySel, setup for iteration
m_refp = nodep->user1p()->castNode()->castVarRef();
m_refp = nodep->user1p()->castVarRef();
m_vecIdx += 1;
if (m_vecIdx == (int)m_selBits.size()) {
m_selBits.push_back(vector<unsigned>());
@ -259,7 +259,7 @@ class SliceVisitor : public AstNVisitor {
// Insert any implicit slices as explicit slices (ArraySel nodes).
// Return a new pointer to replace nodep() in the ArraySel.
UINFO(9," insertImplicit (startDim="<<startDim<<",c="<<numDimensions<<") "<<nodep<<endl);
AstVarRef* refp = nodep->user1p()->castNode()->castVarRef();
AstVarRef* refp = nodep->user1p()->castVarRef();
if (!refp) nodep->v3fatalSrc("No VarRef in user1 of node "<<nodep);
AstVar* varp = refp->varp();
AstNode* topp = nodep;
@ -326,7 +326,7 @@ class SliceVisitor : public AstNVisitor {
if (!m_assignp) return;
if (nodep->user3()) return; // Prevent recursion on just created nodes
unsigned dim = explicitDimensions(nodep);
AstVarRef* refp = nodep->user1p()->castNode()->castVarRef();
AstVarRef* refp = nodep->user1p()->castVarRef();
pair<uint32_t,uint32_t> arrDim = refp->varp()->dtypep()->dimensions(false);
uint32_t implicit = (arrDim.second) - dim;
if (implicit > 0) {

View File

@ -118,7 +118,7 @@ private:
public:
// METHODS
AstScope* getScope(AstNodeFTask* nodep) {
AstScope* scopep = nodep->user3p()->castNode()->castScope();
AstScope* scopep = nodep->user3p()->castScope();
if (!scopep) nodep->v3fatalSrc("No scope for function");
return scopep;
}
@ -155,7 +155,7 @@ private:
if (!nodep->user4p()) {
nodep->user4p(new TaskFTaskVertex(&m_callGraph, nodep));
}
return static_cast<TaskFTaskVertex*>(nodep->user4p()->castGraphVertex());
return static_cast<TaskFTaskVertex*>(nodep->user4u().toGraphVertex());
}
// VISITORS
@ -220,7 +220,7 @@ private:
}
virtual void visit(AstVarRef* nodep) {
nodep->iterateChildren(*this);
if (nodep->varp()->user4p() != m_curVxp) {
if (nodep->varp()->user4u().toGraphVertex() != m_curVxp) {
if (m_curVxp->pure()
&& !nodep->varp()->isXTemp()) {
m_curVxp->impure(nodep);
@ -262,7 +262,7 @@ private:
// Similar code in V3Inline
if (nodep->varp()->user2p()) { // It's being converted to a alias.
UINFO(9, " relinkVar "<<(void*)nodep->varp()->user2p()<<" "<<nodep<<endl);
AstVarScope* newvscp = nodep->varp()->user2p()->castNode()->castVarScope();
AstVarScope* newvscp = nodep->varp()->user2p()->castVarScope();
if (!newvscp) nodep->v3fatalSrc("Null?\n");
nodep->varScopep(newvscp);
nodep->varp(nodep->varScopep()->varp());
@ -773,7 +773,7 @@ private:
string args;
for (AstNode* stmtp = cfuncp->argsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
AstVarScope* portvscp = portp->user2p()->castNode()->castVarScope(); // Remembered when we created it earlier
AstVarScope* portvscp = portp->user2p()->castVarScope(); // Remembered when we created it earlier
if (portp->isIO() && !portp->isFuncReturn() && portvscp != rtnvscp
&& portp->name() != "__Vscopep" // Passed to dpiContext, not callee
&& portp->name() != "__Vfilenamep"
@ -814,7 +814,7 @@ private:
for (AstNode* stmtp = cfuncp->argsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (portp->isIO() && (portp->isOutput() || portp->isFuncReturn())) {
AstVarScope* portvscp = portp->user2p()->castNode()->castVarScope(); // Remembered when we created it earlier
AstVarScope* portvscp = portp->user2p()->castVarScope(); // Remembered when we created it earlier
cfuncp->addStmtsp(createAssignDpiToInternal(portvscp,portp->name()+"__Vcvt",true));
}
}

View File

@ -225,7 +225,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->user1p()->castGraphVertex());
TraceTraceVertex* dupvertexp = dynamic_cast<TraceTraceVertex*>(dupincp->user1u().toGraphVertex());
UINFO(8," Orig "<<nodep<<endl);
UINFO(8," dup "<<dupincp<<endl);
// Mark the hashed node as the original and our iterating node as duplicated
@ -539,7 +539,7 @@ private:
}
TraceCFuncVertex* getCFuncVertexp(AstCFunc* nodep) {
TraceCFuncVertex* vertexp = dynamic_cast<TraceCFuncVertex*>(nodep->user1p()->castGraphVertex());
TraceCFuncVertex* vertexp = dynamic_cast<TraceCFuncVertex*>(nodep->user1u().toGraphVertex());
if (!vertexp) {
vertexp = new TraceCFuncVertex(&m_graph, nodep);
nodep->user1p(vertexp);
@ -547,7 +547,7 @@ private:
return vertexp;
}
TraceActivityVertex* getActivityVertexp(AstNode* nodep, bool slow) {
TraceActivityVertex* vertexp = dynamic_cast<TraceActivityVertex*>(nodep->user3p()->castGraphVertex());
TraceActivityVertex* vertexp = dynamic_cast<TraceActivityVertex*>(nodep->user3u().toGraphVertex());
if (!vertexp) {
vertexp = new TraceActivityVertex(&m_graph, nodep, slow);
nodep->user3p(vertexp);
@ -653,12 +653,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()->user1p()->castGraphVertex();
V3GraphVertex* varVtxp = nodep->varScopep()->user1u().toGraphVertex();
if (!varVtxp) {
varVtxp = new TraceVarVertex(&m_graph, nodep->varScopep());
nodep->varScopep()->user1p(varVtxp);
}
V3GraphVertex* traceVtxp = m_tracep->user1p()->castGraphVertex();
V3GraphVertex* traceVtxp = m_tracep->user1u().toGraphVertex();
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
@ -668,7 +668,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()->user1p()->castGraphVertex();
V3GraphVertex* varVtxp = nodep->varScopep()->user1u().toGraphVertex();
if (varVtxp) { // else we're not tracing this signal
new V3GraphEdge(&m_graph, funcVtxp, varVtxp, 1);
}

View File

@ -373,7 +373,7 @@ class TristateVisitor : public TristateBaseVisitor {
AstNode* enp = new AstConst(nodep->fileline(), num);
nodep->user1p(enp);
}
return nodep->user1p()->castNode();
return nodep->user1p();
}
AstVar* getCreateEnVarp(AstVar* invarp) {
@ -388,7 +388,7 @@ class TristateVisitor : public TristateBaseVisitor {
else m_modp->addStmtp(newp);
invarp->user1p(newp); // find envar given invarp
}
return invarp->user1p()->castNode()->castVar();
return invarp->user1p()->castVar();
}
AstVar* getCreateOutVarp(AstVar* invarp) {
@ -403,7 +403,7 @@ class TristateVisitor : public TristateBaseVisitor {
else m_modp->addStmtp(newp);
invarp->user4p(newp); // find outvar given invarp
}
return invarp->user4p()->castNode()->castVar();
return invarp->user4p()->castVar();
}
AstVar* getCreateUnconnVarp(AstNode* fromp, AstNodeDType* dtypep) {
@ -541,7 +541,7 @@ class TristateVisitor : public TristateBaseVisitor {
outvarp->user3p(invarp->user3p()); // AstPull* propagation
if (invarp->user3p()) UINFO(9, "propagate pull to "<<outvarp<<endl);
} else if (invarp->user1p()) {
envarp = invarp->user1p()->castNode()->castVar(); // From CASEEQ, foo === 1'bz
envarp = invarp->user1p()->castVar(); // From CASEEQ, foo === 1'bz
}
AstNode* orp = NULL;
@ -720,7 +720,7 @@ class TristateVisitor : public TristateBaseVisitor {
UINFO(9,dbgState()<<nodep<<endl);
if (nodep->user1p()) {
// Form a "deposit" instruction. Would be nicer if we made this a new AST type
AstNode* newp = newEnableDeposit(nodep, nodep->user1p()->castNode());
AstNode* newp = newEnableDeposit(nodep, nodep->user1p());
nodep->fromp()->user1p(newp); // Push to varref (etc)
if (debug()>=9) newp->dumpTree(cout,"-assign-sel; ");
m_tgraph.didProcess(nodep);
@ -760,7 +760,7 @@ class TristateVisitor : public TristateBaseVisitor {
UINFO(9,dbgState()<<nodep<<endl);
if (nodep->user1p()) {
// Each half of the concat gets a select of the enable expression
AstNode* enp = nodep->user1p()->castNode();
AstNode* enp = nodep->user1p();
nodep->user1p(NULL);
nodep->lhsp()->user1p(new AstSel(nodep->fileline(),
enp->cloneTree(true),
@ -807,7 +807,7 @@ class TristateVisitor : public TristateBaseVisitor {
AstNode* expr1p = nodep->lhsp()->unlinkFrBack();
AstNode* expr2p = nodep->rhsp()->unlinkFrBack();
AstNode* enp;
if (AstNode* en2p = expr2p->user1p()->castNode()) {
if (AstNode* en2p = expr2p->user1p()) {
enp = new AstAnd(nodep->fileline(), expr1p, en2p);
} else {
enp = expr1p;
@ -937,7 +937,7 @@ class TristateVisitor : public TristateBaseVisitor {
// 3'b1z0 -> ((3'b101 == in__en) && (3'b100 == in))
varrefp->unlinkFrBack();
FileLine* fl = nodep->fileline();
V3Number oneIfEn = constp->user1p()->castNode()->castConst()->num(); // visit(AstConst) already split into en/ones
V3Number oneIfEn = constp->user1p()->castConst()->num(); // visit(AstConst) already split into en/ones
V3Number oneIfEnOne = constp->num();
AstVar* envarp = getCreateEnVarp(varrefp->varp());
AstNode* newp = new AstLogAnd (fl, new AstEq (fl, new AstConst(fl, oneIfEn),

View File

@ -113,7 +113,7 @@ private:
// Already exists; rather than IF(a,... IF(b... optimize to IF(a&&b,
// Saves us teaching V3Const how to optimize, and it won't be needed again.
if (AstIf* ifp = prep->user2p()->castNode()->castIf()) {
if (AstIf* ifp = prep->user2p()->castIf()) {
if (needDly) prep->v3fatalSrc("Should have already converted to non-delay");
AstNRelinker replaceHandle;
AstNode* earliercondp = ifp->condp()->unlinkFrBack(&replaceHandle);