Associate trace codes with function indices (#4610)

For each traced variable, also register the trace function index that
will write it.
This commit is contained in:
Geza Lore
2023-10-23 16:01:55 +01:00
committed by GitHub
parent 1bd31742b9
commit d1b6224c2b
9 changed files with 125 additions and 83 deletions
+4 -1
View File
@@ -3192,7 +3192,8 @@ class AstTraceDecl final : public AstNodeStmt {
// Expression being traced - Moved to AstTraceInc by V3Trace
// @astgen op1 := valuep : Optional[AstNodeExpr]
private:
uint32_t m_code = 0; // Trace identifier code; converted to ASCII by trace routines
uint32_t m_code{0}; // Trace identifier code
uint32_t m_fidx{0}; // Trace function index
const string m_showname; // Name of variable
const VNumRange m_bitRange; // Property of var the trace details
const VNumRange m_arrayRange; // Property of var the trace details
@@ -3228,6 +3229,8 @@ public:
// Details on what we're tracing
uint32_t code() const { return m_code; }
void code(uint32_t code) { m_code = code; }
uint32_t fidx() const { return m_fidx; }
void fidx(uint32_t fidx) { m_fidx = fidx; }
uint32_t codeInc() const { return m_codeInc; }
const VNumRange& bitRange() const { return m_bitRange; }
const VNumRange& arrayRange() const { return m_arrayRange; }
+2
View File
@@ -649,6 +649,8 @@ class EmitCTrace final : EmitCFunc {
puts("(c+" + cvtToStr(nodep->code()));
if (nodep->arrayRange().ranged()) puts("+i*" + cvtToStr(nodep->widthWords()));
puts(",");
puts(cvtToStr(nodep->fidx()));
puts(",");
putsQuoted(VIdProtect::protectWordsIf(nodep->showname(), nodep->protect()));
// Direction
if (v3Global.opt.traceFormat().fst()) {
+34 -16
View File
@@ -477,22 +477,28 @@ private:
}
}
AstCFunc* newCFunc(VTraceType traceType, AstCFunc* topFuncp, unsigned funcNum,
AstCFunc* newCFunc(VTraceType traceType, AstCFunc* topFuncp, uint32_t funcNum,
uint32_t baseCode = 0) {
// Create new function
const bool isTopFunc = topFuncp == nullptr;
std::string baseName = "trace_";
if (traceType == VTraceType::CONSTANT) {
baseName += "const_";
} else if (traceType == VTraceType::FULL) {
baseName += "full_";
std::string funcName;
if (isTopFunc) {
if (traceType == VTraceType::CONSTANT) {
funcName = "trace_const";
} else if (traceType == VTraceType::FULL) {
funcName = "trace_full";
} else {
funcName = "trace_chg";
}
} else {
baseName += "chg_";
funcName = topFuncp->name();
funcName += "_sub";
}
baseName += isTopFunc ? "top_" : "sub_";
funcName += "_";
funcName += cvtToStr(funcNum);
FileLine* const flp = m_topScopep->fileline();
AstCFunc* const funcp = new AstCFunc{flp, baseName + cvtToStr(funcNum), m_topScopep};
AstCFunc* const funcp = new AstCFunc{flp, funcName, m_topScopep};
funcp->isTrace(true);
funcp->dontCombine(true);
funcp->isLoose(true);
@@ -526,6 +532,8 @@ private:
}
m_regFuncp->addStmtsp(new AstText{flp, str, true});
m_regFuncp->addStmtsp(new AstAddrOfCFunc{flp, funcp});
m_regFuncp->addStmtsp(new AstText{flp, ", ", true});
m_regFuncp->addStmtsp(new AstConst{flp, funcNum});
m_regFuncp->addStmtsp(new AstText{flp, ", vlSelf);\n", true});
} else {
// Sub functions
@@ -565,7 +573,7 @@ private:
: std::numeric_limits<int>::max();
AstCFunc* const topFuncp = newCFunc(VTraceType::CONSTANT, nullptr, 0);
unsigned subFuncNum = 0;
uint32_t subFuncNum = 0;
AstCFunc* subFuncp = nullptr;
int subStmts = 0;
for (auto it = traces.cbegin(); it != traces.end(); ++it) {
@@ -612,14 +620,16 @@ private:
uint32_t parallelism) {
const int splitLimit = v3Global.opt.outputSplitCTrace() ? v3Global.opt.outputSplitCTrace()
: std::numeric_limits<int>::max();
unsigned topFuncNum = 0;
unsigned subFuncNum = 0;
// pre-incremented, so starts at 0
uint32_t topFuncNum = std::numeric_limits<uint32_t>::max();
TraceVec::const_iterator it = traces.begin();
while (it != traces.end()) {
AstCFunc* topFulFuncp = nullptr;
AstCFunc* topChgFuncp = nullptr;
AstCFunc* subFulFuncp = nullptr;
AstCFunc* subChgFuncp = nullptr;
uint32_t subFuncNum = 0;
int subStmts = 0;
const uint32_t maxCodes = std::max((nAllCodes + parallelism - 1) / parallelism, 1U);
uint32_t nCodes = 0;
@@ -627,20 +637,25 @@ private:
AstIf* ifp = nullptr;
uint32_t baseCode = 0;
for (; nCodes < maxCodes && it != traces.end(); ++it) {
const TraceTraceVertex* const vtxp = it->second;
// This is a duplicate decl, no need to add it
if (vtxp->duplicatep()) continue;
const ActCodeSet& actSet = it->first;
// Traced value never changes, no need to add it
if (actSet.count(TraceActivityVertex::ACTIVITY_NEVER)) continue;
const TraceTraceVertex* const vtxp = it->second;
AstTraceDecl* const declp = vtxp->nodep();
// This is a duplicate decl, no need to add it, but must set the
// function index to the same as the canonical node.
if (const TraceTraceVertex* const canonVtxp = vtxp->duplicatep()) {
declp->fidx(canonVtxp->nodep()->fidx());
continue;
}
// Create top function if not yet created
if (!topFulFuncp) {
++topFuncNum;
topFulFuncp = newCFunc(VTraceType::FULL, nullptr, topFuncNum);
topChgFuncp = newCFunc(VTraceType::CHANGE, nullptr, topFuncNum);
++topFuncNum;
}
// Create new sub function if required
@@ -682,6 +697,9 @@ private:
= new AstTraceInc{flp, declp, VTraceType::CHANGE, baseCode};
ifp->addThensp(incChgp);
// Set the function index of the decl
declp->fidx(topFuncNum);
// Track splitting due to size
UASSERT_OBJ(incFulp->nodeCount() == incChgp->nodeCount(), declp,
"Should have equal cost");