Internals: Factor out --prof-exec section handling, add debug code

This commit is contained in:
Geza Lore 2025-11-25 05:53:59 +00:00
parent 9e37a09765
commit d2ce5e62e7
7 changed files with 51 additions and 33 deletions

View File

@ -288,6 +288,27 @@ public:
class AstCStmt final : public AstNodeStmt {
// C statement emitted into output, with some arbitrary nodes interspersed
// @astgen op1 := nodesp : List[AstNode<AstNodeStmt|AstNodeExpr|AstText>]
static AstCStmt* profExecSection(FileLine* flp, const std::string& section, bool push) {
// Compute the label
std::string label;
if (v3Global.opt.hierChild()) label += v3Global.opt.topModule() + ":";
label += section;
// The profiler statement
std::string pStmt = "VL_EXEC_TRACE_ADD_RECORD(vlSymsp)";
pStmt += push ? ".sectionPush" : ".sectionPop";
pStmt += "(";
if (push) pStmt += "\"" + label + "\"";
pStmt += ");";
// The debug statement
std::string dStmt = "VL_DEBUG_IF(VL_DBG_MSGF(\"+ --prof-exec ";
dStmt += push ? "sectionPush " : "sectionPop ";
dStmt += label;
dStmt += "\\n\"););";
// Concatenate
return new AstCStmt{flp, push ? pStmt + "\n" + dStmt : dStmt + "\n" + pStmt};
}
public:
explicit AstCStmt(FileLine* fl, const std::string& text = "")
: ASTGEN_SUPER_CStmt(fl) {
@ -302,6 +323,13 @@ public:
// Add some text, or a node to this statement
void add(const std::string& text) { addNodesp(new AstText{fileline(), text}); }
void add(AstNode* nodep) { addNodesp(nodep); }
// Static factory methods for specific cases
static AstCStmt* profExecSectionPush(FileLine* flp, const std::string& section) {
return profExecSection(flp, section, true);
}
static AstCStmt* profExecSectionPop(FileLine* flp, const std::string& section) {
return profExecSection(flp, section, false);
}
};
class AstCStmtUser final : public AstNodeStmt {
// User '$c' statement, also used for handling some AstSystemCSection.

View File

@ -156,14 +156,11 @@ AstCFunc* V3Order::order(AstNetlist* netlistp, //
// Assemble the body
if (v3Global.opt.profExec()) {
const std::string name
= (v3Global.opt.hierChild() ? (v3Global.opt.topModule() + " ") : "") + "func " + tag;
funcp->addStmtsp(
new AstCStmt{flp, "VL_EXEC_TRACE_ADD_RECORD(vlSymsp).sectionPush(\"" + name + "\");"});
funcp->addStmtsp(AstCStmt::profExecSectionPush(flp, "func " + tag));
}
funcp->addStmtsp(stmtsp);
if (v3Global.opt.profExec()) {
funcp->addStmtsp(new AstCStmt{flp, "VL_EXEC_TRACE_ADD_RECORD(vlSymsp).sectionPop();"});
if (v3Global.opt.profExec()) { //
funcp->addStmtsp(AstCStmt::profExecSectionPop(flp, "func " + tag));
}
// Done

View File

@ -175,7 +175,9 @@ EvalLoop createEvalLoop(
AstNodeStmt* stmtps = nullptr;
// Prof-exec section push
if (v3Global.opt.profExec()) stmtps = util::profExecSectionPush(flp, "loop " + tag);
if (v3Global.opt.profExec()) { //
stmtps = AstCStmt::profExecSectionPush(flp, "loop " + tag);
}
const auto addVar = [&](const std::string& name, int width, uint32_t initVal) {
AstVarScope* const vscp = scopeTopp->createTemp("__V" + tag + name, width);
@ -215,7 +217,9 @@ EvalLoop createEvalLoop(
}
// Prof-exec section pop
if (v3Global.opt.profExec()) stmtps->addNext(util::profExecSectionPop(flp));
if (v3Global.opt.profExec()) {
stmtps->addNext(AstCStmt::profExecSectionPop(flp, "loop " + tag));
}
return {firstIterFlagp, stmtps};
}
@ -684,7 +688,7 @@ void createEval(AstNetlist* netlistp, //
AstCFunc* const funcp = util::makeTopFunction(netlistp, "_eval", false);
netlistp->evalp(funcp);
if (v3Global.opt.profExec()) funcp->addStmtsp(util::profExecSectionPush(flp, "eval"));
if (v3Global.opt.profExec()) funcp->addStmtsp(AstCStmt::profExecSectionPush(flp, "eval"));
// Start with the ico loop, if any
if (icoLoop) funcp->addStmtsp(icoLoop);
@ -695,7 +699,7 @@ void createEval(AstNetlist* netlistp, //
// Add the Postponed eval call
if (postponedFuncp) funcp->addStmtsp(util::callVoidFunc(postponedFuncp));
if (v3Global.opt.profExec()) funcp->addStmtsp(util::profExecSectionPop(flp));
if (v3Global.opt.profExec()) funcp->addStmtsp(AstCStmt::profExecSectionPop(flp, "eval"));
}
} // namespace

View File

@ -405,10 +405,6 @@ AstNodeStmt* callVoidFunc(AstCFunc* funcp);
// Create statement that checks counterp' to see if the eval loop iteration limit is reached
AstNodeStmt* checkIterationLimit(AstNetlist* netlistp, const string& name, AstVarScope* counterp,
AstNodeStmt* dumpCallp);
// Create statement that pushed a --prof-exec section
AstNodeStmt* profExecSectionPush(FileLine* flp, const string& section);
// Create statement that pops a --prof-exec section
AstNodeStmt* profExecSectionPop(FileLine* flp);
// Split large function according to --output-split-cfuncs
void splitCheck(AstCFunc* ofuncp);
// Build an AstIf conditional on the given SenTree being triggered

View File

@ -661,7 +661,9 @@ TriggerKit TriggerKit::create(AstNetlist* netlistp, //
AstCFunc* const fp = kit.m_compp;
AstScope* const scopep = netlistp->topScopep()->scopep();
// Profiling push
if (v3Global.opt.profExec()) fp->addStmtsp(util::profExecSectionPush(flp, "trig " + name));
if (v3Global.opt.profExec()) {
fp->addStmtsp(AstCStmt::profExecSectionPush(flp, "trig " + name));
}
// Trigger computation
for (AstNodeStmt* const nodep : senResults.m_preUpdates) fp->addStmtsp(nodep);
fp->addStmtsp(trigStmtsp);
@ -702,7 +704,9 @@ TriggerKit TriggerKit::create(AstNetlist* netlistp, //
// Add a call to the dumping function if debug is enabled
fp->addStmtsp(kit.newDumpCall(kit.m_vscp, name, true));
// Profiling pop
if (v3Global.opt.profExec()) fp->addStmtsp(util::profExecSectionPop(flp));
if (v3Global.opt.profExec()) {
fp->addStmtsp(AstCStmt::profExecSectionPop(flp, "trig " + name));
}
// Done with the trigger computation function, split as might be large
util::splitCheck(fp);
};

View File

@ -101,16 +101,6 @@ AstNodeStmt* checkIterationLimit(AstNetlist* netlistp, const string& name, AstVa
return ifp;
}
AstNodeStmt* profExecSectionPush(FileLine* flp, const string& section) {
const string name
= (v3Global.opt.hierChild() ? (v3Global.opt.topModule() + " ") : "") + section;
return new AstCStmt{flp, "VL_EXEC_TRACE_ADD_RECORD(vlSymsp).sectionPush(\"" + name + "\");"};
}
AstNodeStmt* profExecSectionPop(FileLine* flp) {
return new AstCStmt{flp, "VL_EXEC_TRACE_ADD_RECORD(vlSymsp).sectionPop();"};
}
static AstCFunc* splitCheckCreateNewSubFunc(AstCFunc* ofuncp) {
static std::map<AstCFunc*, uint32_t> s_funcNums; // What split number to attach to a function
const uint32_t funcNum = s_funcNums[ofuncp]++;

View File

@ -1064,10 +1064,9 @@ class TaskVisitor final : public VNVisitor {
AstCFunc* dpiFuncp) {
const char* const tmpSuffixp = V3Task::dpiTemporaryVarSuffix();
if (v3Global.opt.profExec())
cfuncp->addStmtsp(
new AstCStmt{nodep->fileline(),
"VL_EXEC_TRACE_ADD_RECORD(vlSymsp).sectionPush(\"dpiimports\");"});
if (v3Global.opt.profExec()) {
cfuncp->addStmtsp(AstCStmt::profExecSectionPush(nodep->fileline(), "dpiimports"));
}
// Convert input/inout arguments to DPI types
string args;
@ -1161,9 +1160,9 @@ class TaskVisitor final : public VNVisitor {
}
}
if (v3Global.opt.profExec())
cfuncp->addStmtsp(new AstCStmt{nodep->fileline(),
"VL_EXEC_TRACE_ADD_RECORD(vlSymsp).sectionPop();"});
if (v3Global.opt.profExec()) {
cfuncp->addStmtsp(AstCStmt::profExecSectionPop(nodep->fileline(), "dpiimports"));
}
}
AstVarScope* getDpiExporTrigger() {