Exemplo n.º 1
0
    // 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);
    }
Exemplo n.º 2
0
    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);
	}
    }