Beispiel #1
0
    AstNodeAssign* hashAndFindDupe(AstNodeAssign* assignp, AstNode* extra1p, AstNode* extra2p) {
	AstNode *rhsp = assignp->rhsp();
	rhsp->user2p(assignp);
	rhsp->user3p(extra1p);
	rhsp->user5p(extra2p);

	hash(extra1p);
	hash(extra2p);

	V3Hashed::iterator inserted = m_hashed.hashAndInsert(rhsp);
	V3Hashed::iterator dupit = m_hashed.findDuplicate(rhsp, this);
	// Even though rhsp was just inserted, V3Hashed::findDuplicate doesn't
	// return anything in the hash that has the same pointer (V3Hashed.cpp::findDuplicate)
	// So dupit is either a different, duplicate rhsp, or the end of the hash.
	if (dupit != m_hashed.end()) {
	    m_hashed.erase(inserted);
	    return m_hashed.iteratorNodep(dupit)->user2p()->castNode()->castNodeAssign();
	}
	return NULL;
    }
    void detectDuplicates() {
	UINFO(9,"Finding duplicates\n");
	// Note uses user4
	V3Hashed  hashed;	// Duplicate code detection
	// Hash all of the original signals we toggle cover
	for (ToggleList::iterator it = m_toggleps.begin(); it != m_toggleps.end(); ++it) {
	    AstCoverToggle* nodep = *it;
	    hashed.hashAndInsert(nodep->origp());
	}
	// Find if there are any duplicates
	for (ToggleList::iterator it = m_toggleps.begin(); it != m_toggleps.end(); ++it) {
	    AstCoverToggle* nodep = *it;
	    if (nodep->backp()) {   // nodep->backp() is null if we already detected it's a duplicate and unlinked it
		// Want to choose a base node, and keep finding duplicates that are identical
		// This prevents making chains where a->b, then c->d, then b->c, as we'll find a->b, a->c, a->d directly.
		while (1) {
		    V3Hashed::iterator dupit = hashed.findDuplicate(nodep->origp());
		    if (dupit == hashed.end()) break;
		    //
		    AstNode* duporigp = hashed.iteratorNodep(dupit);
		    // Note hashed will point to the original variable (what's duplicated), not the covertoggle,
		    // but we need to get back to the covertoggle which is immediately above, so:
		    AstCoverToggle* removep = duporigp->backp()->castCoverToggle();
		    if (!removep) nodep->v3fatalSrc("CoverageJoin duplicate of wrong type");
		    UINFO(8,"  Orig "<<nodep<<" -->> "<<nodep->incp()->declp()<<endl);
		    UINFO(8,"   dup "<<removep<<" -->> "<<removep->incp()->declp()<<endl);
		    // The CoverDecl the duplicate pointed to now needs to point to the original's data
		    // IE the duplicate will get the coverage number from the non-duplicate
		    AstCoverDecl* datadeclp = nodep->incp()->declp()->dataDeclThisp();
		    removep->incp()->declp()->dataDeclp (datadeclp);
		    UINFO(8,"   new "<<removep->incp()->declp()<<endl);
		    // Mark the found node as a duplicate of the first node
		    // (Not vice-versa as we have the iterator for the found node)
		    removep->unlinkFrBack();  pushDeletep(removep); removep=NULL;
		    // Remove node from comparison so don't hit it again
		    hashed.erase(dupit);
		    ++m_statToggleJoins;
		}
	    }
	}
    }