diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 0fa610241..da7ad5309 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -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; } diff --git a/src/V3Ast.h b/src/V3Ast.h index 5a2d98dd5..e9bf7bde9 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -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=##" diff --git a/src/V3Clean.cpp b/src/V3Clean.cpp index 948f9f479..8b61f4b99 100644 --- a/src/V3Clean.cpp +++ b/src/V3Clean.cpp @@ -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()); diff --git a/src/V3ClkGater.cpp b/src/V3ClkGater.cpp index 326b9f555..ae0195c31 100644 --- a/src/V3ClkGater.cpp +++ b/src/V3ClkGater.cpp @@ -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: "<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 "<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 diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp index 6693f62a0..335903968 100644 --- a/src/V3Gate.cpp +++ b/src/V3Gate.cpp @@ -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(edgep->fromp())->accept(v, vup); + ret = dynamic_cast(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: diff --git a/src/V3GenClk.cpp b/src/V3GenClk.cpp index 3ce9dd530..ce06240a8 100644 --- a/src/V3GenClk.cpp +++ b/src/V3GenClk.cpp @@ -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(); diff --git a/src/V3Graph.h b/src/V3Graph.h index e72c423c3..781269340 100644 --- a/src/V3Graph.h +++ b/src/V3Graph.h @@ -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; diff --git a/src/V3GraphDfa.cpp b/src/V3GraphDfa.cpp index f091208ad..80c8b0e91 100644 --- a/src/V3GraphDfa.cpp +++ b/src/V3GraphDfa.cpp @@ -194,7 +194,7 @@ private: // Foreach input transition (on this nfaStatep) for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep; nfaEdgep=nfaEdgep->outNextp()) { DfaEdge* cNfaEdgep = static_cast(nfaEdgep); - if (cNfaEdgep->input() == input) { + if (cNfaEdgep->input().toNodep() == input.toNodep()) { DfaVertex* nextStatep = static_cast(cNfaEdgep->top()); if (unseenNfaThisStep(nextStatep)) { // Not processed? nfasWithInput.push_back(nextStatep); @@ -275,7 +275,7 @@ private: UINFO(9," On dfaState "< inputs; + set 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(nfaEdgep); if (!cNfaEdgep->epsilon()) { - if (inputs.find(cNfaEdgep->input()) == inputs.end()) { - inputs.insert(cNfaEdgep->input()); - UINFO(9," Input to "<input())<<" via "<input().toInt()) == inputs.end()) { + inputs.insert(cNfaEdgep->input().toInt()); + UINFO(9," Input to "<input().toInt())<<" via "<::const_iterator inIt=inputs.begin(); inIt!=inputs.end(); ++inIt) { + for (set::const_iterator inIt=inputs.begin(); inIt!=inputs.end(); ++inIt) { DfaInput input = *inIt; UINFO(9," ==="<<++i<<"=======================\n"); - UINFO(9," On input "<<(void*)(input)<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); diff --git a/src/V3Inline.cpp b/src/V3Inline.cpp index 69251a0c2..8f019f714 100644 --- a/src/V3Inline.cpp +++ b/src/V3Inline.cpp @@ -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: "<user2p()->castNode()<user2p()->castConst(); + AstVarRef* exprvarrefp = nodep->user2p()->castVarRef(); + UINFO(8,"connectto: "<user2p()<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); diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index 7bea24ce7..c2e6f3aa6 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -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) { diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 31d630fc2..bc6710968 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -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 "<prettyName()<user5p()->castNode()->warnMore() + <user5p()->warnMore() <<"... Location of original "<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 "<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()); diff --git a/src/V3Localize.cpp b/src/V3Localize.cpp index 36d67673a..6d3e0ac0b 100644 --- a/src/V3Localize.cpp +++ b/src/V3Localize.cpp @@ -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 "<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 "<varp()->user1p(m_cfuncp); // Remember where it was used diff --git a/src/V3Order.cpp b/src/V3Order.cpp index e610e4576..9edd94966 100644 --- a/src/V3Order.cpp +++ b/src/V3Order.cpp @@ -1493,7 +1493,7 @@ void OrderVisitor::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* d <<" s="<<(void*)(scopep)<<" "<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"); } diff --git a/src/V3ParseSym.h b/src/V3ParseSym.h index c566ce322..926368ac0 100644 --- a/src/V3ParseSym.h +++ b/src/V3ParseSym.h @@ -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: diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp index 788e6f7b1..37783d264 100644 --- a/src/V3Scope.cpp +++ b/src/V3Scope.cpp @@ -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 "<user3p((AstNUser*)nump); + nodep->user3p((void*)nump); } inline void setOutNumber(AstNode* nodep, const V3Number* nump) { UINFO(9," set num "<<*nump<<" on "<user2p((AstNUser*)nump); + nodep->user2p((void*)nump); } void checkNodeInfo(AstNode* nodep) { diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index 20f138781..f193a0b5c 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -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()); @@ -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="<user1p()->castNode()->castVarRef(); + AstVarRef* refp = nodep->user1p()->castVarRef(); if (!refp) nodep->v3fatalSrc("No VarRef in user1 of node "<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 arrDim = refp->varp()->dtypep()->dimensions(false); uint32_t implicit = (arrDim.second) - dim; if (implicit > 0) { diff --git a/src/V3Task.cpp b/src/V3Task.cpp index f2e6432ce..9de2c9a3f 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -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(nodep->user4p()->castGraphVertex()); + return static_cast(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()<<" "<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)); } } diff --git a/src/V3Trace.cpp b/src/V3Trace.cpp index a3ac04aa2..71b400ff8 100644 --- a/src/V3Trace.cpp +++ b/src/V3Trace.cpp @@ -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(dupincp->user1p()->castGraphVertex()); + TraceTraceVertex* dupvertexp = dynamic_cast(dupincp->user1u().toGraphVertex()); UINFO(8," Orig "<(nodep->user1p()->castGraphVertex()); + TraceCFuncVertex* vertexp = dynamic_cast(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(nodep->user3p()->castGraphVertex()); + TraceActivityVertex* vertexp = dynamic_cast(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); } diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index 5ef5dcfe6..32f0f53dd 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -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 "<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()<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()<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), diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index 99413e2bc..0edd11479 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -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);