Optimize empty function definition bodies (#5750).
This commit is contained in:
parent
98e40c847c
commit
001c098e5a
1
Changes
1
Changes
|
@ -26,6 +26,7 @@ Verilator 5.033 devel
|
|||
* Improve VPI write errors (#5712). [Andrew Nolte]
|
||||
* Improve `resetall support (#5728) (#5730). [Ethan Sifferman]
|
||||
* Optimize labels as final `if` block statements (#5744).
|
||||
* Optimize empty function definition bodies (#5750).
|
||||
* Fix error message when call task as a function (#3089). [Matthew Ballance]
|
||||
* Fix VPI iteration over hierarchy (#5314) (#5731). [Natan Kreimer]
|
||||
* Fix constrained random for > 64-bit associative arrays (#5670) (#5682). [Yilou Wang]
|
||||
|
|
|
@ -625,6 +625,7 @@ class AstCFunc final : public AstNode {
|
|||
bool m_isTrace : 1; // Function is related to tracing
|
||||
bool m_dontCombine : 1; // V3Combine shouldn't compare this func tree, it's special
|
||||
bool m_declPrivate : 1; // Declare it private
|
||||
bool m_keepIfEmpty : 1; // Keep declaration and definition separate, even if empty
|
||||
bool m_slow : 1; // Slow routine, called once or just at init time
|
||||
bool m_funcPublic : 1; // From user public task/function
|
||||
bool m_isConstructor : 1; // Is C class constructor
|
||||
|
@ -655,6 +656,7 @@ public:
|
|||
m_isTrace = false;
|
||||
m_dontCombine = false;
|
||||
m_declPrivate = false;
|
||||
m_keepIfEmpty = false;
|
||||
m_slow = false;
|
||||
m_funcPublic = false;
|
||||
m_isConstructor = false;
|
||||
|
@ -706,6 +708,8 @@ public:
|
|||
bool dontInline() const { return dontCombine() || slow() || funcPublic(); }
|
||||
bool declPrivate() const { return m_declPrivate; }
|
||||
void declPrivate(bool flag) { m_declPrivate = flag; }
|
||||
bool keepIfEmpty() const VL_MT_SAFE { return m_keepIfEmpty; }
|
||||
void keepIfEmpty(bool flag) { m_keepIfEmpty = flag; }
|
||||
bool slow() const VL_MT_SAFE { return m_slow; }
|
||||
void slow(bool flag) { m_slow = flag; }
|
||||
bool funcPublic() const { return m_funcPublic; }
|
||||
|
@ -749,8 +753,7 @@ public:
|
|||
void cost(int cost) { m_cost = cost; }
|
||||
// Special methods
|
||||
bool emptyBody() const {
|
||||
return argsp() == nullptr && initsp() == nullptr && stmtsp() == nullptr
|
||||
&& finalsp() == nullptr;
|
||||
return !keepIfEmpty() && !argsp() && !initsp() && !stmtsp() && !finalsp();
|
||||
}
|
||||
};
|
||||
class AstCLocalScope final : public AstNode {
|
||||
|
|
|
@ -2865,15 +2865,17 @@ void AstCFile::dumpJson(std::ostream& str) const {
|
|||
void AstCFunc::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
if (slow()) str << " [SLOW]";
|
||||
if (dpiPure()) str << " [DPIPURE]";
|
||||
if (isStatic()) str << " [STATIC]";
|
||||
if (dpiContext()) str << " [DPICTX]";
|
||||
if (dpiExportDispatcher()) str << " [DPIED]";
|
||||
if (dpiExportImpl()) str << " [DPIEI]";
|
||||
if (dpiImportPrototype()) str << " [DPIIP]";
|
||||
if (dpiImportWrapper()) str << " [DPIIW]";
|
||||
if (dpiContext()) str << " [DPICTX]";
|
||||
if (dpiPure()) str << " [DPIPURE]";
|
||||
if (isConstructor()) str << " [CTOR]";
|
||||
if (isDestructor()) str << " [DTOR]";
|
||||
if (isMethod()) str << " [METHOD]";
|
||||
if (isLoose()) str << " [LOOSE]";
|
||||
if (isVirtual()) str << " [VIRT]";
|
||||
if (isCoroutine()) str << " [CORO]";
|
||||
if (needProcess()) str << " [NPRC]";
|
||||
|
|
|
@ -62,6 +62,7 @@ class V3CCtorsBuilder final {
|
|||
AstCFunc* const funcp = new AstCFunc{m_modp->fileline(), funcName, nullptr, "void"};
|
||||
funcp->isStatic(false);
|
||||
funcp->isLoose(!m_type.isClass());
|
||||
funcp->keepIfEmpty(true); // TODO relax
|
||||
funcp->declPrivate(true);
|
||||
funcp->slow(!m_type.isClass()); // Only classes construct on fast path
|
||||
string preventUnusedStmt;
|
||||
|
@ -210,6 +211,7 @@ void V3CCtors::evalAsserts() {
|
|||
funcp->declPrivate(true);
|
||||
funcp->isStatic(false);
|
||||
funcp->isLoose(true);
|
||||
funcp->keepIfEmpty(true);
|
||||
funcp->slow(false);
|
||||
funcp->ifdef("VL_DEBUG");
|
||||
modp->addStmtsp(funcp);
|
||||
|
|
|
@ -171,7 +171,11 @@ void EmitCBaseVisitorConst::emitCFuncDecl(const AstCFunc* funcp, const AstNodeMo
|
|||
putns(funcp, "virtual ");
|
||||
}
|
||||
emitCFuncHeader(funcp, modp, /* withScope: */ false);
|
||||
putns(funcp, ";\n");
|
||||
if (funcp->emptyBody() && !funcp->isLoose() && !cLinkage) {
|
||||
putns(funcp, " {}\n");
|
||||
} else {
|
||||
putns(funcp, ";\n");
|
||||
}
|
||||
if (!funcp->ifdef().empty()) putns(funcp, "#endif // " + funcp->ifdef() + "\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -280,6 +280,7 @@ public:
|
|||
// VISITORS
|
||||
using EmitCConstInit::visit;
|
||||
void visit(AstCFunc* nodep) override {
|
||||
if (nodep->emptyBody() && !nodep->isLoose()) return;
|
||||
VL_RESTORER(m_useSelfForThis);
|
||||
VL_RESTORER(m_cfuncp);
|
||||
VL_RESTORER(m_instantiatesOwnProcess)
|
||||
|
|
|
@ -70,6 +70,7 @@ AstCFunc* makeSubFunction(AstNetlist* netlistp, const string& name, bool slow) {
|
|||
AstCFunc* makeTopFunction(AstNetlist* netlistp, const string& name, bool slow) {
|
||||
AstCFunc* const funcp = makeSubFunction(netlistp, name, slow);
|
||||
funcp->entryPoint(true);
|
||||
funcp->keepIfEmpty(true);
|
||||
return funcp;
|
||||
}
|
||||
|
||||
|
|
|
@ -185,7 +185,6 @@
|
|||
-V{t#,#} Awaiting time 101: Process waiting at t/t_timing_class.v:274
|
||||
-V{t#,#} Resuming delayed processes
|
||||
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:173
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelay10::__VnoInFunc_do_sth_else
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelay20::__VnoInFunc_do_delay
|
||||
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:247
|
||||
-V{t#,#} Process forked at t/t_timing_class.v:246 finished
|
||||
|
@ -499,7 +498,6 @@
|
|||
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:257
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aForkDelayClass::__VnoInFunc_do_delay
|
||||
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:174
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelay20::__VnoInFunc_do_sth_else
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelay40::__VnoInFunc_do_delay
|
||||
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:131
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aClkClass::__VnoInFunc_flip
|
||||
|
@ -1038,9 +1036,7 @@
|
|||
-V{t#,#} Process forked at t/t_timing_class.v:250 finished
|
||||
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:245
|
||||
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:175
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelay40::__VnoInFunc_do_sth_else
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aNoDelay::__VnoInFunc_do_delay
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aNoDelay::__VnoInFunc_do_sth_else
|
||||
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__Vtiming__6____Vfork_1__0
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aAssignDelayClass::__VnoInFunc_do_assign
|
||||
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:76
|
||||
|
@ -1082,8 +1078,6 @@
|
|||
-V{t#,#}End-of-eval cleanup
|
||||
-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
|
||||
-V{t#,#}+ Vt_timing_debug2___024root___eval_debug_assertions
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aForkDelayClass::~
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aForkClass::~
|
||||
-V{t#,#}+ Eval
|
||||
-V{t#,#}+ Vt_timing_debug2___024root___eval
|
||||
-V{t#,#}+ Vt_timing_debug2___024root___eval_phase__act
|
||||
|
@ -1236,7 +1230,6 @@
|
|||
-V{t#,#}End-of-eval cleanup
|
||||
-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
|
||||
-V{t#,#}+ Vt_timing_debug2___024root___eval_debug_assertions
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aAssignDelayClass::~
|
||||
-V{t#,#}+ Eval
|
||||
-V{t#,#}+ Vt_timing_debug2___024root___eval
|
||||
-V{t#,#}+ Vt_timing_debug2___024root___eval_phase__act
|
||||
|
@ -1308,18 +1301,3 @@
|
|||
-V{t#,#}+ Vt_timing_debug2___024root___eval_phase__nba
|
||||
-V{t#,#}End-of-eval cleanup
|
||||
-V{t#,#}+ Vt_timing_debug2___024root___eval_final
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelay40::~
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelayClass::~
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelay20::~
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelayClass::~
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelay10::~
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelayClass::~
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aNoDelay::~
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelayClass::~
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aClkClass::~
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aLocalWaitClass::~
|
||||
-V{t#,#}+ Vt_timing_debug2___024unit__03a__03aBaseClass::~
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aWaitClass::~
|
||||
-V{t#,#}+ Vt_timing_debug2___024unit__03a__03aBaseClass::~
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aEventClass::~
|
||||
-V{t#,#}+ Vt_timing_debug2___024unit__03a__03aBaseClass::~
|
||||
|
|
Loading…
Reference in New Issue