diff --git a/src/V3Expand.cpp b/src/V3Expand.cpp index f1c8d9a09..fc14bb971 100644 --- a/src/V3Expand.cpp +++ b/src/V3Expand.cpp @@ -47,6 +47,8 @@ class ExpandVisitor : public AstNVisitor { private: // NODE STATE + // AstNode::user1() -> bool. Processed + AstUser1InUse m_inuser1; // STATE AstNode* m_stmtp; // Current statement @@ -76,12 +78,14 @@ private: } void insertBefore (AstNode* placep, AstNode* newp) { + newp->user1(1); // Already processed, don't need to re-iterate AstNRelinker linker; placep->unlinkFrBack(&linker); newp->addNext(placep); linker.relink(newp); } void replaceWithDelete (AstNode* nodep, AstNode* newp) { + newp->user1(1); // Already processed, don't need to re-iterate nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; } @@ -306,6 +310,7 @@ private: // VISITORS virtual void visit(AstExtend* nodep, AstNUser*) { + if (nodep->user1Inc()) return; // Process once nodep->iterateChildren(*this); if (nodep->isWide()) { // See under ASSIGN(EXTEND) @@ -344,6 +349,7 @@ private: } virtual void visit(AstSel* nodep, AstNUser*) { + if (nodep->user1Inc()) return; // Process once nodep->iterateChildren(*this); // Remember, Sel's may have non-integer rhs, so need to optimize for that! if (nodep->widthMin()!=(int)nodep->widthConst()) nodep->v3fatalSrc("Width mismatch"); @@ -640,6 +646,7 @@ private: } virtual void visit(AstConcat* nodep, AstNUser*) { + if (nodep->user1Inc()) return; // Process once nodep->iterateChildren(*this); if (nodep->isWide()) { // See under ASSIGN(WIDE) @@ -679,6 +686,7 @@ private: } virtual void visit(AstReplicate* nodep, AstNUser*) { + if (nodep->user1Inc()) return; // Process once nodep->iterateChildren(*this); if (nodep->isWide()) { // See under ASSIGN(WIDE) @@ -740,6 +748,7 @@ private: } virtual void visit(AstChangeXor* nodep, AstNUser*) { + if (nodep->user1Inc()) return; // Process once nodep->iterateChildren(*this); UINFO(8," Wordize ChangeXor "< (0=={or{for each_word{WORDSEL(lhs,#)^WORDSEL(rhs,#)}}} @@ -754,6 +763,7 @@ private: } void visitEqNeq(AstNodeBiop* nodep) { + if (nodep->user1Inc()) return; // Process once nodep->iterateChildren(*this); if (nodep->lhsp()->isWide()) { UINFO(8," Wordize EQ/NEQ "<user1Inc()) return; // Process once nodep->iterateChildren(*this); if (nodep->lhsp()->isWide()) { UINFO(8," Wordize REDOR "<user1Inc()) return; // Process once nodep->iterateChildren(*this); if (nodep->lhsp()->isWide()) { UINFO(8," Wordize REDAND "<user1Inc()) return; // Process once nodep->iterateChildren(*this); if (nodep->lhsp()->isWide()) { UINFO(8," Wordize REDXOR "<fileline(), newp, eqp)); } newp = new AstRedXor (nodep->fileline(), newp); + UINFO(8," Wordize REDXORnew "<user1Inc()) return; // Process once m_stmtp = nodep; nodep->iterateChildren(*this); m_stmtp = NULL; } virtual void visit(AstNodeAssign* nodep, AstNUser*) { + if (nodep->user1Inc()) return; // Process once m_stmtp = nodep; nodep->iterateChildren(*this); bool did = false;