diff --git a/src/V3Undriven.cpp b/src/V3Undriven.cpp index 15b0a7b39..401bd17ca 100644 --- a/src/V3Undriven.cpp +++ b/src/V3Undriven.cpp @@ -52,8 +52,8 @@ class UndrivenVarEntry final { const FileLine* m_nodeFileLinep = nullptr; // File line of varref if driven, else nullptr bool m_underGen = false; // Under a generate - 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 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 enum : uint8_t { FLAG_USED = 0, FLAG_DRIVEN = 1, FLAG_DRIVEN_ALWCOMB = 2, FLAGS_PER_BIT = 3 }; @@ -318,8 +318,8 @@ class UndrivenVisitor final : public VNVisitorConst { const AstAlways* m_alwaysp = nullptr; // Current always of either type const AstAlways* m_alwaysCombp = nullptr; // Current always if combo, otherwise nullptr - V3UndrivenCapture* const m_capturep = nullptr; - const bool m_enableWriteSummary = false; + V3UndrivenCapture* const m_capturep = nullptr; // Capture object. 'nullptr' if disabled. + const bool m_enableWriteSummary = false; // Enable writeSummary computation plumbing // METHODS @@ -565,19 +565,15 @@ class UndrivenVisitor final : public VNVisitorConst { // If writeSummary is enabled, task/function definitions are treated as non-executed. // Do not apply writeSummary at calls inside a task definition, or they will look like - // independent drivers (phantom MULTIDRIVEN). did the lambda on purpose - lessen chance of + // independent drivers (phantom MULTIDRIVEN). Did the lambda on purpose - lessen chance of // screwup in future edits. - //const auto inExecutedContext = [this]() const { - // return !(m_taskp && !m_alwaysp && !m_inContAssign && !m_inInitialStatic && - // !m_inBBox); - //}; const auto inExecutedContext = [this]() { return !(m_taskp && !m_alwaysp && !m_inContAssign && !m_inInitialStatic && !m_inBBox && !m_taskp->dpiExport()); }; - if (!inExecutedContext()) { return; } + if (!inExecutedContext()) return; AstNodeFTask* const calleep = nodep->taskp(); if (!calleep) return; diff --git a/src/V3UndrivenCapture.cpp b/src/V3UndrivenCapture.cpp index e3adfc83f..6c23c20a7 100644 --- a/src/V3UndrivenCapture.cpp +++ b/src/V3UndrivenCapture.cpp @@ -96,14 +96,12 @@ private: bool V3UndrivenCapture::enableWriteSummary = true; -// static -void V3UndrivenCapture::sortUniqueVars(std::vector& vec) { +void V3UndrivenCapture::sortUniqueVars(std::vector& vec) { std::sort(vec.begin(), vec.end()); vec.erase(std::unique(vec.begin(), vec.end()), vec.end()); } -// static -void V3UndrivenCapture::sortUniqueFTasks(std::vector& vec) { +void V3UndrivenCapture::sortUniqueFTasks(std::vector& vec) { std::sort(vec.begin(), vec.end()); vec.erase(std::unique(vec.begin(), vec.end()), vec.end()); } @@ -130,19 +128,19 @@ void V3UndrivenCapture::gather(AstNetlist* netlistp) { CaptureVisitor{*this, netlistp}; } -const V3UndrivenCapture::FTaskInfo* V3UndrivenCapture::find(FTask taskp) const { +const V3UndrivenCapture::FTaskInfo* V3UndrivenCapture::find(const AstNodeFTask* taskp) const { const auto it = m_info.find(taskp); if (it == m_info.end()) return nullptr; return &it->second; } -const std::vector& V3UndrivenCapture::writeSummary(FTask taskp) { +const std::vector& V3UndrivenCapture::writeSummary(const AstNodeFTask* taskp) { // Ensure entry exists even if empty (void)m_info[taskp]; return computeWriteSummary(taskp); } -const std::vector& V3UndrivenCapture::computeWriteSummary(FTask taskp) { +const std::vector& V3UndrivenCapture::computeWriteSummary(const AstNodeFTask* taskp) { FTaskInfo& info = m_info[taskp]; if (info.state == State::DONE) { @@ -166,9 +164,9 @@ const std::vector& V3UndrivenCapture::computeWriteSummar info.writeSummary = info.directWrites; // Need callees - for (FTask calleep : info.callees) { + for (const AstNodeFTask* calleep : info.callees) { if (m_info.find(calleep) == m_info.end()) continue; - const std::vector& sub = computeWriteSummary(calleep); + const std::vector& sub = computeWriteSummary(calleep); info.writeSummary.insert(info.writeSummary.end(), sub.begin(), sub.end()); } @@ -183,9 +181,9 @@ const std::vector& V3UndrivenCapture::computeWriteSummar return info.writeSummary; } -void V3UndrivenCapture::noteTask(FTask taskp) { (void)m_info[taskp]; } +void V3UndrivenCapture::noteTask(const AstNodeFTask* taskp) { (void)m_info[taskp]; } -void V3UndrivenCapture::noteDirectWrite(FTask taskp, Var varp) { +void V3UndrivenCapture::noteDirectWrite(const AstNodeFTask* taskp, AstVar* varp) { FTaskInfo& info = m_info[taskp]; // Exclude function return variable (not an externally visible side-effect) @@ -195,12 +193,12 @@ void V3UndrivenCapture::noteDirectWrite(FTask taskp, Var varp) { info.directWrites.push_back(varp); } -void V3UndrivenCapture::noteCallEdge(FTask callerp, FTask calleep) { +void V3UndrivenCapture::noteCallEdge(const AstNodeFTask* callerp, const AstNodeFTask* 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(const AstNodeFTask* taskp, int level) const { const auto* const infop = find(taskp); if (!infop) { UINFO(level, "undriven capture no entry for task " << taskp); diff --git a/src/V3UndrivenCapture.h b/src/V3UndrivenCapture.h index 462590b2d..27e6ffeb7 100644 --- a/src/V3UndrivenCapture.h +++ b/src/V3UndrivenCapture.h @@ -28,9 +28,6 @@ class AstNetlist; class V3UndrivenCapture final { public: - using FTask = const AstNodeFTask*; - using Var = AstVar*; - // DFS computation state for writeSummary propagation. // UNVISITED: write summary not computed yet // VISITING: currently computing on the call stack - used to detect cycles @@ -39,13 +36,13 @@ public: struct FTaskInfo final { // Variables written directly in this task/function body. - std::vector directWrites; + std::vector directWrites; // Direct resolved callees from this task/function body. - std::vector callees; - // 'write through write' writeSummary for the given task/function. Meaning ultimately + std::vector callees; + // 'Write through write' writeSummary for the given task/function. Meaning ultimately // everything that this function/task writes to. - std::vector writeSummary; - // state for writeSummary computation. + std::vector writeSummary; + // State for writeSummary computation. State state = State::UNVISITED; }; @@ -58,21 +55,21 @@ private: // task). This is our 'graph' of tasks/functions. Each node has a list of direct callees and // a list of variables written in the function body. There are methods to remove duplicates // otherwise this could explode. - std::unordered_map m_info; + std::unordered_map m_info; // Sort and remove duplicates from a vector of variables. This is called after a task/function // write summary is computed. writeSummary can accumulate duplicates if a variable is written // in multiple tasks/functions. - static void sortUniqueVars(std::vector& vec); + static void sortUniqueVars(std::vector& vec); // Sort and remove duplicates from a vector of callees. The visitor can record the same callee // multiple times (multiple call sites, branches, etc). - static void sortUniqueFTasks(std::vector& vec); + static void sortUniqueFTasks(std::vector& vec); // Collect direct writes and call edges for all tasks/functions. Run one time when // UndrivenCapture is created. This runs the visitor over the tree. void gather(AstNetlist* netlistp); // Compute (and cache) 'write through write' writeSummary for the given task/function. - const std::vector& computeWriteSummary(FTask taskp); + const std::vector& computeWriteSummary(const AstNodeFTask* taskp); public: // Build capture database and precompute writeSummary for all discovered tasks/functions. @@ -80,26 +77,26 @@ public: // Lookup task/function capture info (nullptr if unknown). This is currently only used for the // debug helper. - const FTaskInfo* find(FTask taskp) const; + const FTaskInfo* find(const AstNodeFTask* taskp) const; // Get write through write through write, etc (call chain) writeSummary for a task/function // (creates empty entry if needed). This returns a vector of variables that a particular // task/function writes to, including all variables written by functions called by this // task/function, and so on. - const std::vector& writeSummary(FTask taskp); + const std::vector& writeSummary(const AstNodeFTask* taskp); - // used by the capture visitor to record information about tasks/functions and their statements + // Used by the capture visitor to record information about tasks/functions and their statements // and callees. noteTask() makes sure there is an entry for the given taskp. - void noteTask(FTask taskp); - // inside the body of taskp there is a write to variable varp - void noteDirectWrite(FTask taskp, Var varp); - // inside the body of callerp there is a call to calleep, this is needed so we can create a + void noteTask(const AstNodeFTask* taskp); + // Inside the body of taskp there is a write to variable varp + void noteDirectWrite(const AstNodeFTask* taskp, AstVar* varp); + // Inside the body of callerp there is a call to calleep, this is needed so we can create a // summary that includes all variables written by functions called by this task/function, and // so on. - void noteCallEdge(FTask callerp, FTask calleep); + void noteCallEdge(const AstNodeFTask* callerp, const AstNodeFTask* calleep); - // dump one task's summary for debugging. leaving this in, in case need to debug future + // Dump one task's summary for debugging. leaving this in, in case need to debug future // functionality. - void debugDumpTask(FTask taskp, int level = 9) const; + void debugDumpTask(const AstNodeFTask* taskp, int level = 9) const; }; #endif // VERILATOR_V3UNDRIVENCAPTURE_H_