Internals: Avoid emit inheritance in V3EmitCBase. No functional change intended.

This commit is contained in:
Wilson Snyder 2023-03-18 12:05:29 -04:00
parent 053f760e2a
commit 82e653a739
15 changed files with 61 additions and 62 deletions

View File

@ -735,9 +735,9 @@ AstNodeDType::CTypeRecursed AstNodeDType::cTypeRecurse(bool compound) const VL_M
const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(true); const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(true);
info.m_type = "VlSampleQueue<" + sub.m_type + ">"; info.m_type = "VlSampleQueue<" + sub.m_type + ">";
} else if (const auto* const adtypep = VN_CAST(dtypep, ClassRefDType)) { } else if (const auto* const adtypep = VN_CAST(dtypep, ClassRefDType)) {
info.m_type = "VlClassRef<" + EmitCBaseVisitor::prefixNameProtect(adtypep) + ">"; info.m_type = "VlClassRef<" + EmitCBase::prefixNameProtect(adtypep) + ">";
} else if (const auto* const adtypep = VN_CAST(dtypep, IfaceRefDType)) { } else if (const auto* const adtypep = VN_CAST(dtypep, IfaceRefDType)) {
info.m_type = EmitCBaseVisitor::prefixNameProtect(adtypep->ifaceViaCellp()) + "*"; info.m_type = EmitCBase::prefixNameProtect(adtypep->ifaceViaCellp()) + "*";
} else if (const auto* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) { } else if (const auto* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
if (adtypep->isCompound()) compound = true; if (adtypep->isCompound()) compound = true;
const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(compound); const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(compound);
@ -746,7 +746,7 @@ AstNodeDType::CTypeRecursed AstNodeDType::cTypeRecurse(bool compound) const VL_M
info.m_type += ">"; info.m_type += ">";
} else if (VN_IS(dtypep, NodeUOrStructDType) && !VN_AS(dtypep, NodeUOrStructDType)->packed()) { } else if (VN_IS(dtypep, NodeUOrStructDType) && !VN_AS(dtypep, NodeUOrStructDType)->packed()) {
const auto* const sdtypep = VN_AS(dtypep, NodeUOrStructDType); const auto* const sdtypep = VN_AS(dtypep, NodeUOrStructDType);
info.m_type = EmitCBaseVisitor::prefixNameProtect(sdtypep); info.m_type = EmitCBase::prefixNameProtect(sdtypep);
} else if (const AstBasicDType* const bdtypep = dtypep->basicp()) { } else if (const AstBasicDType* const bdtypep = dtypep->basicp()) {
// We don't print msb()/lsb() as multidim packed would require recursion, // We don't print msb()/lsb() as multidim packed would require recursion,
// and may confuse users as C++ data is stored always with bit 0 used // and may confuse users as C++ data is stored always with bit 0 used

View File

@ -70,7 +70,7 @@ private:
funcp->slow(!m_type.isClass()); // Only classes construct on fast path funcp->slow(!m_type.isClass()); // Only classes construct on fast path
string preventUnusedStmt; string preventUnusedStmt;
if (m_type.isClass()) { if (m_type.isClass()) {
funcp->argTypes(EmitCBaseVisitor::symClassVar()); funcp->argTypes(EmitCBase::symClassVar());
preventUnusedStmt = "if (false && vlSymsp) {} // Prevent unused\n"; preventUnusedStmt = "if (false && vlSymsp) {} // Prevent unused\n";
} else if (m_type.isCoverage()) { } else if (m_type.isCoverage()) {
funcp->argTypes("bool first"); funcp->argTypes("bool first");

View File

@ -37,7 +37,7 @@ VL_DEFINE_DEBUG_FUNCTIONS;
static void makeVlToString(AstClass* nodep) { static void makeVlToString(AstClass* nodep) {
AstCFunc* const funcp AstCFunc* const funcp
= new AstCFunc{nodep->fileline(), "VL_TO_STRING", nullptr, "std::string"}; = new AstCFunc{nodep->fileline(), "VL_TO_STRING", nullptr, "std::string"};
funcp->argTypes("const VlClassRef<" + EmitCBaseVisitor::prefixNameProtect(nodep) + ">& obj"); funcp->argTypes("const VlClassRef<" + EmitCBase::prefixNameProtect(nodep) + ">& obj");
funcp->isMethod(false); funcp->isMethod(false);
funcp->isConst(false); funcp->isConst(false);
funcp->isStatic(false); funcp->isStatic(false);
@ -51,7 +51,7 @@ static void makeVlToString(AstClass* nodep) {
static void makeVlToString(AstIface* nodep) { static void makeVlToString(AstIface* nodep) {
AstCFunc* const funcp AstCFunc* const funcp
= new AstCFunc{nodep->fileline(), "VL_TO_STRING", nullptr, "std::string"}; = new AstCFunc{nodep->fileline(), "VL_TO_STRING", nullptr, "std::string"};
funcp->argTypes("const " + EmitCBaseVisitor::prefixNameProtect(nodep) + "* obj"); funcp->argTypes("const " + EmitCBase::prefixNameProtect(nodep) + "* obj");
funcp->isMethod(false); funcp->isMethod(false);
funcp->isConst(false); funcp->isConst(false);
funcp->isStatic(false); funcp->isStatic(false);
@ -65,7 +65,7 @@ static void makeVlToString(AstNodeUOrStructDType* nodep) {
AstNodeModule* const modp = nodep->classOrPackagep(); AstNodeModule* const modp = nodep->classOrPackagep();
AstCFunc* const funcp AstCFunc* const funcp
= new AstCFunc{nodep->fileline(), "VL_TO_STRING", nullptr, "std::string"}; = new AstCFunc{nodep->fileline(), "VL_TO_STRING", nullptr, "std::string"};
funcp->argTypes("const " + EmitCBaseVisitor::prefixNameProtect(nodep) + "& obj"); funcp->argTypes("const " + EmitCBase::prefixNameProtect(nodep) + "& obj");
funcp->isMethod(false); funcp->isMethod(false);
funcp->isConst(false); funcp->isConst(false);
funcp->isStatic(false); funcp->isStatic(false);
@ -137,7 +137,7 @@ static void makeToStringMiddle(AstClass* nodep) {
string stmt = "out += "; string stmt = "out += ";
if (!comma.empty()) stmt += "\", \"+ "; if (!comma.empty()) stmt += "\", \"+ ";
// comma = ", "; // Nothing further so not needed // comma = ", "; // Nothing further so not needed
stmt += EmitCBaseVisitor::prefixNameProtect(nodep->extendsp()->dtypep()); stmt += EmitCBase::prefixNameProtect(nodep->extendsp()->dtypep());
stmt += "::to_string_middle();\n"; stmt += "::to_string_middle();\n";
nodep->user1(true); // So what we extend dumps this nodep->user1(true); // So what we extend dumps this
funcp->addStmtsp(new AstCStmt{nodep->fileline(), stmt}); funcp->addStmtsp(new AstCStmt{nodep->fileline(), stmt});

View File

@ -63,7 +63,7 @@ private:
AstCCall* const callp = new AstCCall{nodep->fileline(), funcp}; AstCCall* const callp = new AstCCall{nodep->fileline(), funcp};
callp->dtypeSetVoid(); callp->dtypeSetVoid();
if (VN_IS(m_modp, Class)) { if (VN_IS(m_modp, Class)) {
funcp->argTypes(EmitCBaseVisitor::symClassVar()); funcp->argTypes(EmitCBase::symClassVar());
callp->argTypes("vlSymsp"); callp->argTypes("vlSymsp");
} }
UINFO(6, " New " << callp << endl); UINFO(6, " New " << callp << endl);

View File

@ -48,7 +48,36 @@ public:
//###################################################################### //######################################################################
// Base Visitor class -- holds output file pointer // Base Visitor class -- holds output file pointer
class EmitCBaseVisitor VL_NOT_FINAL : public VNVisitor { class EmitCBase VL_NOT_FINAL {
public:
static string voidSelfAssign(const AstNodeModule* modp) {
const string className = prefixNameProtect(modp);
return className + "* const __restrict vlSelf VL_ATTR_UNUSED = static_cast<" + className
+ "*>(voidSelf);\n";
}
static string symClassName() {
return v3Global.opt.prefix() + "_" + VIdProtect::protect("_Syms");
}
static string symClassVar() { return symClassName() + "* __restrict vlSymsp"; }
static string symClassAssign() {
return symClassName() + "* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;\n";
}
static string prefixNameProtect(const AstNode* nodep) VL_MT_SAFE { // C++ name with prefix
return v3Global.opt.modPrefix() + "_" + VIdProtect::protect(nodep->name());
}
static bool isAnonOk(const AstVar* varp) {
return v3Global.opt.compLimitMembers() != 0 // Enabled
&& !varp->isStatic() // Not a static variable
&& !varp->isSc() // Aggregates can't be anon
&& !VN_IS(varp->dtypep()->skipRefp(), SampleQueueDType) // Aggregates can't be anon
&& (varp->basicp() && !varp->basicp()->isOpaque()); // Aggregates can't be anon
}
static bool isConstPoolMod(const AstNode* modp) {
return modp == v3Global.rootp()->constPoolp()->modp();
}
};
class EmitCBaseVisitor VL_NOT_FINAL : public VNVisitor, public EmitCBase {
public: public:
// STATE // STATE
V3OutCFile* m_ofp = nullptr; V3OutCFile* m_ofp = nullptr;
@ -63,9 +92,7 @@ public:
void putsQuoted(const string& str) { ofp()->putsQuoted(str); } void putsQuoted(const string& str) { ofp()->putsQuoted(str); }
void ensureNewLine() { ofp()->ensureNewLine(); } void ensureNewLine() { ofp()->ensureNewLine(); }
bool optSystemC() { return v3Global.opt.systemC(); } bool optSystemC() { return v3Global.opt.systemC(); }
static string protect(const string& name) VL_MT_SAFE { static string protect(const string& name) VL_MT_SAFE { return VIdProtect::protect(name); }
return VIdProtect::protectIf(name, true);
}
static string protectIf(const string& name, bool doIt) { static string protectIf(const string& name, bool doIt) {
return VIdProtect::protectIf(name, doIt); return VIdProtect::protectIf(name, doIt);
} }
@ -75,36 +102,10 @@ public:
static string ifNoProtect(const string& in) VL_MT_SAFE { static string ifNoProtect(const string& in) VL_MT_SAFE {
return v3Global.opt.protectIds() ? "" : in; return v3Global.opt.protectIds() ? "" : in;
} }
static string voidSelfAssign(const AstNodeModule* modp) {
const string className = prefixNameProtect(modp);
return className + "* const __restrict vlSelf VL_ATTR_UNUSED = static_cast<" + className
+ "*>(voidSelf);\n";
}
static string symClassName() { return v3Global.opt.prefix() + "_" + protect("_Syms"); }
static string symClassVar() { return symClassName() + "* __restrict vlSymsp"; }
static string symClassAssign() {
return symClassName() + "* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;\n";
}
static string funcNameProtect(const AstCFunc* nodep, const AstNodeModule* modp = nullptr); static string funcNameProtect(const AstCFunc* nodep, const AstNodeModule* modp = nullptr);
static string prefixNameProtect(const AstNode* nodep) VL_MT_SAFE { // C++ name with prefix
return v3Global.opt.modPrefix() + "_" + protect(nodep->name());
}
static string topClassName() VL_MT_SAFE { // Return name of top wrapper module static string topClassName() VL_MT_SAFE { // Return name of top wrapper module
return v3Global.opt.prefix(); return v3Global.opt.prefix();
} }
static bool isConstPoolMod(const AstNode* modp) {
return modp == v3Global.rootp()->constPoolp()->modp();
}
static bool isAnonOk(const AstVar* varp) {
return v3Global.opt.compLimitMembers() != 0 // Enabled
&& !varp->isStatic() // Not a static variable
&& !varp->isSc() // Aggregates can't be anon
&& !VN_IS(varp->dtypep()->skipRefp(), SampleQueueDType) // Aggregates can't be anon
&& (varp->basicp() && !varp->basicp()->isOpaque()); // Aggregates can't be anon
}
static AstCFile* newCFile(const string& filename, bool slow, bool source, bool add = true); static AstCFile* newCFile(const string& filename, bool slow, bool source, bool add = true);
string cFuncArgs(const AstCFunc* nodep); string cFuncArgs(const AstCFunc* nodep);
void emitCFuncHeader(const AstCFunc* funcp, const AstNodeModule* modp, bool withScope); void emitCFuncHeader(const AstCFunc* funcp, const AstNodeModule* modp, bool withScope);

View File

@ -83,7 +83,7 @@ class EmitCLazyDecls final : public VNVisitorConst {
void visit(AstVarRef* nodep) override { void visit(AstVarRef* nodep) override {
AstVar* const varp = nodep->varp(); AstVar* const varp = nodep->varp();
// Only constant pool symbols are lazy declared for now ... // Only constant pool symbols are lazy declared for now ...
if (EmitCBaseVisitor::isConstPoolMod(EmitCParentModule::get(varp))) { if (EmitCBase::isConstPoolMod(EmitCParentModule::get(varp))) {
lazyDeclareConstPoolVar(varp); lazyDeclareConstPoolVar(varp);
} }
} }

View File

@ -224,7 +224,7 @@ class EmitCHeader final : public EmitCConstInit {
} }
} }
puts(sdtypep->verilogKwd()); // "struct"/"union" puts(sdtypep->verilogKwd()); // "struct"/"union"
puts(" " + EmitCBaseVisitor::prefixNameProtect(sdtypep) + " {\n"); puts(" " + EmitCBase::prefixNameProtect(sdtypep) + " {\n");
for (const AstMemberDType* itemp = sdtypep->membersp(); itemp; for (const AstMemberDType* itemp = sdtypep->membersp(); itemp;
itemp = VN_AS(itemp->nextp(), MemberDType)) { itemp = VN_AS(itemp->nextp(), MemberDType)) {
puts(itemp->dtypep()->cType(itemp->nameProtect(), false, false)); puts(itemp->dtypep()->cType(itemp->nameProtect(), false, false));

View File

@ -38,23 +38,22 @@ class EmitCGatherDependencies final : VNVisitorConst {
std::set<string> m_dependencies; // Header names to be included in output C++ file std::set<string> m_dependencies; // Header names to be included in output C++ file
// METHODS // METHODS
void addSymsDependency() { m_dependencies.insert(EmitCBaseVisitor::symClassName()); } void addSymsDependency() { m_dependencies.insert(EmitCBase::symClassName()); }
void addModDependency(const AstNodeModule* modp) { void addModDependency(const AstNodeModule* modp) {
if (const AstClass* const classp = VN_CAST(modp, Class)) { if (const AstClass* const classp = VN_CAST(modp, Class)) {
m_dependencies.insert(EmitCBaseVisitor::prefixNameProtect(classp->classOrPackagep())); m_dependencies.insert(EmitCBase::prefixNameProtect(classp->classOrPackagep()));
} else { } else {
m_dependencies.insert(EmitCBaseVisitor::prefixNameProtect(modp)); m_dependencies.insert(EmitCBase::prefixNameProtect(modp));
} }
} }
void addDTypeDependency(const AstNodeDType* nodep) { void addDTypeDependency(const AstNodeDType* nodep) {
if (const AstClassRefDType* const dtypep = VN_CAST(nodep, ClassRefDType)) { if (const AstClassRefDType* const dtypep = VN_CAST(nodep, ClassRefDType)) {
m_dependencies.insert( m_dependencies.insert(
EmitCBaseVisitor::prefixNameProtect(dtypep->classp()->classOrPackagep())); EmitCBase::prefixNameProtect(dtypep->classp()->classOrPackagep()));
} else if (const AstNodeUOrStructDType* const dtypep } else if (const AstNodeUOrStructDType* const dtypep
= VN_CAST(nodep, NodeUOrStructDType)) { = VN_CAST(nodep, NodeUOrStructDType)) {
if (!dtypep->packed()) { if (!dtypep->packed()) {
m_dependencies.insert( m_dependencies.insert(EmitCBase::prefixNameProtect(dtypep->classOrPackagep()));
EmitCBaseVisitor::prefixNameProtect(dtypep->classOrPackagep()));
} }
} }
} }

View File

@ -3129,8 +3129,8 @@ static const std::vector<AstCFunc*> createThreadFunctions(const ThreadSchedule&
funcp->argTypes("void* voidSelf, bool even_cycle"); funcp->argTypes("void* voidSelf, bool even_cycle");
// Setup vlSelf an vlSyms // Setup vlSelf an vlSyms
funcp->addStmtsp(new AstCStmt{fl, EmitCBaseVisitor::voidSelfAssign(modp)}); funcp->addStmtsp(new AstCStmt{fl, EmitCBase::voidSelfAssign(modp)});
funcp->addStmtsp(new AstCStmt{fl, EmitCBaseVisitor::symClassAssign()}); funcp->addStmtsp(new AstCStmt{fl, EmitCBase::symClassAssign()});
// Invoke each mtask scheduled to this thread from the thread function // Invoke each mtask scheduled to this thread from the thread function
for (const ExecMTask* const mtaskp : thread) { for (const ExecMTask* const mtaskp : thread) {

View File

@ -607,7 +607,7 @@ std::pair<AstVarScope*, AstNodeStmt*> makeEvalLoop(AstNetlist* netlistp, const s
AstTextBlock* const blockp = new AstTextBlock{flp}; AstTextBlock* const blockp = new AstTextBlock{flp};
failp->addThensp(blockp); failp->addThensp(blockp);
FileLine* const locp = netlistp->topModulep()->fileline(); FileLine* const locp = netlistp->topModulep()->fileline();
const string& file = EmitCBaseVisitor::protect(locp->filename()); const string& file = VIdProtect::protect(locp->filename());
const string& line = cvtToStr(locp->lineno()); const string& line = cvtToStr(locp->lineno());
const auto add = [&](const string& text) { blockp->addText(flp, text, true); }; const auto add = [&](const string& text) { blockp->addText(flp, text, true); };
add("#ifdef VL_DEBUG\n"); add("#ifdef VL_DEBUG\n");

View File

@ -362,7 +362,7 @@ void transformForks(AstNetlist* const netlistp) {
// If we're in a class, add a vlSymsp arg // If we're in a class, add a vlSymsp arg
if (m_inClass) { if (m_inClass) {
newfuncp->addInitsp(new AstCStmt{nodep->fileline(), "VL_KEEP_THIS;\n"}); newfuncp->addInitsp(new AstCStmt{nodep->fileline(), "VL_KEEP_THIS;\n"});
newfuncp->argTypes(EmitCBaseVisitor::symClassVar()); newfuncp->argTypes(EmitCBase::symClassVar());
callp->argTypes("vlSymsp"); callp->argTypes("vlSymsp");
} }
// Put the begin's statements in the function, delete the begin // Put the begin's statements in the function, delete the begin

View File

@ -802,7 +802,7 @@ private:
// Convert input/inout DPI arguments to Internal types // Convert input/inout DPI arguments to Internal types
string args; string args;
args += ("(" + EmitCBaseVisitor::symClassName() args += ("(" + EmitCBase::symClassName()
+ "*)(__Vscopep->symsp())"); // Upcast w/o overhead + "*)(__Vscopep->symsp())"); // Upcast w/o overhead
AstNode* argnodesp = nullptr; AstNode* argnodesp = nullptr;
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) { for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
@ -1181,15 +1181,14 @@ private:
cfuncp->isConstructor(true); cfuncp->isConstructor(true);
AstClass* const classp = m_statep->getClassp(nodep); AstClass* const classp = m_statep->getClassp(nodep);
if (classp->extendsp()) { if (classp->extendsp()) {
cfuncp->baseCtors( cfuncp->baseCtors(EmitCBase::prefixNameProtect(classp->extendsp()->classp()));
EmitCBaseVisitor::prefixNameProtect(classp->extendsp()->classp()));
} }
} }
if (cfuncp->dpiExportImpl()) cfuncp->cname(nodep->cname()); if (cfuncp->dpiExportImpl()) cfuncp->cname(nodep->cname());
if (!nodep->dpiImport() && !nodep->taskPublic()) { if (!nodep->dpiImport() && !nodep->taskPublic()) {
// Need symbol table // Need symbol table
cfuncp->argTypes(EmitCBaseVisitor::symClassVar()); cfuncp->argTypes(EmitCBase::symClassVar());
if (cfuncp->name() == "new") { if (cfuncp->name() == "new") {
const string stmt = VIdProtect::protect("_ctor_var_reset") + "(vlSymsp);\n"; const string stmt = VIdProtect::protect("_ctor_var_reset") + "(vlSymsp);\n";
cfuncp->addInitsp(new AstCStmt{nodep->fileline(), stmt}); cfuncp->addInitsp(new AstCStmt{nodep->fileline(), stmt});

View File

@ -154,7 +154,7 @@ public:
//###################################################################### //######################################################################
// Trace state, as a visitor of each AstNode // Trace state, as a visitor of each AstNode
class TraceVisitor final : public EmitCBaseVisitor { class TraceVisitor final : public VNVisitor {
private: private:
// NODE STATE // NODE STATE
// V3Hasher in V3DupFinder // V3Hasher in V3DupFinder
@ -511,8 +511,8 @@ private:
funcp->argTypes("void* voidSelf, " + v3Global.opt.traceClassBase() funcp->argTypes("void* voidSelf, " + v3Global.opt.traceClassBase()
+ "::" + (v3Global.opt.useTraceOffload() ? "OffloadBuffer" : "Buffer") + "::" + (v3Global.opt.useTraceOffload() ? "OffloadBuffer" : "Buffer")
+ "* bufp"); + "* bufp");
addInitStr(voidSelfAssign(m_topModp)); addInitStr(EmitCBase::voidSelfAssign(m_topModp));
addInitStr(symClassAssign()); addInitStr(EmitCBase::symClassAssign());
// Add global activity check to change dump functions // Add global activity check to change dump functions
if (!full) { // if (!full) { //
addInitStr("if (VL_UNLIKELY(!vlSymsp->__Vm_activity)) return;\n"); addInitStr("if (VL_UNLIKELY(!vlSymsp->__Vm_activity)) return;\n");
@ -709,8 +709,8 @@ private:
cleanupFuncp->isStatic(true); cleanupFuncp->isStatic(true);
cleanupFuncp->isLoose(true); cleanupFuncp->isLoose(true);
m_topScopep->addBlocksp(cleanupFuncp); m_topScopep->addBlocksp(cleanupFuncp);
cleanupFuncp->addInitsp(new AstCStmt{fl, voidSelfAssign(m_topModp)}); cleanupFuncp->addInitsp(new AstCStmt{fl, EmitCBase::voidSelfAssign(m_topModp)});
cleanupFuncp->addInitsp(new AstCStmt{fl, symClassAssign()}); cleanupFuncp->addInitsp(new AstCStmt{fl, EmitCBase::symClassAssign()});
// Register it // Register it
m_regFuncp->addStmtsp(new AstText{fl, "tracep->addCleanupCb(", true}); m_regFuncp->addStmtsp(new AstText{fl, "tracep->addCleanupCb(", true});

View File

@ -93,7 +93,7 @@ public:
//###################################################################### //######################################################################
// TraceDecl state, as a visitor of each AstNode // TraceDecl state, as a visitor of each AstNode
class TraceDeclVisitor final : public EmitCBaseVisitor { class TraceDeclVisitor final : public VNVisitor {
private: private:
// NODE STATE // NODE STATE

View File

@ -169,7 +169,7 @@ class VariableOrder final {
: (sigbytes == 1) ? 2 : (sigbytes == 1) ? 2
: 10; : 10;
// Anonymous structure ok // Anonymous structure ok
attributes.anonOk = EmitCBaseVisitor::isAnonOk(varp); attributes.anonOk = EmitCBase::isAnonOk(varp);
} }
} }