// METHODS void nodeHashIterate(AstNode* nodep) { if (!nodep->user4()) { if (nodep->backp()->castCFunc() && !(nodep->castNodeStmt() || nodep->castCFunc())) { nodep->v3fatalSrc("Node "<<nodep->prettyTypeName()<<" in statement position but not marked stmt (node under function)"); } V3Hash oldHash = m_lowerHash; { m_lowerHash = nodep->sameHash(); if (m_lowerHash.isIllegal()) { nodep->v3fatalSrc("sameHash function undefined (returns 0) for node under CFunc."); } // For identical nodes, the type should be the same thus dtypep should be the same too m_lowerHash = V3Hash(m_lowerHash, V3Hash(nodep->type()<<6, V3Hash(nodep->dtypep()))); // Now update m_lowerHash for our children's (and next children) contributions nodep->iterateChildren(*this); // Store the hash value nodep->user4(m_lowerHash.fullValue()); //UINFO(9, " hashnode "<<m_lowerHash<<" "<<nodep<<endl); } m_lowerHash = oldHash; } // Update what will become the above node's hash m_lowerHash += V3Hashed::nodeHash(nodep); }
void replaceFuncWFunc(AstCFunc* oldfuncp, AstCFunc* newfuncp) { UINFO(5," DupFunc "<<hex<<V3Hash(newfuncp->user4p())<<" "<<newfuncp<<endl); UINFO(5," and "<<hex<<V3Hash(oldfuncp->user4p())<<" "<<oldfuncp<<endl); // Mark user3p on entire old tree, so we don't process it more ++m_statCombs; CombMarkVisitor visitor(oldfuncp); m_call.replaceFunc(oldfuncp, newfuncp); oldfuncp->unlinkFrBack(); pushDeletep(oldfuncp); VL_DANGLING(oldfuncp); }
void walkEmptyFuncs() { for (V3Hashed::iterator it = m_hashed.begin(); it != m_hashed.end(); ++it) { AstNode* node1p = it->second; AstCFunc* oldfuncp = node1p->castCFunc(); if (oldfuncp && oldfuncp->emptyBody() && !oldfuncp->dontCombine()) { UINFO(5," EmptyFunc "<<hex<<V3Hash(oldfuncp->user4p())<<" "<<oldfuncp<<endl); // Mark user3p on entire old tree, so we don't process it more CombMarkVisitor visitor(oldfuncp); m_call.replaceFunc(oldfuncp, NULL); oldfuncp->unlinkFrBack(); pushDeletep(oldfuncp); VL_DANGLING(oldfuncp); } } }