Internals: Remove VlNow (#4089)

`VlNow{}` is completely unnecessary, as coroutines are always on the
heap (unless optimized out). Also fix access of var ref passed to forked processes.
This commit is contained in:
Krzysztof Bieganski
2023-04-06 10:31:52 -04:00
committed by GitHub
parent 05660d1118
commit cdb61842d6
3 changed files with 17 additions and 34 deletions
+11 -12
View File
@@ -272,22 +272,20 @@ void transformForks(AstNetlist* const netlistp) {
// If it a fork sync or an intra-assignment variable, pass it by value
const bool passByValue = (dtypep && dtypep->isForkSync())
|| VString::startsWith(varp->name(), "__Vintra");
// Only handle vars passed by value or locals declared before the fork
if (!passByValue && (!varp->user1() || !varp->isFuncLocal())) return;
if (passByValue) {
// We can just pass it to the new function
} else if (!varp->user1() || !varp->isFuncLocal()) {
// Not func local, or not declared before the fork. Their lifetime is longer
// than the forked process. Skip
return;
} else if (m_forkp->joinType().join()) {
// If it's fork..join, we can refer to variables from the parent process
if (!m_funcp->user1SetOnce()) { // Only do this once per function
// Move all locals to the heap before the fork
AstCExpr* const nowp
= new AstCExpr{m_forkp->fileline(), "VlNow{}", 0, true};
nowp->dtypeSetVoid(); // TODO: this is sloppy but harmless
AstCAwait* const awaitp = new AstCAwait{m_forkp->fileline(), nowp};
awaitp->dtypeSetVoid();
m_forkp->addHereThisAsNext(awaitp->makeStmt());
}
} else {
// TODO: It is possible to relax this by allowing the use of such variables up
// until the first await. Also, variables defined within a forked process
// (inside a begin) are extracted out by V3Begin, so they also trigger this
// error. Preventing this (or detecting such cases and moving the vars back)
// would also allow for using them freely.
refp->v3warn(E_UNSUPPORTED, "Unsupported: variable local to a forking process "
"accessed in a fork..join_any or fork..join_none");
return;
@@ -305,7 +303,8 @@ void transformForks(AstNetlist* const netlistp) {
= new AstVarScope{newvarp->fileline(), funcp->scopep(), newvarp};
funcp->scopep()->addVarsp(newvscp);
vscp->user2p(newvscp);
callp->addArgsp(new AstVarRef{refp->fileline(), vscp, VAccess::READ});
callp->addArgsp(new AstVarRef{
refp->fileline(), vscp, passByValue ? VAccess::READ : VAccess::READWRITE});
}
AstVarScope* const newvscp = VN_AS(vscp->user2p(), VarScope);
refp->varScopep(newvscp);