Make AstTopScope accessible from AstNetlist

AstTopScope is a singleton node and making it accessible without a
traversal simplifies some code and decouple some other.
This commit is contained in:
Geza Lore 2021-10-17 10:29:17 +01:00
parent 381c87a1eb
commit 5515eed0b6
9 changed files with 37 additions and 54 deletions

View File

@ -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

View File

@ -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; }

View File

@ -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);
}
//----

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;

View File

@ -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()) {

View File

@ -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