additional cleanup

This commit is contained in:
em2machine 2025-12-22 12:25:27 +01:00
parent 0a517f260d
commit b174ee4a31
3 changed files with 37 additions and 53 deletions

View File

@ -29,7 +29,6 @@
#include "V3Stats.h" #include "V3Stats.h"
// EOM
#include "V3UndrivenCapture.h" #include "V3UndrivenCapture.h"
#include <vector> #include <vector>
@ -54,7 +53,6 @@ class UndrivenVarEntry final {
const FileLine* m_nodeFileLinep = nullptr; // File line of varref if driven, else nullptr const FileLine* m_nodeFileLinep = nullptr; // File line of varref if driven, else nullptr
bool m_underGen = false; // Under a generate bool m_underGen = false; // Under a generate
// EOM
const AstNode* m_callNodep = nullptr; // call node if driven via writeSummary, else nullptr const AstNode* m_callNodep = nullptr; // call node if driven via writeSummary, else nullptr
const FileLine* m_callFileLinep = nullptr; // file line of call node if driven via summary const FileLine* m_callFileLinep = nullptr; // file line of call node if driven via summary
@ -286,7 +284,6 @@ public:
} }
} }
// EOM
void drivenViaCall(const AstNode* nodep, const FileLine* fileLinep) { void drivenViaCall(const AstNode* nodep, const FileLine* fileLinep) {
drivenWhole(); drivenWhole();
if (!m_callNodep) { if (!m_callNodep) {
@ -322,7 +319,6 @@ class UndrivenVisitor final : public VNVisitorConst {
const AstAlways* m_alwaysp = nullptr; // Current always of either type const AstAlways* m_alwaysp = nullptr; // Current always of either type
const AstAlways* m_alwaysCombp = nullptr; // Current always if combo, otherwise nullptr const AstAlways* m_alwaysCombp = nullptr; // Current always if combo, otherwise nullptr
// EOM
V3UndrivenCapture* const m_capturep = nullptr; V3UndrivenCapture* const m_capturep = nullptr;
const bool m_enableWriteSummary = false; const bool m_enableWriteSummary = false;
@ -443,21 +439,9 @@ class UndrivenVisitor final : public VNVisitorConst {
} }
} }
// EOM
// If writeSummary is enabled, task/function definitions are treated as non-executed. // If writeSummary is enabled, task/function definitions are treated as non-executed.
// Their effects are applied at call sites via writeSummary(), so don't let definition // Their effects are applied at call sites via writeSummary(), so don't let definition
// traversal create phantom "other writes" for MULTIDRIVEN. // traversal create phantom "other writes" for MULTIDRIVEN.
//const auto inExecutedContext = [this, nodep]() {
// return !(m_enableWriteSummary && m_taskp && !m_alwaysp && !m_inContAssign &&
// !m_inInitialStatic
// && !m_inBBox && !m_taskp->dpiExport() && !nodep->varp()->isFuncLocal());
//};
//if (!inExecutedContext()) {
// return;
//}
if (m_enableWriteSummary && m_taskp && !m_alwaysp && !m_inContAssign && !m_inInitialStatic if (m_enableWriteSummary && m_taskp && !m_alwaysp && !m_inContAssign && !m_inInitialStatic
&& !m_inBBox && !m_taskp->dpiExport()) { && !m_inBBox && !m_taskp->dpiExport()) {
AstVar* const retVarp = VN_CAST(m_taskp->fvarp(), Var); AstVar* const retVarp = VN_CAST(m_taskp->fvarp(), Var);
@ -477,11 +461,8 @@ class UndrivenVisitor final : public VNVisitorConst {
&& !VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType) && !VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType)
&& nodep->fileline() != entryp->getNodeFileLinep() && nodep->fileline() != entryp->getNodeFileLinep()
&& !entryp->isUnderGen() && !entryp->isUnderGen()
// EOM
//&& entryp->getNodep()) {
&& (entryp->getNodep() || (m_enableWriteSummary && entryp->getCallNodep()))) { && (entryp->getNodep() || (m_enableWriteSummary && entryp->getCallNodep()))) {
// EOM
const AstNode* const otherWritep const AstNode* const otherWritep
= entryp->getNodep() = entryp->getNodep()
? static_cast<const AstNode*>(entryp->getNodep()) ? static_cast<const AstNode*>(entryp->getNodep())
@ -498,11 +479,8 @@ class UndrivenVisitor final : public VNVisitorConst {
<< nodep->warnOther() << '\n' << nodep->warnOther() << '\n'
<< nodep->warnContextPrimary() << nodep->warnContextPrimary()
<< '\n' << '\n'
// EOM
//<< entryp->getNodep()->warnOther()
<< otherWritep->warnOther() << otherWritep->warnOther()
<< "... Location of other write\n" << "... Location of other write\n"
//<< entryp->getNodep()->warnContextSecondary());
<< otherWritep->warnContextSecondary()); << otherWritep->warnContextSecondary());
} }
if (!m_alwaysCombp && entryp->isDrivenAlwaysCombWhole()) { if (!m_alwaysCombp && entryp->isDrivenAlwaysCombWhole()) {
@ -513,11 +491,8 @@ class UndrivenVisitor final : public VNVisitorConst {
<< nodep->warnOther() << '\n' << nodep->warnOther() << '\n'
<< nodep->warnContextPrimary() << nodep->warnContextPrimary()
<< '\n' << '\n'
//EOM
//<< entryp->getNodep()->warnOther()
<< otherWritep->warnOther() << otherWritep->warnOther()
<< "... Location of always_comb write\n" << "... Location of always_comb write\n"
//<< entryp->getNodep()->warnContextSecondary());
<< otherWritep->warnContextSecondary()); << otherWritep->warnContextSecondary());
} }
} }
@ -651,8 +626,6 @@ class UndrivenVisitor final : public VNVisitorConst {
public: public:
// CONSTRUCTORS // CONSTRUCTORS
// EOM
// explicit UndrivenVisitor(AstNetlist* nodep) { iterateConst(nodep); }
explicit UndrivenVisitor(AstNetlist* nodep, V3UndrivenCapture* capturep, explicit UndrivenVisitor(AstNetlist* nodep, V3UndrivenCapture* capturep,
bool enableWriteSummary) bool enableWriteSummary)
: m_capturep{capturep} : m_capturep{capturep}
@ -673,7 +646,6 @@ public:
void V3Undriven::undrivenAll(AstNetlist* nodep) { void V3Undriven::undrivenAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ":"); UINFO(2, __FUNCTION__ << ":");
// EOM
const bool enable = V3UndrivenCapture::enableWriteSummary; const bool enable = V3UndrivenCapture::enableWriteSummary;
if (enable) { if (enable) {
V3UndrivenCapture capture{nodep}; V3UndrivenCapture capture{nodep};

View File

@ -58,24 +58,20 @@ private:
VL_RESTORER(m_curTaskp); VL_RESTORER(m_curTaskp);
m_curTaskp = nodep; m_curTaskp = nodep;
++g_stats.ftasks; ++g_stats.ftasks;
UINFO(DBG, "UndrivenCapture: enter ftask " << nodep << " " << nodep->prettyNameQ()); UINFO(DBG, "undriven capture enter ftask " << nodep << " " << nodep->prettyNameQ());
m_cap.info(nodep); m_cap.noteTask(nodep);
iterateListConst(*this, nodep->stmtsp()); iterateListConst(*this, nodep->stmtsp());
} }
void visit(AstNodeVarRef* nodep) override { void visit(AstNodeVarRef* nodep) override {
if (m_curTaskp && nodep->access().isWriteOrRW()) { if (m_curTaskp && nodep->access().isWriteOrRW()) {
++g_stats.varWrites; ++g_stats.varWrites;
UINFO(DBG, "UndrivenCapture: direct write in " UINFO(DBG, "undriven capture direct write in "
<< taskNameQ(m_curTaskp) << " var=" << nodep->varp()->prettyNameQ() << taskNameQ(m_curTaskp) << " var=" << nodep->varp()->prettyNameQ()
<< " at " << nodep->fileline()); << " at " << nodep->fileline());
//m_cap.info(m_curTaskp).directWrites.push_back(nodep->varp());
AstVar* const retVarp = VN_CAST(m_curTaskp->fvarp(), Var); m_cap.noteDirectWrite(m_curTaskp, nodep->varp());
if (retVarp && nodep->varp() == retVarp) {
// Skip: function return variable is local, not a side-effect
} else {
m_cap.info(m_curTaskp).directWrites.push_back(nodep->varp());
}
} }
iterateChildrenConst(nodep); iterateChildrenConst(nodep);
} }
@ -85,12 +81,11 @@ private:
if (m_curTaskp) { if (m_curTaskp) {
if (AstNodeFTask* const calleep = nodep->taskp()) { if (AstNodeFTask* const calleep = nodep->taskp()) {
++g_stats.callEdges; ++g_stats.callEdges;
UINFO(DBG, "UndrivenCapture: call edge " << taskNameQ(m_curTaskp) << " -> " UINFO(DBG, "undriven capture call edge " << taskNameQ(m_curTaskp) << " -> "
<< taskNameQ(calleep)); << taskNameQ(calleep));
m_cap.info(m_curTaskp).callees.push_back(calleep); m_cap.noteCallEdge(m_curTaskp, calleep);
m_cap.info(calleep);
} else { } else {
UINFO(DBG, "UndrivenCapture: unresolved call in " << taskNameQ(m_curTaskp) UINFO(DBG, "undriven capture unresolved call in " << taskNameQ(m_curTaskp)
<< " name=" << nodep->name()); << " name=" << nodep->name());
} }
} }
@ -128,7 +123,7 @@ V3UndrivenCapture::V3UndrivenCapture(AstNetlist* netlistp) {
// Compute summaries for all tasks // Compute summaries for all tasks
for (const auto& kv : m_info) (void)computeWriteSummary(kv.first); for (const auto& kv : m_info) (void)computeWriteSummary(kv.first);
UINFO(DBG, "UndrivenCapture: stats ftasks=" UINFO(DBG, "undriven capture stats ftasks="
<< g_stats.ftasks << " varWrites=" << g_stats.varWrites << g_stats.ftasks << " varWrites=" << g_stats.varWrites
<< " callEdges=" << g_stats.callEdges << " uniqueTasks=" << m_info.size()); << " callEdges=" << g_stats.callEdges << " uniqueTasks=" << m_info.size());
} }
@ -154,12 +149,12 @@ const std::vector<V3UndrivenCapture::Var>& V3UndrivenCapture::computeWriteSummar
FTaskInfo& info = m_info[taskp]; FTaskInfo& info = m_info[taskp];
if (info.state == State::DONE) { if (info.state == State::DONE) {
UINFO(DBG, "UndrivenCapture: writeSummary cached size=" << info.writeSummary.size() UINFO(DBG, "undriven capture writeSummary cached size=" << info.writeSummary.size()
<< " for " << taskNameQ(taskp)); << " for " << taskNameQ(taskp));
return info.writeSummary; return info.writeSummary;
} }
if (info.state == State::VISITING) { if (info.state == State::VISITING) {
UINFO(DBG, "UndrivenCapture: recursion detected at " UINFO(DBG, "undriven capture recursion detected at "
<< taskNameQ(taskp) << taskNameQ(taskp)
<< " returning directWrites size=" << info.directWrites.size()); << " returning directWrites size=" << info.directWrites.size());
// Cycle detected. Simple behaviour: // Cycle detected. Simple behaviour:
@ -183,23 +178,38 @@ const std::vector<V3UndrivenCapture::Var>& V3UndrivenCapture::computeWriteSummar
sortUniqueVars(info.writeSummary); sortUniqueVars(info.writeSummary);
UINFO(DBG, "UndrivenCapture: writeSummary computed size=" << info.writeSummary.size() UINFO(DBG, "undriven capture writeSummary computed size=" << info.writeSummary.size()
<< " for " << taskNameQ(taskp)); << " for " << taskNameQ(taskp));
info.state = State::DONE; info.state = State::DONE;
return info.writeSummary; return info.writeSummary;
} }
void V3UndrivenCapture::noteTask(FTask taskp) { (void)m_info[taskp]; }
void V3UndrivenCapture::noteDirectWrite(FTask taskp, Var varp) {
FTaskInfo& info = m_info[taskp];
// Exclude function return variable (not an externally visible side-effect)
AstVar* const retVarp = VN_CAST(taskp->fvarp(), Var);
if (retVarp && varp == retVarp) return;
info.directWrites.push_back(varp);
}
void V3UndrivenCapture::noteCallEdge(FTask callerp, FTask calleep) {
m_info[callerp].callees.push_back(calleep);
(void)m_info[calleep]; // ensure callee entry exists
}
void V3UndrivenCapture::debugDumpTask(FTask taskp, int level) const { void V3UndrivenCapture::debugDumpTask(FTask taskp, int level) const {
const auto* const infop = find(taskp); const auto* const infop = find(taskp);
if (!infop) { if (!infop) {
UINFO(level, "UndrivenCapture: no entry for task " << taskp); UINFO(level, "undriven capture no entry for task " << taskp);
return; return;
} }
UINFO(level, "UndrivenCapture: dump task " << taskp << " " << taskp->prettyNameQ() UINFO(level, "undriven capture dump task " << taskp << " " << taskp->prettyNameQ()
<< " directWrites=" << infop->directWrites.size() << " directWrites=" << infop->directWrites.size()
<< " callees=" << infop->callees.size() << " callees=" << infop->callees.size()
<< " writeSummary=" << infop->writeSummary.size()); << " writeSummary=" << infop->writeSummary.size());
} }
V3UndrivenCapture::FTaskInfo& V3UndrivenCapture::info(FTask taskp) { return m_info[taskp]; }

View File

@ -47,9 +47,6 @@ public:
static bool enableWriteSummary; static bool enableWriteSummary;
// Get (and create if needed) mutable info entry for a task/function.
FTaskInfo& info(FTask taskp);
private: private:
// Per-task/function capture info keyed by resolved AstNodeFTask* identity. // Per-task/function capture info keyed by resolved AstNodeFTask* identity.
std::unordered_map<FTask, FTaskInfo> m_info; std::unordered_map<FTask, FTaskInfo> m_info;
@ -74,6 +71,11 @@ public:
// (creates empty entry if needed). // (creates empty entry if needed).
const std::vector<Var>& writeSummary(FTask taskp); const std::vector<Var>& writeSummary(FTask taskp);
// used by the capture visitor
void noteTask(FTask taskp);
void noteDirectWrite(FTask taskp, Var varp);
void noteCallEdge(FTask callerp, FTask calleep);
// Optional: dump one task's summary (for debug bring-up). // Optional: dump one task's summary (for debug bring-up).
void debugDumpTask(FTask taskp, int level = 9) const; void debugDumpTask(FTask taskp, int level = 9) const;
}; };