From 878204db73d67b5e6a6ec5f583019c8ba3c85a45 Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Sat, 16 Mar 2024 10:35:56 +0000 Subject: [PATCH] Do not feed any empty logic into scheduling (#4972) --- src/V3ActiveTop.cpp | 15 +++++++++++++++ src/V3OrderCFuncEmitter.h | 3 ++- src/V3Sched.cpp | 9 +-------- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/V3ActiveTop.cpp b/src/V3ActiveTop.cpp index 2f4e63bd6..de1f11d43 100644 --- a/src/V3ActiveTop.cpp +++ b/src/V3ActiveTop.cpp @@ -77,6 +77,21 @@ class ActiveTopVisitor final : public VNVisitor { VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); return; } + + // Delete empty procedures + for (AstNode *stmtp = nodep->stmtsp(), *nextp; stmtp; stmtp = nextp) { + nextp = stmtp->nextp(); + if (AstNodeProcedure* const procp = VN_CAST(stmtp, NodeProcedure)) { + if (!procp->stmtsp()) VL_DO_DANGLING(pushDeletep(procp->unlinkFrBack()), stmtp); + } + } + + // Delete empty actives + if (!nodep->stmtsp()) { + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); + return; + } + // Move the SENTREE for each active up to the global level. // This way we'll easily see what clock domains are identical AstSenTree* const wantp = m_finder.getSenTree(sensesp); diff --git a/src/V3OrderCFuncEmitter.h b/src/V3OrderCFuncEmitter.h index ed0c0d4db..37cda41f3 100644 --- a/src/V3OrderCFuncEmitter.h +++ b/src/V3OrderCFuncEmitter.h @@ -116,7 +116,8 @@ public: AstNode* const headp = [&]() -> AstNode* { if (!procp) return logicp; // Not a procedure, handle as a unit AstNode* const stmtsp = procp->stmtsp(); - if (stmtsp) stmtsp->unlinkFrBackWithNext(); + UASSERT_OBJ(stmtsp, procp, "Empty process should have been deleted earlier"); + stmtsp->unlinkFrBackWithNext(); // Procedure is no longer needed and can be deleted right now VL_DO_DANGLING(procp->deleteTree(), procp); return stmtsp; diff --git a/src/V3Sched.cpp b/src/V3Sched.cpp index 5e471ce8d..b00c68d34 100644 --- a/src/V3Sched.cpp +++ b/src/V3Sched.cpp @@ -355,14 +355,9 @@ LogicClasses gatherLogicClasses(AstNetlist* netlistp) { LogicClasses result; netlistp->foreach([&](AstScope* scopep) { - std::vector empty; - scopep->foreach([&](AstActive* activep) { AstSenTree* const senTreep = activep->sensesp(); - if (!activep->stmtsp()) { - // Some AstActives might be empty due to previous optimizations - empty.push_back(activep); - } else if (senTreep->hasStatic()) { + if (senTreep->hasStatic()) { UASSERT_OBJ(!senTreep->sensesp()->nextp(), activep, "static initializer with additional sensitivities"); result.m_static.emplace_back(scopep, activep); @@ -393,8 +388,6 @@ LogicClasses gatherLogicClasses(AstNetlist* netlistp) { } } }); - - for (AstActive* const activep : empty) activep->unlinkFrBack()->deleteTree(); }); return result;