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
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
|
|||
Loading…
Reference in New Issue