mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 10:03:44 +02:00
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:
+21
-25
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user