From 5515eed0b67422a3219027a98fed9aea203c0e7a Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Sun, 17 Oct 2021 10:29:17 +0100 Subject: [PATCH] Make AstTopScope accessible from AstNetlist AstTopScope is a singleton node and making it accessible without a traversal simplifies some code and decouple some other. --- src/V3ActiveTop.cpp | 9 +-------- src/V3AstNodes.h | 30 +++++++++++++++++++++--------- src/V3GenClk.cpp | 7 +------ src/V3Order.cpp | 2 -- src/V3Scope.cpp | 3 +-- src/V3SenTree.h | 23 ++++++++++------------- src/V3Task.cpp | 6 +----- src/V3Trace.cpp | 8 +------- src/V3TraceDecl.cpp | 3 +-- 9 files changed, 37 insertions(+), 54 deletions(-) diff --git a/src/V3ActiveTop.cpp b/src/V3ActiveTop.cpp index 3fe652d58..52556d5ba 100644 --- a/src/V3ActiveTop.cpp +++ b/src/V3ActiveTop.cpp @@ -45,19 +45,12 @@ private: AstUser1InUse m_inuser1; // STATE - AstTopScope* m_topscopep = nullptr; // Top scope for adding sentrees under - SenTreeFinder m_finder; // Find global sentree's and add them + SenTreeFinder m_finder; // Find global sentree's / add them under the AstTopScope // METHODS VL_DEBUG_FUNC; // Declare debug() // VISITORS - virtual void visit(AstTopScope* nodep) override { - m_topscopep = nodep; - m_finder.init(m_topscopep); - iterateChildren(nodep); - m_topscopep = nullptr; - } virtual void visit(AstNodeModule* nodep) override { // Create required actives and add to module // We can start ordering at a module, or a scope diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 303bf7894..b109c4928 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -2333,19 +2333,22 @@ public: }; class AstTopScope final : public AstNode { - // In the top level netlist, a complete scope tree - // There may be two of these, when we support "rare" and "usual" splitting - // Parents: topMODULE - // Children: SCOPEs -public: + // A singleton, held under the top level AstModule. Holds the top level AstScope, + // and after V3ActiveTop, the global list of AstSenTrees (list of unique sensitivity lists). + // Parent: Top level AstModule + // Children: AstSenTree, AstScope + friend class AstNetlist; // Only the AstNetlist can create one AstTopScope(FileLine* fl, AstScope* ascopep) : ASTGEN_SUPER_TopScope(fl) { - addNOp2p(ascopep); + addOp2p(ascopep); } + +public: ASTNODE_NODE_FUNCS(TopScope) - AstNode* stmtsp() const { return op1p(); } - void addStmtsp(AstNode* nodep) { addOp1p(nodep); } - AstScope* scopep() const { return VN_AS(op2p(), Scope); } // op1 = AstVarScope's + virtual bool maybePointedTo() const override { return true; } + AstSenTree* senTreesp() const { return VN_AS(op1p(), SenTree); } + void addSenTreep(AstSenTree* nodep) { addOp1p((AstNode*)nodep); } + AstScope* scopep() const { return VN_AS(op2p(), Scope); } }; class AstVarScope final : public AstNode { @@ -9191,6 +9194,7 @@ private: AstCFunc* m_evalp = nullptr; // The '_eval' function AstExecGraph* m_execGraphp = nullptr; // Execution MTask graph for threads>1 mode AstVarScope* m_dpiExportTriggerp = nullptr; // The DPI export trigger variable + AstTopScope* m_topScopep = nullptr; // The singleton AstTopScope under the top module VTimescale m_timeunit; // Global time unit VTimescale m_timeprecision; // Global time precision bool m_changeRequest = false; // Have _change_request method @@ -9202,6 +9206,7 @@ public: BROKEN_RTN(m_dollarUnitPkgp && !m_dollarUnitPkgp->brokeExists()); BROKEN_RTN(m_evalp && !m_evalp->brokeExists()); BROKEN_RTN(m_dpiExportTriggerp && !m_dpiExportTriggerp->brokeExists()); + BROKEN_RTN(m_topScopep && !m_topScopep->brokeExists()); return nullptr; } virtual string name() const override { return "$root"; } @@ -9239,6 +9244,13 @@ public: void execGraphp(AstExecGraph* graphp) { m_execGraphp = graphp; } AstVarScope* dpiExportTriggerp() const { return m_dpiExportTriggerp; } void dpiExportTriggerp(AstVarScope* varScopep) { m_dpiExportTriggerp = varScopep; } + AstTopScope* topScopep() const { return m_topScopep; } + void createTopScope(AstScope* scopep) { + UASSERT(scopep, "Must not be nullptr"); + UASSERT_OBJ(!m_topScopep, scopep, "TopScope already exits"); + m_topScopep = new AstTopScope{scopep->modp()->fileline(), scopep}; + scopep->modp()->addStmtp(v3Global.rootp()->topScopep()); + } VTimescale timeunit() const { return m_timeunit; } void timeunit(const VTimescale& value) { m_timeunit = value; } VTimescale timeprecision() const { return m_timeprecision; } diff --git a/src/V3GenClk.cpp b/src/V3GenClk.cpp index f766b7a4a..cf7c4fc54 100644 --- a/src/V3GenClk.cpp +++ b/src/V3GenClk.cpp @@ -49,7 +49,7 @@ private: // STATE AstActive* m_activep = nullptr; // Inside activate statement AstNodeModule* m_topModp; // Top module - AstScope* m_scopetopp = nullptr; // Scope under TOPSCOPE + AstScope* const m_scopetopp = v3Global.rootp()->topScopep()->scopep(); // The top AstScope // METHODS AstVarScope* genInpClk(AstVarScope* vscp) { @@ -93,11 +93,6 @@ private: // VISITORS virtual void visit(AstTopScope* nodep) override { AstNode::user2ClearTree(); // user2p() used on entire tree - - AstScope* scopep = nodep->scopep(); - UASSERT_OBJ(scopep, nodep, "No scope found on top level"); - m_scopetopp = scopep; - iterateChildren(nodep); } //---- diff --git a/src/V3Order.cpp b/src/V3Order.cpp index 0c1994fa3..98cb21f7e 100644 --- a/src/V3Order.cpp +++ b/src/V3Order.cpp @@ -941,8 +941,6 @@ private: m_activep = nullptr; m_topScopep = nodep; m_scopetopp = nodep->scopep(); - // Find global SenTrees - m_finder.init(m_topScopep); // ProcessDomainsIterate will use these when it needs to move // something to a combodomain. This saves a ton of find() operations. AstSenTree* combp diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp index d9ed9ce9f..d9b73b4de 100644 --- a/src/V3Scope.cpp +++ b/src/V3Scope.cpp @@ -132,8 +132,7 @@ private: AstNode::user1ClearTree(); m_modp = nodep; if (m_modp->isTop()) { - AstTopScope* topscp = new AstTopScope(nodep->fileline(), m_scopep); - m_modp->addStmtp(topscp); + v3Global.rootp()->createTopScope(m_scopep); } else { m_modp->addStmtp(m_scopep); } diff --git a/src/V3SenTree.h b/src/V3SenTree.h index 5abca02f6..243d493fa 100644 --- a/src/V3SenTree.h +++ b/src/V3SenTree.h @@ -74,14 +74,21 @@ private: class SenTreeFinder final { private: // STATE - AstTopScope* m_topScopep = nullptr; // Top scope to add global SenTrees to + AstTopScope* const m_topScopep; // Top scope to add global SenTrees to SenTreeSet m_trees; // Set of global SenTrees VL_UNCOPYABLE(SenTreeFinder); public: // CONSTRUCTORS - SenTreeFinder() = default; + SenTreeFinder() + : m_topScopep{v3Global.rootp()->topScopep()} { + // Gather existing global SenTrees + for (AstSenTree* nodep = m_topScopep->senTreesp(); nodep; + nodep = VN_AS(nodep->nextp(), SenTree)) { + m_trees.add(nodep); + } + } // METHODS AstSenTree* getSenTree(AstSenTree* senTreep) { @@ -90,23 +97,13 @@ public: AstSenTree* treep = m_trees.find(senTreep); // Not found, form a new one if (!treep) { - UASSERT(m_topScopep, "Never called init()"); treep = senTreep->cloneTree(false); - m_topScopep->addStmtsp(treep); + m_topScopep->addSenTreep(treep); UINFO(8, " New SENTREE " << treep << endl); m_trees.add(treep); } return treep; } - - void init(AstTopScope* topScopep) { - // Keep hold of top scope so we can add global SenTrees later - m_topScopep = topScopep; - // Gather existing global SenTrees - for (AstNode* nodep = topScopep->stmtsp(); nodep; nodep = nodep->nextp()) { - if (AstSenTree* senTreep = VN_CAST(nodep, SenTree)) m_trees.add(senTreep); - } - } }; #endif // Guard diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 8db34120f..73042fe34 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -423,7 +423,7 @@ private: // STATE TaskStateVisitor* m_statep; // Common state between visitors AstNodeModule* m_modp = nullptr; // Current module - AstTopScope* m_topScopep = nullptr; // Current top scope + AstTopScope* const m_topScopep = v3Global.rootp()->topScopep(); // The AstTopScope AstScope* m_scopep = nullptr; // Current scope InsertMode m_insMode = IM_BEFORE; // How to insert AstNode* m_insStmtp = nullptr; // Where to insert statement @@ -1392,10 +1392,6 @@ private: iterateChildren(nodep); } } - virtual void visit(AstTopScope* nodep) override { - m_topScopep = nodep; - iterateChildren(nodep); - } virtual void visit(AstScope* nodep) override { m_scopep = nodep; m_insStmtp = nullptr; diff --git a/src/V3Trace.cpp b/src/V3Trace.cpp index bf878eb18..a2b3553da 100644 --- a/src/V3Trace.cpp +++ b/src/V3Trace.cpp @@ -169,7 +169,7 @@ private: // STATE AstNodeModule* m_topModp = nullptr; // Module to add variables to - AstScope* m_topScopep = nullptr; // Scope to add variables to + AstScope* const m_topScopep = v3Global.rootp()->topScopep()->scopep(); // The top AstScope AstCFunc* m_cfuncp = nullptr; // C function adding to graph AstCFunc* m_regFuncp = nullptr; // Trace registration function AstTraceDecl* m_tracep = nullptr; // Trace function adding to graph @@ -808,12 +808,6 @@ private: if (nodep->isTop()) m_topModp = nodep; iterateChildren(nodep); } - virtual void visit(AstTopScope* nodep) override { - AstScope* const scopep = nodep->scopep(); - UASSERT_OBJ(scopep, nodep, "No scope found on top level"); - m_topScopep = scopep; - iterateChildren(nodep); - } virtual void visit(AstCCall* nodep) override { UINFO(8, " CCALL " << nodep << endl); if (!m_finding && !nodep->user2()) { diff --git a/src/V3TraceDecl.cpp b/src/V3TraceDecl.cpp index d1bcbb66e..a37ddb8c8 100644 --- a/src/V3TraceDecl.cpp +++ b/src/V3TraceDecl.cpp @@ -37,7 +37,7 @@ private: // NODE STATE // STATE - AstScope* m_topScopep = nullptr; // Current top scope + AstScope* const m_topScopep = v3Global.rootp()->topScopep()->scopep(); // The top AstScope AstCFunc* m_initFuncp = nullptr; // Trace function being built AstCFunc* m_initSubFuncp = nullptr; // Trace function being built (under m_init) int m_initSubStmts = 0; // Number of statements in function @@ -136,7 +136,6 @@ private: // VISITORS virtual void visit(AstTopScope* nodep) override { - m_topScopep = nodep->scopep(); // Create the trace init function m_initFuncp = newCFunc("trace_init_top"); // Create initial sub function