Avoid repeated traversal for SC text sections in emit when not needed

Repeatedly traversing whole modules in emit (due to file splitting)
looking for `systemc_* sections can add up to a lot of time on large
designs that have been flattened and need to be split into many files.
Assuming `systemc_* is a rarely used feature, just don't bother if we
don't need to. This gain 9% verilation speed improvement on a large
benchmark.
This commit is contained in:
Geza Lore 2021-12-20 14:42:15 +00:00
parent 41a563bdc8
commit 9a8c878f2d
3 changed files with 13 additions and 6 deletions

View File

@ -235,6 +235,10 @@ void EmitCBaseVisitor::emitModCUse(const AstNodeModule* modp, VUseType useType)
}
void EmitCBaseVisitor::emitTextSection(const AstNodeModule* modp, VNType type) {
// Short circuit if nothing to do. This can save a lot of time on large designs as this
// function needs to traverse the entire module linearly.
if (!v3Global.hasSCTextSections()) return;
int last_line = -999;
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (const AstNodeText* const textp = VN_CAST(nodep, NodeText)) {

View File

@ -104,6 +104,7 @@ class V3Global final {
bool m_needTraceDumper = false; // Need __Vm_dumperp in symbols
bool m_dpi = false; // Need __Dpi include files
bool m_useForce = false; // Need force/release processing
bool m_hasSCTextSections = false; // Has `systemc_* sections that need to be emitted
bool m_useParallelBuild = false; // Use parallel build for model
bool m_useRandomizeMethods = false; // Need to define randomize() class methods
@ -146,6 +147,8 @@ public:
void needTraceDumper(bool flag) { m_needTraceDumper = flag; }
bool dpi() const { return m_dpi; }
void dpi(bool flag) { m_dpi = flag; }
bool hasSCTextSections() const { return m_hasSCTextSections; }
void setHasSCTextSections() { m_hasSCTextSections = true; }
V3HierBlockPlan* hierPlanp() const { return m_hierPlanp; }
void hierPlanp(V3HierBlockPlan* plan) {
UASSERT(!m_hierPlanp, "call once");

View File

@ -2293,12 +2293,12 @@ non_port_module_item<nodep>: // ==IEEE: non_port_module_item
{ $$ = nullptr; BBUNSUP(CRELINE(), "Unsupported: interface decls within module decls"); }
| timeunits_declaration { $$ = $1; }
// // Verilator specific
| yaSCHDR { $$ = new AstScHdr($<fl>1,*$1); }
| yaSCINT { $$ = new AstScInt($<fl>1,*$1); }
| yaSCIMP { $$ = new AstScImp($<fl>1,*$1); }
| yaSCIMPH { $$ = new AstScImpHdr($<fl>1,*$1); }
| yaSCCTOR { $$ = new AstScCtor($<fl>1,*$1); }
| yaSCDTOR { $$ = new AstScDtor($<fl>1,*$1); }
| yaSCHDR { $$ = new AstScHdr($<fl>1,*$1); v3Global.setHasSCTextSections(); }
| yaSCINT { $$ = new AstScInt($<fl>1,*$1); v3Global.setHasSCTextSections(); }
| yaSCIMP { $$ = new AstScImp($<fl>1,*$1); v3Global.setHasSCTextSections(); }
| yaSCIMPH { $$ = new AstScImpHdr($<fl>1,*$1); v3Global.setHasSCTextSections(); }
| yaSCCTOR { $$ = new AstScCtor($<fl>1,*$1); v3Global.setHasSCTextSections(); }
| yaSCDTOR { $$ = new AstScDtor($<fl>1,*$1); v3Global.setHasSCTextSections(); }
| yVL_HIER_BLOCK { $$ = new AstPragma($1,VPragmaType::HIER_BLOCK); }
| yVL_INLINE_MODULE { $$ = new AstPragma($1,VPragmaType::INLINE_MODULE); }
| yVL_NO_INLINE_MODULE { $$ = new AstPragma($1,VPragmaType::NO_INLINE_MODULE); }