Split V3Hashed to V3Hasher and V3DupFinder (#2967)

V3Hasher is responsible for computing AstNode hashes, while V3DupFinder
can be used to find duplicate trees based on hashes. Interface of
V3DupFinder simplified somewhat. No functional change intended at this
point, but hash computation might differ in minor details, this however
should have no perceivable effect on output/runtime.

Implements (#2964)
This commit is contained in:
Geza Lore
2021-05-21 01:41:46 +01:00
committed by GitHub
parent a44d2b2570
commit fd35492226
17 changed files with 389 additions and 382 deletions
+21 -25
View File
@@ -30,7 +30,7 @@
#include "V3Graph.h"
#include "V3Const.h"
#include "V3Stats.h"
#include "V3Hashed.h"
#include "V3DupFinder.h"
#include <algorithm>
#include <list>
@@ -900,7 +900,7 @@ void GateVisitor::optimizeElimVar(AstVarScope* varscp, AstNode* substp, AstNode*
//######################################################################
// Auxiliary hash class for GateDedupeVarVisitor
class GateDedupeHash final : public V3HashedUserSame {
class GateDedupeHash final : public V3DupFinderUserSame {
private:
// NODE STATE
// Ast*::user2p -> parent AstNodeAssign* for this rhsp
@@ -911,22 +911,22 @@ private:
// AstUser1InUse m_inuser1; (Allocated for use in GateVisitor)
// AstUser2InUse m_inuser2; (Allocated for use in GateVisitor)
AstUser3InUse m_inuser3;
// AstUser4InUse m_inuser4; (Allocated for use in V3Hashed)
// AstUser4InUse m_inuser4; (Allocated for use in V3Hasher via V3DupFinder)
AstUser5InUse m_inuser5;
V3Hashed m_hashed; // Hash, contains rhs of assigns
V3DupFinder m_dupFinder; // Duplicate finder for rhs of assigns
std::unordered_set<AstNode*> m_nodeDeleteds; // Any node in this hash was deleted
VL_DEBUG_FUNC; // Declare debug()
void hash(AstNode* nodep) {
// !nullptr && the object is hashable
if (nodep && !nodep->sameHash().isIllegal()) m_hashed.hash(nodep);
}
bool sameHash(AstNode* node1p, AstNode* node2p) {
return (node1p && node2p && !node1p->sameHash().isIllegal()
&& !node2p->sameHash().isIllegal() && m_hashed.sameNodes(node1p, node2p));
return node1p //
&& node2p //
&& !node1p->sameHash().isIllegal() //
&& !node2p->sameHash().isIllegal() //
&& m_dupFinder.sameNodes(node1p, node2p);
}
bool same(AstNode* node1p, AstNode* node2p) {
return node1p == node2p || sameHash(node1p, node2p);
}
@@ -958,7 +958,7 @@ public:
|| (extra2p && m_nodeDeleteds.find(extra2p) != m_nodeDeleteds.end()));
}
// Callback from V3Hashed::findDuplicate
// Callback from V3DupFinder::findDuplicate
virtual bool isSame(AstNode* node1p, AstNode* node2p) override {
// Assignment may have been hashReplaced, if so consider non-match (effectively removed)
if (isReplaced(node1p) || isReplaced(node2p)) {
@@ -977,25 +977,21 @@ public:
rhsp->user3p(extra1p);
rhsp->user5p(extra2p);
hash(extra1p);
hash(extra2p);
const auto inserted = m_hashed.hashAndInsert(rhsp);
const auto 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)
const auto inserted = m_dupFinder.insert(rhsp);
const auto dupit = m_dupFinder.findDuplicate(rhsp, this);
// Even though rhsp was just inserted, V3DupFinder::findDuplicate doesn't
// return anything in the hash that has the same pointer (V3DupFinder::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 VN_CAST(m_hashed.iteratorNodep(dupit)->user2p(), NodeAssign);
if (dupit != m_dupFinder.end()) {
m_dupFinder.erase(inserted);
return VN_CAST(dupit->second->user2p(), NodeAssign);
}
// Retain new inserted information
return nullptr;
}
void check() {
m_hashed.check();
for (const auto& itr : m_hashed) {
for (const auto& itr : m_dupFinder) {
AstNode* nodep = itr.second;
AstNode* activep = nodep->user3p();
AstNode* condVarp = nodep->user5p();
@@ -1003,9 +999,9 @@ public:
// This class won't break if activep isn't an active, or
// ifVar isn't a var, but this is checking the caller's construction.
UASSERT_OBJ(!activep || (!VN_DELETED(activep) && VN_IS(activep, Active)), nodep,
"V3Hashed check failed, lost active pointer");
"V3DupFinder check failed, lost active pointer");
UASSERT_OBJ(!condVarp || !VN_DELETED(condVarp), nodep,
"V3Hashed check failed, lost if pointer");
"V3DupFinder check failed, lost if pointer");
}
}
}