removed aliases in V3UndrivenCapture, updated comments per feedback
This commit is contained in:
parent
74c7d598cb
commit
d8d46b8fce
|
|
@ -52,8 +52,8 @@ 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
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
enum : uint8_t { FLAG_USED = 0, FLAG_DRIVEN = 1, FLAG_DRIVEN_ALWCOMB = 2, FLAGS_PER_BIT = 3 };
|
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_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
|
||||||
|
|
||||||
V3UndrivenCapture* const m_capturep = nullptr;
|
V3UndrivenCapture* const m_capturep = nullptr; // Capture object. 'nullptr' if disabled.
|
||||||
const bool m_enableWriteSummary = false;
|
const bool m_enableWriteSummary = false; // Enable writeSummary computation plumbing
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
|
|
||||||
|
|
@ -565,19 +565,15 @@ class UndrivenVisitor final : public VNVisitorConst {
|
||||||
|
|
||||||
// If writeSummary is enabled, task/function definitions are treated as non-executed.
|
// 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
|
// 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.
|
// screwup in future edits.
|
||||||
//const auto inExecutedContext = [this]() const {
|
|
||||||
// return !(m_taskp && !m_alwaysp && !m_inContAssign && !m_inInitialStatic &&
|
|
||||||
// !m_inBBox);
|
|
||||||
//};
|
|
||||||
|
|
||||||
const auto inExecutedContext = [this]() {
|
const auto inExecutedContext = [this]() {
|
||||||
return !(m_taskp && !m_alwaysp && !m_inContAssign && !m_inInitialStatic && !m_inBBox
|
return !(m_taskp && !m_alwaysp && !m_inContAssign && !m_inInitialStatic && !m_inBBox
|
||||||
&& !m_taskp->dpiExport());
|
&& !m_taskp->dpiExport());
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!inExecutedContext()) { return; }
|
if (!inExecutedContext()) return;
|
||||||
|
|
||||||
AstNodeFTask* const calleep = nodep->taskp();
|
AstNodeFTask* const calleep = nodep->taskp();
|
||||||
if (!calleep) return;
|
if (!calleep) return;
|
||||||
|
|
|
||||||
|
|
@ -96,14 +96,12 @@ private:
|
||||||
|
|
||||||
bool V3UndrivenCapture::enableWriteSummary = true;
|
bool V3UndrivenCapture::enableWriteSummary = true;
|
||||||
|
|
||||||
// static
|
void V3UndrivenCapture::sortUniqueVars(std::vector<AstVar*>& vec) {
|
||||||
void V3UndrivenCapture::sortUniqueVars(std::vector<Var>& vec) {
|
|
||||||
std::sort(vec.begin(), vec.end());
|
std::sort(vec.begin(), vec.end());
|
||||||
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
|
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
void V3UndrivenCapture::sortUniqueFTasks(std::vector<const AstNodeFTask*>& vec) {
|
||||||
void V3UndrivenCapture::sortUniqueFTasks(std::vector<FTask>& vec) {
|
|
||||||
std::sort(vec.begin(), vec.end());
|
std::sort(vec.begin(), vec.end());
|
||||||
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
|
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
|
||||||
}
|
}
|
||||||
|
|
@ -130,19 +128,19 @@ void V3UndrivenCapture::gather(AstNetlist* netlistp) {
|
||||||
CaptureVisitor{*this, 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);
|
const auto it = m_info.find(taskp);
|
||||||
if (it == m_info.end()) return nullptr;
|
if (it == m_info.end()) return nullptr;
|
||||||
return &it->second;
|
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
|
// Ensure entry exists even if empty
|
||||||
(void)m_info[taskp];
|
(void)m_info[taskp];
|
||||||
return computeWriteSummary(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];
|
FTaskInfo& info = m_info[taskp];
|
||||||
|
|
||||||
if (info.state == State::DONE) {
|
if (info.state == State::DONE) {
|
||||||
|
|
@ -166,9 +164,9 @@ const std::vector<V3UndrivenCapture::Var>& V3UndrivenCapture::computeWriteSummar
|
||||||
info.writeSummary = info.directWrites;
|
info.writeSummary = info.directWrites;
|
||||||
|
|
||||||
// Need callees
|
// Need callees
|
||||||
for (FTask calleep : info.callees) {
|
for (const AstNodeFTask* calleep : info.callees) {
|
||||||
if (m_info.find(calleep) == m_info.end()) continue;
|
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());
|
info.writeSummary.insert(info.writeSummary.end(), sub.begin(), sub.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -183,9 +181,9 @@ const std::vector<V3UndrivenCapture::Var>& V3UndrivenCapture::computeWriteSummar
|
||||||
return info.writeSummary;
|
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];
|
FTaskInfo& info = m_info[taskp];
|
||||||
|
|
||||||
// Exclude function return variable (not an externally visible side-effect)
|
// 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);
|
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);
|
m_info[callerp].callees.push_back(calleep);
|
||||||
(void)m_info[calleep]; // ensure callee entry exists
|
(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);
|
const auto* const infop = find(taskp);
|
||||||
if (!infop) {
|
if (!infop) {
|
||||||
UINFO(level, "undriven capture no entry for task " << taskp);
|
UINFO(level, "undriven capture no entry for task " << taskp);
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,6 @@ class AstNetlist;
|
||||||
|
|
||||||
class V3UndrivenCapture final {
|
class V3UndrivenCapture final {
|
||||||
public:
|
public:
|
||||||
using FTask = const AstNodeFTask*;
|
|
||||||
using Var = AstVar*;
|
|
||||||
|
|
||||||
// DFS computation state for writeSummary propagation.
|
// DFS computation state for writeSummary propagation.
|
||||||
// UNVISITED: write summary not computed yet
|
// UNVISITED: write summary not computed yet
|
||||||
// VISITING: currently computing on the call stack - used to detect cycles
|
// VISITING: currently computing on the call stack - used to detect cycles
|
||||||
|
|
@ -39,13 +36,13 @@ public:
|
||||||
|
|
||||||
struct FTaskInfo final {
|
struct FTaskInfo final {
|
||||||
// Variables written directly in this task/function body.
|
// Variables written directly in this task/function body.
|
||||||
std::vector<Var> directWrites;
|
std::vector<AstVar*> directWrites;
|
||||||
// Direct resolved callees from this task/function body.
|
// Direct resolved callees from this task/function body.
|
||||||
std::vector<FTask> callees;
|
std::vector<const AstNodeFTask*> callees;
|
||||||
// 'write through write' writeSummary for the given task/function. Meaning ultimately
|
// 'Write through write' writeSummary for the given task/function. Meaning ultimately
|
||||||
// everything that this function/task writes to.
|
// everything that this function/task writes to.
|
||||||
std::vector<Var> writeSummary;
|
std::vector<AstVar*> writeSummary;
|
||||||
// state for writeSummary computation.
|
// State for writeSummary computation.
|
||||||
State state = State::UNVISITED;
|
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
|
// 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
|
// a list of variables written in the function body. There are methods to remove duplicates
|
||||||
// otherwise this could explode.
|
// 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
|
// 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
|
// write summary is computed. writeSummary can accumulate duplicates if a variable is written
|
||||||
// in multiple tasks/functions.
|
// 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
|
// Sort and remove duplicates from a vector of callees. The visitor can record the same callee
|
||||||
// multiple times (multiple call sites, branches, etc).
|
// 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
|
// Collect direct writes and call edges for all tasks/functions. Run one time when
|
||||||
// UndrivenCapture is created. This runs the visitor over the tree.
|
// UndrivenCapture is created. This runs the visitor over the tree.
|
||||||
void gather(AstNetlist* netlistp);
|
void gather(AstNetlist* netlistp);
|
||||||
// Compute (and cache) 'write through write' writeSummary for the given task/function.
|
// 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:
|
public:
|
||||||
// Build capture database and precompute writeSummary for all discovered tasks/functions.
|
// 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
|
// Lookup task/function capture info (nullptr if unknown). This is currently only used for the
|
||||||
// debug helper.
|
// 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
|
// 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
|
// (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 writes to, including all variables written by functions called by this
|
||||||
// task/function, and so on.
|
// 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.
|
// and callees. noteTask() makes sure there is an entry for the given taskp.
|
||||||
void noteTask(FTask taskp);
|
void noteTask(const AstNodeFTask* taskp);
|
||||||
// inside the body of taskp there is a write to variable varp
|
// Inside the body of taskp there is a write to variable varp
|
||||||
void noteDirectWrite(FTask taskp, Var 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
|
// 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
|
// summary that includes all variables written by functions called by this task/function, and
|
||||||
// so on.
|
// 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.
|
// functionality.
|
||||||
void debugDumpTask(FTask taskp, int level = 9) const;
|
void debugDumpTask(const AstNodeFTask* taskp, int level = 9) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VERILATOR_V3UNDRIVENCAPTURE_H_
|
#endif // VERILATOR_V3UNDRIVENCAPTURE_H_
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue