// 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 walkDupFuncs() { for (V3Hashed::iterator it = m_hashed.begin(); it != m_hashed.end(); ++it) { V3Hash hashval = it->first; AstNode* node1p = it->second; if (!node1p->castCFunc()) continue; if (hashval.isIllegal()) node1p->v3fatalSrc("Illegal (unhashed) nodes\n"); for (V3Hashed::iterator eqit = it; eqit != m_hashed.end(); ++eqit) { AstNode* node2p = eqit->second; if (!(eqit->first == hashval)) break; if (node1p==node2p) continue; // Identical iterator if (node1p->user3p() || node2p->user3p()) continue; // Already merged if (node1p->sameTree(node2p)) { // walk of tree has same comparison // Replace AstCCall's that point here replaceFuncWFunc(node2p->castCFunc(), node1p->castCFunc()); // Replacement may promote a slow routine to fast path if (!node2p->castCFunc()->slow()) node1p->castCFunc()->slow(false); } } } }
string paramValueNumber(AstNode* nodep) { // Given a compilcated object create a number to use for param module assignment // Ideally would be relatively stable if design changes (not use pointer value), // and must return same value given same input node // Return must presently be numberic so doesn't collide with 'small' alphanumeric parameter names ValueMap::iterator it = m_valueMap.find(nodep); if (it != m_valueMap.end()) { return cvtToStr(it->second); } else { static int BUCKETS = 1000; V3Hash hash (nodep->name()); int bucket = hash.hshval() % BUCKETS; int offset = 0; NextValueMap::iterator it = m_nextValueMap.find(bucket); if (it != m_nextValueMap.end()) { offset = it->second; it->second = offset + 1; } else { m_nextValueMap.insert(make_pair(bucket, offset + 1)); } int num = bucket + offset * BUCKETS; m_valueMap.insert(make_pair(nodep, num)); return cvtToStr(num); } }