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;