mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Fix performance of V3Trace when many activity blocks (#5372).
This commit is contained in:
parent
f4fe89a8c4
commit
fa32d10f39
1
Changes
1
Changes
@ -16,6 +16,7 @@ Verilator 5.029 devel
|
||||
* Support unconstrained randomization for unions (#5395) (#5396). [Yilou Wang]
|
||||
* Add method to check if there are VPI callbacks of the given type (#5399). [Kaleb Barrett]
|
||||
* Improve Verilation thread pool (#5161). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Fix performance of V3Trace when many activity blocks (#5372). [Deniz Güzel]
|
||||
* Fix REALCVT warning on integral timescale conversions (#5378). [Liam Braun]
|
||||
* Fix dot fallback finding wrong symbols (#5394). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Fix infinite recursion due to recursive functions/tasks (#5398). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
|
@ -221,7 +221,7 @@ void V3Stats::statsStage(const string& name) {
|
||||
|
||||
void V3Stats::infoHeader(std::ofstream& os, const string& prefix) {
|
||||
os << prefix << "Information:\n";
|
||||
os << prefix << " " << V3Options::version() << '\n';
|
||||
os << prefix << " Version: " << V3Options::version() << '\n';
|
||||
os << prefix << " Arguments: " << v3Global.opt.allArgsString() << '\n';
|
||||
os << prefix << " Build jobs: " << v3Global.opt.buildJobs() << '\n';
|
||||
os << prefix << " Verilate jobs: " << v3Global.opt.verilateJobs() << '\n';
|
||||
|
@ -175,6 +175,7 @@ class TraceVisitor final : public VNVisitor {
|
||||
AstScope* const m_topScopep = v3Global.rootp()->topScopep()->scopep(); // The top AstScope
|
||||
AstCFunc* m_cfuncp = nullptr; // C function adding to graph
|
||||
AstCFunc* m_regFuncp = nullptr; // Trace registration function
|
||||
AstCFunc* m_actAllFuncp = nullptr; // Set all activity function
|
||||
AstTraceDecl* m_tracep = nullptr; // Trace function adding to graph
|
||||
AstVarScope* m_activityVscp = nullptr; // Activity variable
|
||||
uint32_t m_activityNumber = 0; // Count of fields in activity variable
|
||||
@ -187,8 +188,10 @@ class TraceVisitor final : public VNVisitor {
|
||||
const uint32_t m_parallelism
|
||||
= v3Global.opt.useTraceParallel() ? static_cast<uint32_t>(v3Global.opt.threads()) : 1;
|
||||
|
||||
VDouble0 m_statUniqSigs; // Statistic tracking
|
||||
VDouble0 m_statSetters; // Statistic tracking
|
||||
VDouble0 m_statSettersSlow; // Statistic tracking
|
||||
VDouble0 m_statUniqCodes; // Statistic tracking
|
||||
VDouble0 m_statUniqSigs; // Statistic tracking
|
||||
|
||||
// All activity numbers applying to a given trace
|
||||
using ActCodeSet = std::set<uint32_t>;
|
||||
@ -395,25 +398,32 @@ class TraceVisitor final : public VNVisitor {
|
||||
return new AstArraySel(flp, new AstVarRef{flp, m_activityVscp, access}, acode);
|
||||
}
|
||||
|
||||
void addActivitySetter(AstNode* insertp, uint32_t code) {
|
||||
AstNode* newActivitySetter(AstNode* insertp, uint32_t code) {
|
||||
++m_statSetters;
|
||||
FileLine* const fl = insertp->fileline();
|
||||
AstAssign* const setterp = new AstAssign{fl, selectActivity(fl, code, VAccess::WRITE),
|
||||
new AstConst{fl, AstConst::BitTrue{}}};
|
||||
if (AstStmtExpr* const stmtp = VN_CAST(insertp, StmtExpr)) {
|
||||
stmtp->addNextHere(setterp);
|
||||
} else if (AstCFunc* const funcp = VN_CAST(insertp, CFunc)) {
|
||||
// If there are awaits, insert the setter after each await
|
||||
if (funcp->isCoroutine() && funcp->stmtsp()) {
|
||||
funcp->stmtsp()->foreachAndNext([&](AstCAwait* awaitp) {
|
||||
AstNode* stmtp = awaitp->backp();
|
||||
while (VN_IS(stmtp, NodeExpr)) stmtp = stmtp->backp();
|
||||
stmtp->addNextHere(setterp->cloneTree(false));
|
||||
});
|
||||
return setterp;
|
||||
}
|
||||
|
||||
AstNode* newActivityAll(AstNode* insertp) {
|
||||
++m_statSettersSlow;
|
||||
if (!m_actAllFuncp) {
|
||||
FileLine* const flp = m_topScopep->fileline();
|
||||
AstCFunc* const funcp = new AstCFunc{flp, "__Vm_traceActivitySetAll", m_topScopep};
|
||||
funcp->slow(true);
|
||||
funcp->isStatic(false);
|
||||
funcp->isLoose(true);
|
||||
m_topScopep->addBlocksp(funcp);
|
||||
for (uint32_t code = 0; code < m_activityNumber; ++code) {
|
||||
AstNode* const setterp = newActivitySetter(insertp, code);
|
||||
funcp->addStmtsp(setterp);
|
||||
}
|
||||
funcp->addStmtsp(setterp);
|
||||
} else {
|
||||
insertp->v3fatalSrc("Bad trace activity vertex");
|
||||
m_actAllFuncp = funcp;
|
||||
}
|
||||
AstCCall* const callp = new AstCCall{insertp->fileline(), m_actAllFuncp};
|
||||
callp->dtypeSetVoid();
|
||||
return callp->makeStmt();
|
||||
}
|
||||
|
||||
void createActivityFlags() {
|
||||
@ -441,14 +451,31 @@ class TraceVisitor final : public VNVisitor {
|
||||
// Insert activity setters
|
||||
for (const V3GraphVertex& vtx : m_graph.vertices()) {
|
||||
if (const TraceActivityVertex* const vtxp = vtx.cast<const TraceActivityVertex>()) {
|
||||
AstNode* setterp = nullptr;
|
||||
if (vtxp->activitySlow()) {
|
||||
setterp = newActivityAll(vtxp->insertp());
|
||||
// Just set all flags in slow code as it should be rare.
|
||||
// This will be rolled up into a loop by V3Reloop.
|
||||
for (uint32_t code = 0; code < m_activityNumber; ++code) {
|
||||
addActivitySetter(vtxp->insertp(), code);
|
||||
}
|
||||
} else if (!vtxp->activityAlways()) {
|
||||
addActivitySetter(vtxp->insertp(), vtxp->activityCode());
|
||||
setterp = newActivitySetter(vtxp->insertp(), vtxp->activityCode());
|
||||
}
|
||||
if (setterp) {
|
||||
AstNode* const insertp = vtxp->insertp();
|
||||
if (AstStmtExpr* const stmtp = VN_CAST(insertp, StmtExpr)) {
|
||||
stmtp->addNextHere(setterp);
|
||||
} else if (AstCFunc* const funcp = VN_CAST(insertp, CFunc)) {
|
||||
// If there are awaits, insert the setter after each await
|
||||
if (funcp->isCoroutine() && funcp->stmtsp()) {
|
||||
funcp->stmtsp()->foreachAndNext([&](AstCAwait* awaitp) {
|
||||
AstNode* stmtp = awaitp->backp();
|
||||
while (VN_IS(stmtp, NodeExpr)) stmtp = stmtp->backp();
|
||||
stmtp->addNextHere(setterp->cloneTree(false));
|
||||
});
|
||||
}
|
||||
funcp->addStmtsp(setterp);
|
||||
} else {
|
||||
insertp->v3fatalSrc("Bad trace activity vertex");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -901,8 +928,10 @@ public:
|
||||
iterate(nodep);
|
||||
}
|
||||
~TraceVisitor() override {
|
||||
V3Stats::addStat("Tracing, Unique traced signals", m_statUniqSigs);
|
||||
V3Stats::addStat("Tracing, Activity setters", m_statSetters);
|
||||
V3Stats::addStat("Tracing, Activity slow blocks", m_statSettersSlow);
|
||||
V3Stats::addStat("Tracing, Unique trace codes", m_statUniqCodes);
|
||||
V3Stats::addStat("Tracing, Unique traced signals", m_statUniqSigs);
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user