Partial cleanup of V3Param. No functional change.

This commit is contained in:
Geza Lore 2022-04-22 21:48:03 +01:00
parent 5f0e1fae7f
commit 8189416d0c

View File

@ -847,78 +847,74 @@ class ParamVisitor final : public VNVisitor {
ParamProcessor m_processor; // De-parameterize a cell, build modules ParamProcessor m_processor; // De-parameterize a cell, build modules
UnrollStateful m_unroller; // Loop unroller UnrollStateful m_unroller; // Loop unroller
AstNodeModule* m_modp = nullptr; // Current module being processed bool m_iterateModule = false; // Iterating module body
string m_generateHierName; // Generate portion of hierarchy name string m_generateHierName; // Generate portion of hierarchy name
string m_unlinkedTxt; // Text for AstUnlinkedRef string m_unlinkedTxt; // Text for AstUnlinkedRef
std::deque<AstCell*> m_cellps; // Cells left to process (in this module) std::deque<AstCell*> m_cellps; // Cells left to process (in current module)
std::multimap<int, AstNodeModule*> m_todoModps; // Modules left to process
// METHODS // METHODS
VL_DEBUG_FUNC; // Declare debug() VL_DEBUG_FUNC; // Declare debug()
void visitCellDeparam(AstCell* nodep, const string& someInstanceName) { void visitCells(AstNodeModule* nodep) {
// Cell: Check for parameters in the instantiation. UASSERT_OBJ(!m_iterateModule, nodep, "Should not nest");
iterateChildren(nodep); std::multimap<int, AstNodeModule*> workQueue;
UASSERT_OBJ(nodep->modp(), nodep, "Not linked?"); workQueue.emplace(nodep->level(), nodep);
m_processor.cellDeparam(nodep, m_modp, someInstanceName); m_generateHierName = "";
// Remember to process the child module at the end of the module m_iterateModule = true;
m_todoModps.emplace(nodep->modp()->level(), nodep->modp());
}
void visitModules() {
// Loop on all modules left to process
// Hitting a cell adds to the appropriate level of this level-sorted list,
// so since cells originally exist top->bottom we process in top->bottom order too.
while (!m_todoModps.empty()) {
const auto itm = m_todoModps.cbegin();
AstNodeModule* const nodep = itm->second;
m_todoModps.erase(itm);
if (!nodep->user5SetOnce()) { // Process once; note clone() must clear so we do it
// again
m_modp = nodep;
UINFO(4, " MOD " << nodep << endl);
if (m_modp->someInstanceName().empty()) {
m_modp->someInstanceName(m_modp->origName());
}
iterateChildren(nodep);
// Note above iterate may add to m_todoModps // Visit all cells under module, recursively
// do {
// Process interface cells, then non-interface which may ref an interface cell const auto itm = workQueue.cbegin();
for (int nonIf = 0; nonIf < 2; ++nonIf) { AstNodeModule* const modp = itm->second;
for (AstCell* const cellp : m_cellps) { workQueue.erase(itm);
if ((nonIf == 0 && VN_IS(cellp->modp(), Iface))
|| (nonIf == 1 && !VN_IS(cellp->modp(), Iface))) { // Process once; note user5 will be cleared on specialization, so we will do the
string someInstanceName(m_modp->someInstanceName()); // specialized module if needed
if (const string* const genHierNamep = (string*)cellp->user5p()) { if (modp->user5SetOnce()) continue;
someInstanceName += *genHierNamep;
cellp->user5p(nullptr); // TODO: this really should be an assert, but classes and hier_blocks are special...
VL_DO_DANGLING(delete genHierNamep, genHierNamep); if (modp->someInstanceName().empty()) modp->someInstanceName(modp->origName());
}
VL_DO_DANGLING(visitCellDeparam(cellp, someInstanceName), cellp); // Iterate the body
} iterateChildren(modp);
// Process interface cells, then non-interface cells, which may reference an interface
// cell.
for (bool doInterface : {true, false}) {
for (AstCell* const cellp : m_cellps) {
if (doInterface != VN_IS(cellp->modp(), Iface)) continue;
// Visit parameters in the instantiation.
iterateChildren(cellp);
// Update path
string someInstanceName(modp->someInstanceName());
if (const string* const genHierNamep = cellp->user5u().to<string*>()) {
someInstanceName += *genHierNamep;
cellp->user5p(nullptr);
VL_DO_DANGLING(delete genHierNamep, genHierNamep);
} }
// Apply parameter specialization
m_processor.cellDeparam(cellp, modp, someInstanceName);
// Add the (now potentially specialized) child module to the work queue
workQueue.emplace(cellp->modp()->level(), cellp->modp());
} }
m_cellps.clear();
m_modp = nullptr;
UINFO(4, " MOD-done\n");
} }
} m_cellps.clear();
} while (!workQueue.empty());
m_iterateModule = false;
} }
// VISITORS // VISITORS
virtual void visit(AstNodeModule* nodep) override { virtual void visit(AstNodeModule* nodep) override {
if (nodep->dead()) { if (nodep->recursiveClone()) nodep->dead(true); // Fake, made for recursive elimination
UINFO(4, " MOD-dead. " << nodep << endl); // Marked by LinkDot if (nodep->dead()) return; // Marked by LinkDot (and above)
return;
} else if (nodep->recursiveClone()) { // Warn on unsupported parametrised class
// Fake, made for recursive elimination if (VN_IS(nodep, Class)) {
UINFO(4, " MOD-recursive-dead. " << nodep << endl);
nodep->dead(true); // So Dead checks won't count references to it
return;
}
//
if (!nodep->dead() && VN_IS(nodep, Class)) {
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) { for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
if (const AstVar* const varp = VN_CAST(stmtp, Var)) { if (const AstVar* const varp = VN_CAST(stmtp, Var)) {
if (varp->isParam()) { if (varp->isParam()) {
@ -927,24 +923,21 @@ class ParamVisitor final : public VNVisitor {
} }
} }
} }
//
if (m_modp) { if (m_iterateModule) { // Iterating body
UINFO(4, " MOD-under-MOD. " << nodep << endl); UINFO(4, " MOD-under-MOD. " << nodep << endl);
iterateChildren(nodep); iterateChildren(nodep);
} else if (nodep->level() <= 2 // Haven't added top yet, so level 2 is the top return;
|| VN_IS(nodep, Class) // Nor moved classes }
|| VN_IS(nodep, Package)) { // Likewise haven't done wrapTopPackages yet
// Add request to END of modules left to process // Start traversal at root-like things
m_todoModps.emplace(nodep->level(), nodep); if (nodep->level() <= 2 // Haven't added top yet, so level 2 is the top
m_generateHierName = ""; || VN_IS(nodep, Class) // Nor moved classes
visitModules(); || VN_IS(nodep, Package)) { // Likewise haven't done wrapTopPackages yet
} else if (nodep->user5()) { visitCells(nodep);
UINFO(4, " MOD-done " << nodep << endl); // Already did it
} else {
// Should have been done by now, if not dead
UINFO(4, " MOD-dead? " << nodep << endl);
} }
} }
virtual void visit(AstCell* nodep) override { virtual void visit(AstCell* nodep) override {
// Must do ifaces first, so push to list and do in proper order // Must do ifaces first, so push to list and do in proper order
string* const genHierNamep = new string(m_generateHierName); string* const genHierNamep = new string(m_generateHierName);