Internals: Fix fallout from #6588
This commit is contained in:
parent
7225c902ee
commit
bfb20397d9
|
|
@ -360,45 +360,71 @@ void transformForks(AstNetlist* const netlistp) {
|
||||||
// Replace self with the function calls (no co_await, as we don't want the main
|
// Replace self with the function calls (no co_await, as we don't want the main
|
||||||
// process to suspend whenever any of the children do)
|
// process to suspend whenever any of the children do)
|
||||||
// V3Dead could have removed all statements from the fork, so guard against it
|
// V3Dead could have removed all statements from the fork, so guard against it
|
||||||
if (nodep->forksp()) nodep->addNextHere(nodep->forksp()->unlinkFrBackWithNext());
|
// Inline begins now that they are not needed
|
||||||
if (nodep->stmtsp()) nodep->addNextHere(nodep->stmtsp()->unlinkFrBackWithNext());
|
AstNode* resp = nullptr;
|
||||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
if (AstNode* const declsp = nodep->declsp()) {
|
||||||
|
resp = AstNode::addNext(resp, declsp->unlinkFrBackWithNext());
|
||||||
|
}
|
||||||
|
if (AstNode* const stmtsp = nodep->stmtsp()) {
|
||||||
|
resp = AstNode::addNext(resp, stmtsp->unlinkFrBackWithNext());
|
||||||
|
}
|
||||||
|
while (AstBegin* const beginp = nodep->forksp()) {
|
||||||
|
if (AstNode* const declsp = beginp->declsp()) {
|
||||||
|
resp = AstNode::addNext(resp, declsp->unlinkFrBackWithNext());
|
||||||
|
}
|
||||||
|
if (AstNode* const stmtsp = beginp->stmtsp()) {
|
||||||
|
resp = AstNode::addNext(resp, stmtsp->unlinkFrBackWithNext());
|
||||||
|
}
|
||||||
|
VL_DO_DANGLING(pushDeletep(beginp->unlinkFrBack()), beginp);
|
||||||
|
}
|
||||||
|
if (resp) {
|
||||||
|
nodep->replaceWith(resp);
|
||||||
|
} else {
|
||||||
|
nodep->unlinkFrBack();
|
||||||
|
}
|
||||||
|
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||||
}
|
}
|
||||||
void visit(AstBegin* nodep) override {
|
void visit(AstBegin* nodep) override {
|
||||||
UASSERT_OBJ(m_forkp, nodep, "Begin outside of a fork");
|
UASSERT_OBJ(m_forkp, nodep, "Begin outside of a fork");
|
||||||
// Start with children, so later we only find awaits that are actually in this begin
|
// Start with children, so later we only find awaits that are actually in this begin
|
||||||
m_beginHasAwaits = false;
|
m_beginHasAwaits = false;
|
||||||
iterateChildrenConst(nodep);
|
iterateChildrenConst(nodep);
|
||||||
if (!nodep->stmtsp()) {
|
if (!nodep->stmtsp()) return;
|
||||||
nodep->unlinkFrBack();
|
if (!m_beginHasAwaits && !nodep->needProcess()) return;
|
||||||
} else if (m_beginHasAwaits || nodep->needProcess()) {
|
|
||||||
UASSERT_OBJ(!nodep->name().empty(), nodep, "Begin needs a name");
|
UASSERT_OBJ(!nodep->name().empty(), nodep, "Begin needs a name");
|
||||||
// Create a function to put this begin's statements in
|
// Create a function to put this begin's statements in
|
||||||
FileLine* const flp = nodep->fileline();
|
FileLine* const flp = nodep->fileline();
|
||||||
AstCFunc* const newfuncp = new AstCFunc{
|
AstCFunc* const newfuncp = new AstCFunc{flp, m_funcp->name() + "__" + nodep->name(),
|
||||||
flp, m_funcp->name() + "__" + nodep->name(), m_funcp->scopep(), "VlCoroutine"};
|
m_funcp->scopep(), "VlCoroutine"};
|
||||||
|
|
||||||
m_funcp->addNextHere(newfuncp);
|
m_funcp->addNextHere(newfuncp);
|
||||||
newfuncp->isLoose(m_funcp->isLoose());
|
newfuncp->isLoose(m_funcp->isLoose());
|
||||||
newfuncp->slow(m_funcp->slow());
|
newfuncp->slow(m_funcp->slow());
|
||||||
newfuncp->isConst(m_funcp->isConst());
|
newfuncp->isConst(m_funcp->isConst());
|
||||||
newfuncp->declPrivate(true);
|
newfuncp->declPrivate(true);
|
||||||
// Replace the begin with a call to the newly created function
|
// Create the call to the function
|
||||||
AstCCall* const callp = new AstCCall{flp, newfuncp};
|
AstCCall* const callp = new AstCCall{flp, newfuncp};
|
||||||
callp->dtypeSetVoid();
|
callp->dtypeSetVoid();
|
||||||
nodep->replaceWith(callp->makeStmt());
|
|
||||||
// If we're in a class, add a vlSymsp arg
|
// If we're in a class, add a vlSymsp arg
|
||||||
if (m_inClass) {
|
if (m_inClass) {
|
||||||
newfuncp->addStmtsp(new AstCStmt{flp, "VL_KEEP_THIS;"});
|
newfuncp->addStmtsp(new AstCStmt{flp, "VL_KEEP_THIS;"});
|
||||||
newfuncp->argTypes(EmitCUtil::symClassVar());
|
newfuncp->argTypes(EmitCUtil::symClassVar());
|
||||||
callp->argTypes("vlSymsp");
|
callp->argTypes("vlSymsp");
|
||||||
}
|
}
|
||||||
// Put the begin's statements in the function, delete the begin
|
// Put the begin's statements in the function
|
||||||
newfuncp->addStmtsp(nodep->stmtsp()->unlinkFrBackWithNext());
|
if (AstNode* const declsp = nodep->declsp()) {
|
||||||
|
newfuncp->addStmtsp(declsp->unlinkFrBackWithNext());
|
||||||
|
}
|
||||||
|
if (AstNode* const stmtsp = nodep->stmtsp()) {
|
||||||
|
newfuncp->addStmtsp(stmtsp->unlinkFrBackWithNext());
|
||||||
|
}
|
||||||
|
// Replace the body of the begin with a call to the newly created function
|
||||||
|
nodep->addStmtsp(callp->makeStmt());
|
||||||
|
// Propagate if needs process
|
||||||
if (nodep->needProcess()) {
|
if (nodep->needProcess()) {
|
||||||
newfuncp->setNeedProcess();
|
newfuncp->setNeedProcess();
|
||||||
newfuncp->addStmtsp(
|
newfuncp->addStmtsp(new AstCStmt{flp, "vlProcess->state(VlProcess::FINISHED);"});
|
||||||
new AstCStmt{flp, "vlProcess->state(VlProcess::FINISHED);"});
|
|
||||||
}
|
}
|
||||||
if (!m_beginHasAwaits) {
|
if (!m_beginHasAwaits) {
|
||||||
// co_return at the end (either that or a co_await is required in a coroutine
|
// co_return at the end (either that or a co_await is required in a coroutine
|
||||||
|
|
@ -407,12 +433,6 @@ void transformForks(AstNetlist* const netlistp) {
|
||||||
m_awaitMoved = true;
|
m_awaitMoved = true;
|
||||||
}
|
}
|
||||||
remapLocals(newfuncp, callp);
|
remapLocals(newfuncp, callp);
|
||||||
} else {
|
|
||||||
// The begin has neither awaits nor a process::self call, just inline the
|
|
||||||
// statements
|
|
||||||
nodep->replaceWith(nodep->stmtsp()->unlinkFrBackWithNext());
|
|
||||||
}
|
|
||||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
|
||||||
}
|
}
|
||||||
void visit(AstCAwait* nodep) override {
|
void visit(AstCAwait* nodep) override {
|
||||||
m_beginHasAwaits = true;
|
m_beginHasAwaits = true;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue