From 634816d37860e715060db083e762d42ef2cd9d68 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 1 Feb 2010 18:55:32 -0500 Subject: [PATCH] V3Delayed warnings now per-scope, bug102 part 2+3 --- internals.pod | 2 +- src/V3Ast.cpp | 5 +++++ src/V3Ast.h | 21 +++++++++++++++++++++ src/V3Delayed.cpp | 15 ++++++++------- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/internals.pod b/internals.pod index 5e60926d1..791bf84d9 100644 --- a/internals.pod +++ b/internals.pod @@ -116,7 +116,7 @@ nested items (for example an AstFor under an AstFor) the variable needs to be save-set-restored in the AstFor visitor, otherwise exiting the lower for will loose the upper for's setting. -2. User() attributes. Each node has 4 ->user() number or ->userp() pointer +2. User() attributes. Each node has 5 ->user() number or ->userp() pointer utility values (a common technique lifted from graph traversal packages). A visitor first clears the one it wants to use by calling AstNode::user#ClearTree(), then it can mark any node's user() with whatever diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index b16a4ede7..ba183371b 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -44,11 +44,13 @@ 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 +uint32_t AstUser5InUse::s_userCntGbl=0; // Hot cache line, leave adjacent bool AstUser1InUse::s_userBusy=false; bool AstUser2InUse::s_userBusy=false; bool AstUser3InUse::s_userBusy=false; bool AstUser4InUse::s_userBusy=false; +bool AstUser5InUse::s_userBusy=false; //###################################################################### // V3AstType @@ -83,6 +85,8 @@ void AstNode::init() { m_user3Cnt = 0; m_user4p = NULL; m_user4Cnt = 0; + m_user5p = NULL; + m_user5Cnt = 0; } string AstNode::encodeName(const string& namein) { @@ -954,6 +958,7 @@ void AstNode::dumpPtrs(ostream& os) { if (user2p()) os<<" user2p="<<(void*)user2p(); if (user3p()) os<<" user3p="<<(void*)user3p(); if (user4p()) os<<" user4p="<<(void*)user4p(); + if (user5p()) os<<" user5p="<<(void*)user5p(); if (m_iterpp) { os<<" iterpp="<<(void*)m_iterpp; os<<"*="<<(void*)*m_iterpp; diff --git a/src/V3Ast.h b/src/V3Ast.h index 9f666bde2..f5e0f7f80 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -550,6 +550,17 @@ public: static void clear() { clearcnt(4, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } static void check() { checkcnt(4, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } }; +class AstUser5InUse : 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: + AstUser5InUse() { allocate(5, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + ~AstUser5InUse() { free (5, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + static void clear() { clearcnt(5, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + static void check() { checkcnt(5, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } +}; //###################################################################### // AstNVisitor -- Allows new functions to be called on each node @@ -685,6 +696,8 @@ class AstNode { 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 + uint32_t m_user5Cnt; // Mark of when userp was set // METHODS void op1p(AstNode* nodep) { m_op1p = nodep; if (nodep) nodep->m_backp = this; } @@ -832,6 +845,14 @@ public: void user4(int val) { user4p(AstNUser::fromInt(val)); } static void user4ClearTree() { AstUser4InUse::clear(); } + AstNUser* user5p() const { + //UASSERT_STATIC(AstUser5InUse::s_userBusy, "user5p set w/o busy"); + return ((m_user5Cnt==AstUser5InUse::s_userCntGbl)?m_user5p:NULL); } + void user5p(void* userp) { m_user5p=(AstNUser*)(userp); m_user5Cnt=AstUser5InUse::s_userCntGbl; } + int user5() const { return user5p()->castInt(); } + void user5(int val) { user5p(AstNUser::fromInt(val)); } + static void user5ClearTree() { AstUser5InUse::clear(); } + vluint64_t editCount() const { return m_editCount; } void editCountInc() { m_editCount = ++s_editCntGbl; } // Preincrement, so can "watch AstNode::s_editCntGbl=##" static vluint64_t editCountLast() { return s_editCntLast; } diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index b1f175d37..873950647 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -76,7 +76,7 @@ private: // 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::user1() -> VarUsage. Tracks delayed vs non-delayed usage + // AstVarScope::user5() -> 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 @@ -88,6 +88,7 @@ private: AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; AstUser4InUse m_inuser4; + AstUser5InUse m_inuser5; enum VarUsage { VU_NONE=0, VU_DLY=1, VU_NONDLY=2 }; @@ -110,11 +111,11 @@ private: return level; } - void markVarUsage(AstVar* nodep, uint32_t flags) { + void markVarUsage(AstVarScope* nodep, uint32_t flags) { //UINFO(4," MVU "<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: "<prettyName()); + nodep->user5( nodep->user5() | flags ); + if ((nodep->user5() & VU_DLY) && (nodep->user5() & VU_NONDLY)) { + nodep->v3warn(BLKANDNBLK,"Unsupported: Blocked and non-blocking assignments to same variable: "<varp()->prettyName()); } } AstVarScope* createVarSc(AstVarScope* oldvarscp, string name, int width/*0==fromoldvar*/) { @@ -349,7 +350,7 @@ private: if (m_inDly && nodep->lvalue()) { UINFO(4,"AssignDlyVar: "<varp(), VU_DLY); + markVarUsage(nodep->varScopep(), VU_DLY); if (!m_activep) nodep->v3fatalSrc("<= not under sensitivity block"); if (!m_activep->hasClocked()) nodep->v3error("Internal: Blocking <= assignment in non-clocked block, should have converted in V3Active"); AstVarScope* oldvscp = nodep->varScopep(); @@ -411,7 +412,7 @@ private: //UINFO(9,"NBA "<varp(), VU_NONDLY); + markVarUsage(nodep->varScopep(), VU_NONDLY); } } }