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 <wsnyder@wsnyder.org>
This commit is contained in:
John Coiner 2017-11-28 18:38:19 -05:00 committed by Wilson Snyder
parent 791d02a753
commit 631bda395d
4 changed files with 53 additions and 19 deletions

View File

@ -150,7 +150,7 @@ private:
// STATE // STATE
AstActive* m_activep; // Inside activate statement 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 AstNodeAssign* m_assignp; // Inside assigndly statement
AstNodeModule* m_topModp; // Top module AstNodeModule* m_topModp; // Top module
@ -172,20 +172,21 @@ private:
} }
} }
virtual void visit(AstCCall* nodep) { virtual void visit(AstCCall* nodep) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
// Enter the function and trace it if (!nodep->funcp()->entryPoint()) {
// Enter the function and trace it
m_tracingCallp = nodep->funcp(); m_tracingCall = true;
nodep->funcp()->accept(*this); nodep->funcp()->accept(*this);
}
} }
virtual void visit(AstCFunc* nodep) { virtual void visit(AstCFunc* nodep) {
if (m_tracingCallp != nodep) { if (!m_tracingCall && !nodep->entryPoint()) {
// Only consider logic within a CFunc when looking // Only consider logic within a CFunc when looking
// at the call to it, and not when scanning whatever // at the call to it, and not when scanning whatever
// scope it happens to live beneath. // scope it happens to live beneath.
return; return;
} }
m_tracingCallp = NULL; m_tracingCall = false;
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
} }
//---- //----
@ -228,7 +229,7 @@ public:
// CONSTRUCTORS // CONSTRUCTORS
explicit GenClkReadVisitor(AstNetlist* nodep) explicit GenClkReadVisitor(AstNetlist* nodep)
: m_activep(NULL) : m_activep(NULL)
, m_tracingCallp(NULL) , m_tracingCall(false)
, m_assignp(NULL) , m_assignp(NULL)
, m_topModp(NULL) { , m_topModp(NULL) {
nodep->accept(*this); nodep->accept(*this);

View File

@ -288,6 +288,7 @@ private:
LifeState* m_statep; // Current state LifeState* m_statep; // Current state
bool m_sideEffect; // Side effects discovered in assign RHS bool m_sideEffect; // Side effects discovered in assign RHS
bool m_noopt; // Disable optimization of variables in this block bool m_noopt; // Disable optimization of variables in this block
bool m_tracingCall; // Iterating into a CCall to a CFunc
// LIFE MAP // LIFE MAP
// For each basic block, we'll make a new map of what variables that if/else is changing // 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); nodep->iterateChildren(*this);
// Enter the function and trace it // Enter the function and trace it
if (!nodep->funcp()->entryPoint()) { // else is non-inline or public function we optimize separately 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) { virtual void visit(AstCFunc* nodep) {
//UINFO(4," CCALL "<<nodep<<endl); //UINFO(4," CCALL "<<nodep<<endl);
if (!m_tracingCall && !nodep->entryPoint()) return;
m_tracingCall = false;
if (nodep->dpiImport() && !nodep->pure()) { if (nodep->dpiImport() && !nodep->pure()) {
m_sideEffect = true; // If appears on assign RHS, don't ever delete the assignment m_sideEffect = true; // If appears on assign RHS, don't ever delete the assignment
} }
@ -454,6 +458,7 @@ public:
m_statep = statep; m_statep = statep;
m_sideEffect = false; m_sideEffect = false;
m_noopt = false; m_noopt = false;
m_tracingCall = false;
{ {
m_lifep = new LifeBlock (NULL, m_statep); m_lifep = new LifeBlock (NULL, m_statep);
nodep->accept(*this); nodep->accept(*this);

View File

@ -56,6 +56,8 @@ protected:
class LifePostElimVisitor : public LifePostBaseVisitor { class LifePostElimVisitor : public LifePostBaseVisitor {
private: private:
bool m_tracingCall; // Iterating into a CCall to a CFunc
// NODE STATE // NODE STATE
// INPUT: // INPUT:
// AstVarScope::user4p() -> AstVarScope*, If set, replace this varscope with specified new one // AstVarScope::user4p() -> AstVarScope*, If set, replace this varscope with specified new one
@ -77,8 +79,16 @@ private:
} }
virtual void visit(AstCCall* nodep) { virtual void visit(AstCCall* nodep) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
// Enter the function and trace it if (!nodep->funcp()->entryPoint()) {
nodep->funcp()->accept(*this); // 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(AstVar*) {} // Don't want varrefs under it
virtual void visit(AstNode* nodep) { virtual void visit(AstNode* nodep) {
@ -86,7 +96,8 @@ private:
} }
public: public:
// CONSTRUCTORS // CONSTRUCTORS
explicit LifePostElimVisitor(AstTopScope* nodep) { explicit LifePostElimVisitor(AstTopScope* nodep)
: m_tracingCall(false) {
nodep->accept(*this); nodep->accept(*this);
} }
virtual ~LifePostElimVisitor() {} virtual ~LifePostElimVisitor() {}
@ -109,6 +120,7 @@ private:
// STATE // STATE
uint32_t m_sequence; // Sequence number of assignments/varrefs uint32_t m_sequence; // Sequence number of assignments/varrefs
V3Double0 m_statAssnDel; // Statistic tracking V3Double0 m_statAssnDel; // Statistic tracking
bool m_tracingCall; // Tracing a CCall to a CFunc
// VISITORS // VISITORS
virtual void visit(AstTopScope* nodep) { virtual void visit(AstTopScope* nodep) {
@ -167,8 +179,16 @@ private:
} }
virtual void visit(AstCCall* nodep) { virtual void visit(AstCCall* nodep) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
// Enter the function and trace it if (!nodep->funcp()->entryPoint()) {
nodep->funcp()->accept(*this); // 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: public:
// CONSTRUCTORS // CONSTRUCTORS
explicit LifePostDlyVisitor(AstNetlist* nodep) { explicit LifePostDlyVisitor(AstNetlist* nodep)
: m_tracingCall(false) {
nodep->accept(*this); nodep->accept(*this);
} }
virtual ~LifePostDlyVisitor() { virtual ~LifePostDlyVisitor() {

View File

@ -53,6 +53,7 @@ private:
V3Double0 m_statInstrLong; // Instruction count V3Double0 m_statInstrLong; // Instruction count
bool m_counting; // Currently counting bool m_counting; // Currently counting
double m_instrs; // Current instr count (for determining branch direction) double m_instrs; // Current instr count (for determining branch direction)
bool m_tracingCall; // Iterating into a CCall to a CFunc
vector<V3Double0> m_statTypeCount; // Nodes of given type vector<V3Double0> m_statTypeCount; // Nodes of given type
V3Double0 m_statAbove[AstType::_ENUM_END][AstType::_ENUM_END]; // 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) { virtual void visit(AstCCall* nodep) {
allNodes(nodep); allNodes(nodep);
nodep->iterateChildrenConst(*this); nodep->iterateChildrenConst(*this);
if (m_fast) { if (m_fast && !nodep->funcp()->entryPoint()) {
// Enter the function and trace it // Enter the function and trace it
nodep->funcp()->accept(*this); m_tracingCall = true;
} nodep->funcp()->accept(*this);
}
} }
virtual void visit(AstCFunc* nodep) { virtual void visit(AstCFunc* nodep) {
if (m_fast) {
if (!m_tracingCall && !nodep->entryPoint()) return;
m_tracingCall = false;
}
m_cfuncp = nodep; m_cfuncp = nodep;
allNodes(nodep); allNodes(nodep);
nodep->iterateChildrenConst(*this); nodep->iterateChildrenConst(*this);
@ -215,6 +221,7 @@ public:
m_cfuncp = NULL; m_cfuncp = NULL;
m_counting = !m_fast; m_counting = !m_fast;
m_instrs = 0; m_instrs = 0;
m_tracingCall = false;
// Initialize arrays // Initialize arrays
m_statTypeCount.resize(AstType::_ENUM_END); m_statTypeCount.resize(AstType::_ENUM_END);
// Process // Process