From 631bda395d210cd8aea69bb6b5d1ab8c54a4bbf8 Mon Sep 17 00:00:00 2001 From: John Coiner Date: Tue, 28 Nov 2017 18:38:19 -0500 Subject: [PATCH] Avoid duplicated scans of CFuncs. Trace into non-entry-point functions (most of them) at their call sites. We'll trace into entry-point functions (like eval) from their parent scope. We must trace eval_ to reach the tree of calls beneath it. Signed-off-by: Wilson Snyder --- src/V3GenClk.cpp | 19 ++++++++++--------- src/V3Life.cpp | 7 ++++++- src/V3LifePost.cpp | 33 +++++++++++++++++++++++++++------ src/V3Stats.cpp | 13 ++++++++++--- 4 files changed, 53 insertions(+), 19 deletions(-) diff --git a/src/V3GenClk.cpp b/src/V3GenClk.cpp index a8c7beaf1..d032c329a 100644 --- a/src/V3GenClk.cpp +++ b/src/V3GenClk.cpp @@ -150,7 +150,7 @@ private: // STATE AstActive* m_activep; // Inside activate statement - AstCFunc* m_tracingCallp; // Currently tracing a call to this cfunc + bool m_tracingCall; // Iterating into a call to a cfunc AstNodeAssign* m_assignp; // Inside assigndly statement AstNodeModule* m_topModp; // Top module @@ -172,20 +172,21 @@ private: } } virtual void visit(AstCCall* nodep) { - nodep->iterateChildren(*this); - // Enter the function and trace it - - m_tracingCallp = nodep->funcp(); - nodep->funcp()->accept(*this); + nodep->iterateChildren(*this); + if (!nodep->funcp()->entryPoint()) { + // Enter the function and trace it + m_tracingCall = true; + nodep->funcp()->accept(*this); + } } virtual void visit(AstCFunc* nodep) { - if (m_tracingCallp != nodep) { + if (!m_tracingCall && !nodep->entryPoint()) { // Only consider logic within a CFunc when looking // at the call to it, and not when scanning whatever // scope it happens to live beneath. return; } - m_tracingCallp = NULL; + m_tracingCall = false; nodep->iterateChildren(*this); } //---- @@ -228,7 +229,7 @@ public: // CONSTRUCTORS explicit GenClkReadVisitor(AstNetlist* nodep) : m_activep(NULL) - , m_tracingCallp(NULL) + , m_tracingCall(false) , m_assignp(NULL) , m_topModp(NULL) { nodep->accept(*this); diff --git a/src/V3Life.cpp b/src/V3Life.cpp index da227a525..9d775ece9 100644 --- a/src/V3Life.cpp +++ b/src/V3Life.cpp @@ -288,6 +288,7 @@ private: LifeState* m_statep; // Current state bool m_sideEffect; // Side effects discovered in assign RHS bool m_noopt; // Disable optimization of variables in this block + bool m_tracingCall; // Iterating into a CCall to a CFunc // LIFE MAP // For each basic block, we'll make a new map of what variables that if/else is changing @@ -423,11 +424,14 @@ private: nodep->iterateChildren(*this); // Enter the function and trace it if (!nodep->funcp()->entryPoint()) { // else is non-inline or public function we optimize separately - nodep->funcp()->accept(*this); + m_tracingCall = true; + nodep->funcp()->accept(*this); } } virtual void visit(AstCFunc* nodep) { //UINFO(4," CCALL "<entryPoint()) return; + m_tracingCall = false; if (nodep->dpiImport() && !nodep->pure()) { m_sideEffect = true; // If appears on assign RHS, don't ever delete the assignment } @@ -454,6 +458,7 @@ public: m_statep = statep; m_sideEffect = false; m_noopt = false; + m_tracingCall = false; { m_lifep = new LifeBlock (NULL, m_statep); nodep->accept(*this); diff --git a/src/V3LifePost.cpp b/src/V3LifePost.cpp index 868afe48b..6e4462870 100644 --- a/src/V3LifePost.cpp +++ b/src/V3LifePost.cpp @@ -56,6 +56,8 @@ protected: class LifePostElimVisitor : public LifePostBaseVisitor { private: + bool m_tracingCall; // Iterating into a CCall to a CFunc + // NODE STATE // INPUT: // AstVarScope::user4p() -> AstVarScope*, If set, replace this varscope with specified new one @@ -77,8 +79,16 @@ private: } virtual void visit(AstCCall* nodep) { nodep->iterateChildren(*this); - // Enter the function and trace it - nodep->funcp()->accept(*this); + if (!nodep->funcp()->entryPoint()) { + // Enter the function and trace it + m_tracingCall = true; + nodep->funcp()->accept(*this); + } + } + virtual void visit(AstCFunc* nodep) { + if (!m_tracingCall && !nodep->entryPoint()) return; + m_tracingCall = false; + nodep->iterateChildren(*this); } virtual void visit(AstVar*) {} // Don't want varrefs under it virtual void visit(AstNode* nodep) { @@ -86,7 +96,8 @@ private: } public: // CONSTRUCTORS - explicit LifePostElimVisitor(AstTopScope* nodep) { + explicit LifePostElimVisitor(AstTopScope* nodep) + : m_tracingCall(false) { nodep->accept(*this); } virtual ~LifePostElimVisitor() {} @@ -109,6 +120,7 @@ private: // STATE uint32_t m_sequence; // Sequence number of assignments/varrefs V3Double0 m_statAssnDel; // Statistic tracking + bool m_tracingCall; // Tracing a CCall to a CFunc // VISITORS virtual void visit(AstTopScope* nodep) { @@ -167,8 +179,16 @@ private: } virtual void visit(AstCCall* nodep) { nodep->iterateChildren(*this); - // Enter the function and trace it - nodep->funcp()->accept(*this); + if (!nodep->funcp()->entryPoint()) { + // Enter the function and trace it + m_tracingCall = true; + nodep->funcp()->accept(*this); + } + } + virtual void visit(AstCFunc* nodep) { + if (!m_tracingCall && !nodep->entryPoint()) return; + m_tracingCall = false; + nodep->iterateChildren(*this); } //----- @@ -178,7 +198,8 @@ private: } public: // CONSTRUCTORS - explicit LifePostDlyVisitor(AstNetlist* nodep) { + explicit LifePostDlyVisitor(AstNetlist* nodep) + : m_tracingCall(false) { nodep->accept(*this); } virtual ~LifePostDlyVisitor() { diff --git a/src/V3Stats.cpp b/src/V3Stats.cpp index d9740eb49..3c68b4080 100644 --- a/src/V3Stats.cpp +++ b/src/V3Stats.cpp @@ -53,6 +53,7 @@ private: V3Double0 m_statInstrLong; // Instruction count bool m_counting; // Currently counting double m_instrs; // Current instr count (for determining branch direction) + bool m_tracingCall; // Iterating into a CCall to a CFunc vector m_statTypeCount; // Nodes of given type V3Double0 m_statAbove[AstType::_ENUM_END][AstType::_ENUM_END]; // Nodes of given type @@ -192,12 +193,17 @@ private: virtual void visit(AstCCall* nodep) { allNodes(nodep); nodep->iterateChildrenConst(*this); - if (m_fast) { + if (m_fast && !nodep->funcp()->entryPoint()) { // Enter the function and trace it - nodep->funcp()->accept(*this); - } + m_tracingCall = true; + nodep->funcp()->accept(*this); + } } virtual void visit(AstCFunc* nodep) { + if (m_fast) { + if (!m_tracingCall && !nodep->entryPoint()) return; + m_tracingCall = false; + } m_cfuncp = nodep; allNodes(nodep); nodep->iterateChildrenConst(*this); @@ -215,6 +221,7 @@ public: m_cfuncp = NULL; m_counting = !m_fast; m_instrs = 0; + m_tracingCall = false; // Initialize arrays m_statTypeCount.resize(AstType::_ENUM_END); // Process