diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 4bac79500..83fa35783 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -720,7 +720,11 @@ void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) { // IMPORTANT: If you replace a node that's the target of this iterator, // then the NEW node will be iterated on next, it isn't skipped! // if (!this) return; // Part of for() - for (AstNode* nodep=this; nodep;) { + // Future versions of this function may require the node to have a back to be iterated; + // there's no lower level reason yet though the back must exist. + AstNode* nodep=this; + if (VL_UNLIKELY(nodep && !nodep->m_backp)) nodep->v3fatalSrc("iterateAndNext node has no back"); + while (nodep) { AstNode* niterp = nodep; ASTNODE_PREFETCH(nodep->m_nextp); niterp->m_iterpp = &niterp; @@ -728,7 +732,7 @@ void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) { // accept may do a replaceNode and change niterp on us... if (!niterp) return; niterp->m_iterpp = NULL; - if (niterp!=nodep) { // Edited it + if (VL_UNLIKELY(niterp!=nodep)) { // Edited it nodep = niterp; } else { // Same node, just loop nodep = niterp->m_nextp; diff --git a/src/V3Inline.cpp b/src/V3Inline.cpp index 5d9d1cd39..2ace0c05e 100644 --- a/src/V3Inline.cpp +++ b/src/V3Inline.cpp @@ -146,7 +146,7 @@ private: } // Cleanup var names, etc, to not conflict m_cellp = nodep; - newmodp->iterateAndNext(*this); + newmodp->iterate(*this); // Not iterateAndNext because newmodp isn't linked; no back m_cellp = NULL; // Move statements to top module if (debug()>=9) { newmodp->dumpTree(cout,"fixmod:"); } diff --git a/src/V3Task.cpp b/src/V3Task.cpp index e4a8d3e24..7cb90bfeb 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -243,7 +243,7 @@ public: AstNode::user3ClearTree(); AstNode::user4ClearTree(); // - nodep->iterateAndNext(*this, NULL); + nodep->accept(*this); // m_callGraph.removeRedundantEdgesSum(&TaskEdge::followAlwaysTrue); m_callGraph.dumpDotFilePrefixed("task_call"); @@ -280,8 +280,8 @@ private: } public: // CONSTUCTORS - TaskRelinkVisitor(AstNode* nodep) { - nodep->iterateAndNext(*this, NULL); + TaskRelinkVisitor(AstBegin* nodep) { // Passed temporary tree + nodep->accept(*this); } virtual ~TaskRelinkVisitor() {} }; @@ -430,7 +430,12 @@ private: refp->taskp()->castFunc()->fvarp()->user2p(outvscp); } // Replace variable refs - TaskRelinkVisitor visit (beginp); + // Iteration requires a back, so put under temporary node + { + AstBegin* tempp = new AstBegin(beginp->fileline(),"[EditWrapper]",beginp); + TaskRelinkVisitor visit (tempp); + tempp->stmtsp()->unlinkFrBackWithNext(); tempp->deleteTree(); tempp=NULL; + } // if (debug()>=9) { beginp->dumpTree(cout,"-iotask: "); } return beginp; @@ -582,7 +587,12 @@ private: new AstVarRef(rtnvscp->fileline(), rtnvscp, false))); } // Replace variable refs - TaskRelinkVisitor visit (cfuncp); + // Iteration requires a back, so put under temporary node + { + AstBegin* tempp = new AstBegin(cfuncp->fileline(),"[EditWrapper]",cfuncp); + TaskRelinkVisitor visit (tempp); + tempp->stmtsp()->unlinkFrBackWithNext(); tempp->deleteTree(); tempp=NULL; + } // Delete rest of cloned task and return new func pushDeletep(nodep); nodep=NULL; if (debug()>=9 && forUser) { cfuncp->dumpTree(cout,"-userFunc: "); } diff --git a/src/V3Unroll.cpp b/src/V3Unroll.cpp index 59f5795ce..345dabda3 100644 --- a/src/V3Unroll.cpp +++ b/src/V3Unroll.cpp @@ -257,9 +257,14 @@ private: m_varValuep = new AstConst(nodep->fileline(), loopValue); - m_varModeReplace = true; - oneloopp->iterateAndNext(*this); - m_varModeReplace = false; + // Iteration requires a back, so put under temporary node + if (oneloopp) { + AstBegin* tempp = new AstBegin(oneloopp->fileline(),"[EditWrapper]",oneloopp); + m_varModeReplace = true; + tempp->stmtsp()->iterateAndNext(*this); + m_varModeReplace = false; + tempp->stmtsp()->unlinkFrBackWithNext(); tempp->deleteTree(); tempp=NULL; + } if (newbodysp) newbodysp->addNext(oneloopp); else newbodysp = oneloopp; diff --git a/src/V3Width.cpp b/src/V3Width.cpp index ea838b614..374a83f39 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1169,8 +1169,8 @@ private: } public: // CONSTUCTORS - WidthCommitVisitor(AstNode* nodep) { - nodep->iterateAndNext(*this, NULL); + WidthCommitVisitor(AstNetlist* nodep) { + nodep->accept(*this); } virtual ~WidthCommitVisitor() {} };