From aa28a8d1e180e09ec2d9686b518f12c8fa7090d6 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 6 Sep 2025 08:35:07 -0400 Subject: [PATCH] Fix cell scoping performance (#6059). --- Changes | 1 + docs/spelling.txt | 1 + src/V3Scope.cpp | 36 ++++++++++++++++++++---------------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/Changes b/Changes index e998f6257..c92e1b1b7 100644 --- a/Changes +++ b/Changes @@ -17,6 +17,7 @@ Verilator 5.041 devel * Improve automatic selection of logic for DFG synthesis (#6370). [Geza Lore] * Improve `covergroup with function sample` handling (#6387). [Jakub Wasilewski] * Optimize dead functions without references (#6380). [Artur Bieniek, Antmicro Ltd.] +* Fix cell scoping performance (#6059). [Jerry Tianchen] * Fix while loop hang on timing-delayed assignment (#6343) (#6354). [Krzysztof Bieganski, Antmicro Ltd.] * Fix driver analysis of partially assigned variables (#6364) (#6378). [Geza Lore] * Fix V3Hash MacOS ambiguity (#6350). [Lan Zongwei] diff --git a/docs/spelling.txt b/docs/spelling.txt index 99593957d..47e4310a1 100644 --- a/docs/spelling.txt +++ b/docs/spelling.txt @@ -428,6 +428,7 @@ Terpstra Thiede Thierry Thyer +Tianchen Tianrui Tichelaar Timi diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp index 560e1b40e..bbb691e89 100644 --- a/src/V3Scope.cpp +++ b/src/V3Scope.cpp @@ -115,23 +115,27 @@ class ScopeVisitor final : public VNVisitor { nodep, scopename, m_aboveScopep, m_aboveCellp}; if (VN_IS(nodep, Package)) m_packageScopes.emplace(nodep, m_scopep); - // Now for each child cell, iterate the module this cell points to + // Get list of cells before we edit, to avoid excess visits (issue #6059) + std::deque cells; for (AstNode* cellnextp = nodep->stmtsp(); cellnextp; cellnextp = cellnextp->nextp()) { - if (AstCell* const cellp = VN_CAST(cellnextp, Cell)) { - VL_RESTORER(m_scopep); // Protects m_scopep set in called module - // which is "above" in this code, but later in code execution order - VL_RESTORER(m_aboveCellp); - VL_RESTORER(m_aboveScopep); - { - m_aboveCellp = cellp; - m_aboveScopep = m_scopep; - AstNodeModule* const modp = cellp->modp(); - UASSERT_OBJ(modp, cellp, "Unlinked mod"); - iterate(modp); // Recursive call to visit(AstNodeModule) - if (VN_IS(modp, Iface)) { - // Remember newly created scope - cellp->user2p(m_scopep); - } + if (AstCell* const cellp = VN_CAST(cellnextp, Cell)) cells.push_back(cellp); + } + + // Now for each child cell, iterate the module this cell points to + for (AstCell* const cellp : cells) { + VL_RESTORER(m_scopep); // Protects m_scopep set in called module + // which is "above" in this code, but later in code execution order + VL_RESTORER(m_aboveCellp); + VL_RESTORER(m_aboveScopep); + { + m_aboveCellp = cellp; + m_aboveScopep = m_scopep; + AstNodeModule* const modp = cellp->modp(); + UASSERT_OBJ(modp, cellp, "Unlinked mod"); + iterate(modp); // Recursive call to visit(AstNodeModule) + if (VN_IS(modp, Iface)) { + // Remember newly created scope + cellp->user2p(m_scopep); } } }