Internals: iterateAndNext now requires backp to exist, for forward compatibility

This commit is contained in:
Wilson Snyder 2009-10-04 17:01:35 -04:00
parent 4f2dc0ecff
commit 546e7c0c1f
5 changed files with 32 additions and 13 deletions

View File

@ -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;

View File

@ -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:"); }

View File

@ -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: "); }

View File

@ -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;

View File

@ -1169,8 +1169,8 @@ private:
}
public:
// CONSTUCTORS
WidthCommitVisitor(AstNode* nodep) {
nodep->iterateAndNext(*this, NULL);
WidthCommitVisitor(AstNetlist* nodep) {
nodep->accept(*this);
}
virtual ~WidthCommitVisitor() {}
};