void cantInline(const char* reason, bool hard) { if (hard) { if (m_modp->user2() != CIL_NOTHARD) { UINFO(4," No inline hard: "<<reason<<" "<<m_modp<<endl); m_modp->user2(CIL_NOTHARD); m_statUnsup++; } } else { if (m_modp->user2() == CIL_MAYBE) { UINFO(4," No inline soft: "<<reason<<" "<<m_modp<<endl); m_modp->user2(CIL_NOTSOFT); } } }
// VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { m_stmtCnt = 0; m_modp = nodep; m_modp->user2(CIL_MAYBE); if (m_modp->castIface()) { // Inlining an interface means we no longer have a cell handle to resolve to. // If inlining moves post-scope this can perhaps be relaxed. cantInline("modIface",true); } if (m_modp->modPublic()) cantInline("modPublic",false); // nodep->iterateChildren(*this); // bool userinline = nodep->user1(); int allowed = nodep->user2(); int refs = nodep->user3(); // Should we automatically inline this module? // inlineMult = 2000 by default. If a mod*#instances is < this # nodes, can inline it bool doit = ((allowed == CIL_NOTSOFT || allowed == CIL_MAYBE) && (userinline || ((allowed == CIL_MAYBE) && (refs==1 || m_stmtCnt < INLINE_MODS_SMALLER || v3Global.opt.inlineMult() < 1 || refs*m_stmtCnt < v3Global.opt.inlineMult())))); // Packages aren't really "under" anything so they confuse this algorithm if (nodep->castPackage()) doit = false; UINFO(4, " Inline="<<doit<<" Possible="<<allowed<<" Usr="******" Refs="<<refs<<" Stmts="<<m_stmtCnt <<" "<<nodep<<endl); nodep->user1(doit); m_modp = NULL; }