removed aliases in V3UndrivenCapture, updated comments per feedback

This commit is contained in:
em2machine 2025-12-22 17:58:11 +01:00
parent 74c7d598cb
commit d8d46b8fce
3 changed files with 36 additions and 45 deletions

View File

@ -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;

View File

@ -96,14 +96,12 @@ private:
bool V3UndrivenCapture::enableWriteSummary = true;
// static
void V3UndrivenCapture::sortUniqueVars(std::vector<Var>& vec) {
void V3UndrivenCapture::sortUniqueVars(std::vector<AstVar*>& vec) {
std::sort(vec.begin(), vec.end());
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
}
// static
void V3UndrivenCapture::sortUniqueFTasks(std::vector<FTask>& vec) {
void V3UndrivenCapture::sortUniqueFTasks(std::vector<const AstNodeFTask*>& 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::Var>& V3UndrivenCapture::writeSummary(FTask taskp) {
const std::vector<AstVar*>& V3UndrivenCapture::writeSummary(const AstNodeFTask* taskp) {
// Ensure entry exists even if empty
(void)m_info[taskp];
return computeWriteSummary(taskp);
}
const std::vector<V3UndrivenCapture::Var>& V3UndrivenCapture::computeWriteSummary(FTask taskp) {
const std::vector<AstVar*>& V3UndrivenCapture::computeWriteSummary(const AstNodeFTask* taskp) {
FTaskInfo& info = m_info[taskp];
if (info.state == State::DONE) {
@ -166,9 +164,9 @@ const std::vector<V3UndrivenCapture::Var>& 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<Var>& sub = computeWriteSummary(calleep);
const std::vector<AstVar*>& sub = computeWriteSummary(calleep);
info.writeSummary.insert(info.writeSummary.end(), sub.begin(), sub.end());
}
@ -183,9 +181,9 @@ const std::vector<V3UndrivenCapture::Var>& 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);

View File

@ -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<Var> directWrites;
std::vector<AstVar*> directWrites;
// Direct resolved callees from this task/function body.
std::vector<FTask> callees;
// 'write through write' writeSummary for the given task/function. Meaning ultimately
std::vector<const AstNodeFTask*> callees;
// 'Write through write' writeSummary for the given task/function. Meaning ultimately
// everything that this function/task writes to.
std::vector<Var> writeSummary;
// state for writeSummary computation.
std::vector<AstVar*> 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<FTask, FTaskInfo> m_info;
std::unordered_map<const AstNodeFTask*, FTaskInfo> 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<Var>& vec);
static void sortUniqueVars(std::vector<AstVar*>& 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<FTask>& vec);
static void sortUniqueFTasks(std::vector<const AstNodeFTask*>& 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<Var>& computeWriteSummary(FTask taskp);
const std::vector<AstVar*>& 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<Var>& writeSummary(FTask taskp);
const std::vector<AstVar*>& 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_