Internals: Allow const & non-member CFuncs for class branch. No functional change.

This commit is contained in:
Wilson Snyder 2020-02-01 10:57:55 -05:00
parent f00ff61559
commit 80d94891e1
6 changed files with 43 additions and 24 deletions

View File

@ -544,9 +544,12 @@ public:
static const char* const names[] = { static const char* const names[] = {
"FALSE", "TRUE", "UNK"}; "FALSE", "TRUE", "UNK"};
return names[m_e]; } return names[m_e]; }
bool trueU() const { return m_e == BU_TRUE || m_e == BU_UNKNOWN; } bool trueKnown() const { return m_e == BU_TRUE; }
bool falseU() const { return m_e == BU_FALSE || m_e == BU_UNKNOWN; } bool trueUnknown() const { return m_e == BU_TRUE || m_e == BU_UNKNOWN; }
bool falseKnown() const { return m_e == BU_FALSE; }
bool falseUnknown() const { return m_e == BU_FALSE || m_e == BU_UNKNOWN; }
bool unknown() const { return m_e == BU_UNKNOWN; } bool unknown() const { return m_e == BU_UNKNOWN; }
void setTrueOrFalse(bool flag) { m_e = flag ? BU_TRUE : BU_FALSE; }
}; };
inline bool operator==(VBoolOrUnknown lhs, VBoolOrUnknown rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator==(VBoolOrUnknown lhs, VBoolOrUnknown rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator==(VBoolOrUnknown lhs, VBoolOrUnknown::en rhs) { return (lhs.m_e == rhs); } inline bool operator==(VBoolOrUnknown lhs, VBoolOrUnknown::en rhs) { return (lhs.m_e == rhs); }

View File

@ -1336,7 +1336,7 @@ void AstCFunc::dump(std::ostream& str) const {
if (slow()) str<<" [SLOW]"; if (slow()) str<<" [SLOW]";
if (pure()) str<<" [PURE]"; if (pure()) str<<" [PURE]";
if (isStatic().unknown()) str<<" [STATICU]"; if (isStatic().unknown()) str<<" [STATICU]";
else if (isStatic().trueU()) str<<" [STATIC]"; else if (isStatic().trueUnknown()) str<<" [STATIC]";
if (dpiImport()) str<<" [DPII]"; if (dpiImport()) str<<" [DPII]";
if (dpiExport()) str<<" [DPIX]"; if (dpiExport()) str<<" [DPIX]";
if (dpiExportWrapper()) str<<" [DPIXWR]"; if (dpiExportWrapper()) str<<" [DPIXWR]";

View File

@ -6629,6 +6629,7 @@ private:
string m_rtnType; // void, bool, or other return type string m_rtnType; // void, bool, or other return type
string m_argTypes; string m_argTypes;
string m_ifdef; // #ifdef symbol around this function string m_ifdef; // #ifdef symbol around this function
VBoolOrUnknown m_isConst; // Function is declared const (*this not changed)
VBoolOrUnknown m_isStatic; // Function is declared static (no this) VBoolOrUnknown m_isStatic; // Function is declared static (no this)
bool m_dontCombine:1; // V3Combine shouldn't compare this func tree, it's special bool m_dontCombine:1; // V3Combine shouldn't compare this func tree, it's special
bool m_skipDecl:1; // Don't declare it bool m_skipDecl:1; // Don't declare it
@ -6636,6 +6637,7 @@ private:
bool m_formCallTree:1; // Make a global function to call entire tree of functions bool m_formCallTree:1; // Make a global function to call entire tree of functions
bool m_slow:1; // Slow routine, called once or just at init time bool m_slow:1; // Slow routine, called once or just at init time
bool m_funcPublic:1; // From user public task/function bool m_funcPublic:1; // From user public task/function
bool m_isMethod:1; // Is inside a class definition
bool m_isInline:1; // Inline function bool m_isInline:1; // Inline function
bool m_symProlog:1; // Setup symbol table for later instructions bool m_symProlog:1; // Setup symbol table for later instructions
bool m_entryPoint:1; // User may call into this top level function bool m_entryPoint:1; // User may call into this top level function
@ -6648,6 +6650,7 @@ public:
AstCFunc(FileLine* fl, const string& name, AstScope* scopep, const string& rtnType="") AstCFunc(FileLine* fl, const string& name, AstScope* scopep, const string& rtnType="")
: ASTGEN_SUPER(fl) { : ASTGEN_SUPER(fl) {
m_funcType = AstCFuncType::FT_NORMAL; m_funcType = AstCFuncType::FT_NORMAL;
m_isConst = VBoolOrUnknown::BU_UNKNOWN; // Unknown until analyzed
m_isStatic = VBoolOrUnknown::BU_UNKNOWN; // Unknown until see where thisp needed m_isStatic = VBoolOrUnknown::BU_UNKNOWN; // Unknown until see where thisp needed
m_scopep = scopep; m_scopep = scopep;
m_name = name; m_name = name;
@ -6658,6 +6661,7 @@ public:
m_formCallTree = false; m_formCallTree = false;
m_slow = false; m_slow = false;
m_funcPublic = false; m_funcPublic = false;
m_isMethod = true;
m_isInline = false; m_isInline = false;
m_symProlog = false; m_symProlog = false;
m_entryPoint = false; m_entryPoint = false;
@ -6683,8 +6687,11 @@ public:
// //
virtual void name(const string& name) { m_name = name; } virtual void name(const string& name) { m_name = name; }
virtual int instrCount() const { return dpiImport() ? instrCountDpi() : 0; } virtual int instrCount() const { return dpiImport() ? instrCountDpi() : 0; }
VBoolOrUnknown isConst() const { return m_isConst; }
void isConst(bool flag) { m_isConst.setTrueOrFalse(flag); }
void isConst(VBoolOrUnknown flag) { m_isConst = flag; }
VBoolOrUnknown isStatic() const { return m_isStatic; } VBoolOrUnknown isStatic() const { return m_isStatic; }
void isStatic(bool flag) { m_isStatic = flag ? VBoolOrUnknown::BU_TRUE : VBoolOrUnknown::BU_FALSE; } void isStatic(bool flag) { m_isStatic.setTrueOrFalse(flag); }
void isStatic(VBoolOrUnknown flag) { m_isStatic = flag; } void isStatic(VBoolOrUnknown flag) { m_isStatic = flag; }
void cname(const string& name) { m_cname = name; } void cname(const string& name) { m_cname = name; }
string cname() const { return m_cname; } string cname() const { return m_cname; }
@ -6710,6 +6717,8 @@ public:
string ifdef() const { return m_ifdef; } string ifdef() const { return m_ifdef; }
void funcType(AstCFuncType flag) { m_funcType = flag; } void funcType(AstCFuncType flag) { m_funcType = flag; }
AstCFuncType funcType() const { return m_funcType; } AstCFuncType funcType() const { return m_funcType; }
bool isMethod() const { return m_isMethod; }
void isMethod(bool flag) { m_isMethod = flag; }
bool isInline() const { return m_isInline; } bool isInline() const { return m_isInline; }
void isInline(bool flag) { m_isInline = flag; } void isInline(bool flag) { m_isInline = flag; }
bool symProlog() const { return m_symProlog; } bool symProlog() const { return m_symProlog; }

View File

@ -138,7 +138,7 @@ private:
// (Here instead of new visitor after V3Descope just to avoid another visitor) // (Here instead of new visitor after V3Descope just to avoid another visitor)
void needNonStaticFunc(AstNode* nodep) { void needNonStaticFunc(AstNode* nodep) {
UASSERT_OBJ(m_funcp, nodep, "Non-static accessor not under a function"); UASSERT_OBJ(m_funcp, nodep, "Non-static accessor not under a function");
if (m_funcp->isStatic().trueU()) { if (m_funcp->isStatic().trueUnknown()) {
UINFO(5,"Mark non-public due to "<<nodep<<endl); UINFO(5,"Mark non-public due to "<<nodep<<endl);
m_funcp->isStatic(false); m_funcp->isStatic(false);
} }

View File

@ -273,7 +273,7 @@ private:
virtual void visit(AstCFunc* nodep) VL_OVERRIDE { virtual void visit(AstCFunc* nodep) VL_OVERRIDE {
if (!nodep->user1()) { if (!nodep->user1()) {
m_needThis = false; m_needThis = false;
m_allowThis = nodep->isStatic().falseU(); // Non-static or unknown if static m_allowThis = nodep->isStatic().falseUnknown(); // Non-static or unknown if static
iterateChildren(nodep); iterateChildren(nodep);
nodep->user1(true); nodep->user1(true);
if (m_needThis) nodep->isStatic(false); if (m_needThis) nodep->isStatic(false);

View File

@ -155,13 +155,17 @@ public:
return lhsp->name() < rhsp->name(); return lhsp->name() < rhsp->name();
} }
}; };
void emitIntFuncDecls(AstNodeModule* modp) { void emitIntFuncDecls(AstNodeModule* modp, bool methodFuncs) {
typedef std::vector<const AstCFunc*> FuncVec; typedef std::vector<const AstCFunc*> FuncVec;
FuncVec funcsp; FuncVec funcsp;
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) { for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (const AstCFunc* funcp = VN_CAST(nodep, CFunc)) { if (const AstCFunc* funcp = VN_CAST(nodep, CFunc)) {
if (!funcp->skipDecl()) { funcsp.push_back(funcp); } if (!funcp->skipDecl()
&& funcp->isMethod() == methodFuncs
&& !funcp->dpiImport()) { // DPI is prototyped in __Dpi.h
funcsp.push_back(funcp);
}
} }
} }
@ -169,21 +173,20 @@ public:
for (FuncVec::iterator it = funcsp.begin(); it != funcsp.end(); ++it) { for (FuncVec::iterator it = funcsp.begin(); it != funcsp.end(); ++it) {
const AstCFunc* funcp = *it; const AstCFunc* funcp = *it;
if (!funcp->dpiImport()) { // DPI is prototyped in __Dpi.h
ofp()->putsPrivate(funcp->declPrivate()); ofp()->putsPrivate(funcp->declPrivate());
if (!funcp->ifdef().empty()) puts("#ifdef " + funcp->ifdef() + "\n"); if (!funcp->ifdef().empty()) puts("#ifdef " + funcp->ifdef() + "\n");
if (funcp->isStatic().trueU()) puts("static "); if (funcp->isStatic().trueUnknown()) puts("static ");
puts(funcp->rtnTypeVoid()); puts(funcp->rtnTypeVoid());
puts(" "); puts(" ");
puts(funcp->nameProtect()); puts(funcp->nameProtect());
puts("(" + cFuncArgs(funcp) + ")"); puts("(" + cFuncArgs(funcp) + ")");
if (funcp->isConst().trueKnown()) puts(" const");
if (funcp->slow()) puts(" VL_ATTR_COLD"); if (funcp->slow()) puts(" VL_ATTR_COLD");
puts(";\n"); puts(";\n");
if (!funcp->ifdef().empty()) puts("#endif // " + funcp->ifdef() + "\n"); if (!funcp->ifdef().empty()) puts("#endif // " + funcp->ifdef() + "\n");
} }
}
if (modp->isTop() && v3Global.opt.mtasks()) { if (methodFuncs && modp->isTop() && v3Global.opt.mtasks()) {
// Emit the mtask func prototypes. // Emit the mtask func prototypes.
AstExecGraph* execGraphp = v3Global.rootp()->execGraphp(); AstExecGraph* execGraphp = v3Global.rootp()->execGraphp();
UASSERT_OBJ(execGraphp, v3Global.rootp(), "Root should have an execGraphp"); UASSERT_OBJ(execGraphp, v3Global.rootp(), "Root should have an execGraphp");
@ -1245,8 +1248,10 @@ class EmitCImp : EmitCStmts {
if (nodep->ifdef()!="") puts("#ifdef "+nodep->ifdef()+"\n"); if (nodep->ifdef()!="") puts("#ifdef "+nodep->ifdef()+"\n");
if (nodep->isInline()) puts("VL_INLINE_OPT "); if (nodep->isInline()) puts("VL_INLINE_OPT ");
puts(nodep->rtnTypeVoid()); puts(" "); puts(nodep->rtnTypeVoid()); puts(" ");
puts(prefixNameProtect(m_modp) + "::" + nodep->nameProtect() + "(" + cFuncArgs(nodep) if (nodep->isMethod()) puts(prefixNameProtect(m_modp) + "::");
+ ") {\n"); puts(nodep->nameProtect() + "(" + cFuncArgs(nodep) + ")");
if (nodep->isConst().trueKnown()) puts(" const");
puts(" {\n");
// "+" in the debug indicates a print from the model // "+" in the debug indicates a print from the model
puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+ "); puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+ ");
@ -2738,7 +2743,7 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
ofp()->putsPrivate(false); // public: ofp()->putsPrivate(false); // public:
puts("void "+protect("__Vconfigure")+"("+symClassName()+"* symsp, bool first);\n"); puts("void "+protect("__Vconfigure")+"("+symClassName()+"* symsp, bool first);\n");
emitIntFuncDecls(modp); emitIntFuncDecls(modp, true);
if (v3Global.opt.trace()) { if (v3Global.opt.trace()) {
ofp()->putsPrivate(false); // public: ofp()->putsPrivate(false); // public:
@ -2757,6 +2762,8 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
puts("} VL_ATTR_ALIGNED(128);\n"); puts("} VL_ATTR_ALIGNED(128);\n");
emitIntFuncDecls(modp, false);
// Save/restore // Save/restore
if (v3Global.opt.savable() && modp->isTop()) { if (v3Global.opt.savable() && modp->isTop()) {
puts("\n"); puts("\n");