Fix fork/join_non disable by name race.
This commit is contained in:
parent
81c898ef2f
commit
6f154fa1ba
|
|
@ -582,6 +582,39 @@ class ForkVisitor final : public VNVisitor {
|
|||
// We did wrap the body
|
||||
return true;
|
||||
}
|
||||
static bool isForkJoinNoneSentinelDelay(const AstNode* const nodep) {
|
||||
const AstDelay* const delayp = VN_CAST(nodep, Delay);
|
||||
if (!delayp) return false;
|
||||
const AstConst* const constp = VN_CAST(delayp->lhsp(), Const);
|
||||
return constp && (constp->toUQuad() == std::numeric_limits<uint64_t>::max());
|
||||
}
|
||||
static bool isDisableQueuePushSelfStmt(const AstNode* const nodep) {
|
||||
// Detect LinkJump-generated registration:
|
||||
// __VprocessQueue_*.push_back(std::process::self())
|
||||
const AstStmtExpr* const stmtExprp = VN_CAST(nodep, StmtExpr);
|
||||
if (!stmtExprp) return false;
|
||||
const AstCMethodHard* const methodp = VN_CAST(stmtExprp->exprp(), CMethodHard);
|
||||
if (!methodp || methodp->name() != "push_back") return false;
|
||||
const AstVarRef* const queueRefp = VN_CAST(methodp->fromp(), VarRef);
|
||||
return queueRefp && queueRefp->name().rfind("__VprocessQueue_", 0) == 0;
|
||||
}
|
||||
static void moveForkSentinelAfterDisableQueuePushes(AstBegin* const beginp) {
|
||||
AstNode* const firstStmtp = beginp->stmtsp();
|
||||
if (!isForkJoinNoneSentinelDelay(firstStmtp)) return;
|
||||
|
||||
AstNode* insertBeforep = firstStmtp->nextp();
|
||||
while (insertBeforep && isDisableQueuePushSelfStmt(insertBeforep)) {
|
||||
insertBeforep = insertBeforep->nextp();
|
||||
}
|
||||
if (insertBeforep == firstStmtp->nextp()) return;
|
||||
|
||||
AstNode* const delayp = firstStmtp->unlinkFrBackWithNext();
|
||||
if (insertBeforep) {
|
||||
insertBeforep->addHereThisAsNext(delayp);
|
||||
} else {
|
||||
beginp->addStmtsp(delayp);
|
||||
}
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
|
|
@ -619,6 +652,7 @@ class ForkVisitor final : public VNVisitor {
|
|||
new AstConst{fl, AstConst::Unsized64{}, std::numeric_limits<uint64_t>::max()},
|
||||
false};
|
||||
itemp->stmtsp()->addHereThisAsNext(delayp);
|
||||
moveForkSentinelAfterDisableQueuePushes(itemp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,10 @@
|
|||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('linter')
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.lint()
|
||||
test.compile(timing_loop=True, verilator_flags2=["--timing"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
Loading…
Reference in New Issue