diff --git a/src/Makefile_obj.in b/src/Makefile_obj.in index 861383a57..e431515ba 100644 --- a/src/Makefile_obj.in +++ b/src/Makefile_obj.in @@ -203,6 +203,7 @@ RAW_OBJS = \ V3GraphDfa.o \ V3GraphPathChecker.o \ V3GraphTest.o \ + V3Hash.o \ V3Hasher.o \ V3HierBlock.o \ V3Inline.o \ diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 7be1e7a4d..4329c7633 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -970,20 +970,6 @@ bool AstNode::sameTreeIter(const AstNode* node1p, const AstNode* node2p, bool ig && (ignNext || sameTreeIter(node1p->m_nextp, node2p->m_nextp, false, gateOnly))); } -//====================================================================== -// Static utilities - -std::ostream& operator<<(std::ostream& os, const V3Hash& rhs) { - return os << std::hex << std::setw(2) << std::setfill('0') << rhs.depth() << "_" - << std::setw(6) << std::setfill('0') << rhs.hshval(); -} - -V3Hash::V3Hash(const string& name) { - uint32_t val = 0; - for (const auto& c : name) val = val * 31 + c; - setBoth(1, val); -} - //====================================================================== // Debugging diff --git a/src/V3Ast.h b/src/V3Ast.h index 306f75b95..827b9649a 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -1271,6 +1271,8 @@ public: virtual ~AstNVisitor() { doDeletes(); } /// Call visit()s on nodep void iterate(AstNode* nodep); + /// Call visit()s on nodep + void iterateNull(AstNode* nodep); /// Call visit()s on nodep's children void iterateChildren(AstNode* nodep); /// Call visit()s on nodep's children in backp() order @@ -1321,56 +1323,6 @@ inline std::ostream& operator<<(std::ostream& os, const AstNRelinker& rhs) { return os; } -//###################################################################### -// V3Hash -- Node hashing for V3Combine - -class V3Hash final { - // A hash of a tree of nodes, consisting of 8 bits with the number of nodes in the hash - // and 24 bit value hash of relevant information about the node. - // A value of 0 is illegal - uint32_t m_both; - static const uint32_t M24 = ((1 << 24) - 1); - void setBoth(uint32_t depth, uint32_t hshval) { - if (depth == 0) depth = 1; - if (depth > 255) depth = 255; - m_both = (depth << 24) | (hshval & M24); - } - -public: - // METHODS - bool isIllegal() const { return m_both == 0; } - uint32_t fullValue() const { return m_both; } - uint32_t depth() const { return (m_both >> 24) & 255; } - uint32_t hshval() const { return m_both & M24; } - // OPERATORS - bool operator==(const V3Hash& rh) const { return m_both == rh.m_both; } - bool operator!=(const V3Hash& rh) const { return m_both != rh.m_both; } - bool operator<(const V3Hash& rh) const { return m_both < rh.m_both; } - // CONSTRUCTORS - class Illegal {}; // for creator type-overload selection - class FullValue {}; // for creator type-overload selection - explicit V3Hash(Illegal) { m_both = 0; } - // Saving and restoring inside a userp - explicit V3Hash(const VNUser& u) { m_both = u.toInt(); } - V3Hash operator+=(const V3Hash& rh) { - setBoth(depth() + rh.depth(), (hshval() * 31 + rh.hshval())); - return *this; - } - // Creating from raw data (sameHash functions) - V3Hash() { setBoth(1, 0); } - explicit V3Hash(uint32_t val) { setBoth(1, val); } - explicit V3Hash(const void* vp) { setBoth(1, cvtToHash(vp)); } - explicit V3Hash(const string& name); - V3Hash(V3Hash h1, V3Hash h2) { setBoth(1, h1.hshval() * 31 + h2.hshval()); } - V3Hash(V3Hash h1, V3Hash h2, V3Hash h3) { - setBoth(1, (h1.hshval() * 31 + h2.hshval()) * 31 + h3.hshval()); - } - V3Hash(V3Hash h1, V3Hash h2, V3Hash h3, V3Hash h4) { - setBoth(1, ((h1.hshval() * 31 + h2.hshval()) * 31 + h3.hshval()) * 31 + h4.hshval()); - } -}; -std::ostream& operator<<(std::ostream& os, const V3Hash& rhs); - //###################################################################### // Callback base class to determine if node matches some formula @@ -1832,9 +1784,6 @@ public: // statement is unlikely to be taken virtual bool isUnlikely() const { return false; } virtual int instrCount() const { return 0; } - virtual V3Hash sameHash() const { - return V3Hash(V3Hash::Illegal()); // Not a node that supports it - } virtual bool same(const AstNode*) const { return true; } // Iff has a data type; dtype() must be non null virtual bool hasDType() const { return false; } @@ -1968,7 +1917,6 @@ public: virtual bool signedFlavor() const { return false; } virtual bool stringFlavor() const { return false; } // N flavor of nodes with both flavors? virtual int instrCount() const override { return widthInstrs(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode*) const override { return true; } }; @@ -2002,7 +1950,6 @@ public: virtual bool signedFlavor() const { return false; } virtual bool stringFlavor() const { return false; } // N flavor of nodes with both flavors? virtual int instrCount() const override { return widthInstrs(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode*) const override { return true; } }; @@ -2037,7 +1984,6 @@ public: virtual bool sizeMattersRhs() const = 0; // True if output result depends on rhs size virtual bool sizeMattersThs() const = 0; // True if output result depends on ths size virtual int instrCount() const override { return widthInstrs(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode*) const override { return true; } }; @@ -2076,7 +2022,6 @@ public: virtual bool sizeMattersThs() const = 0; // True if output result depends on ths size virtual bool sizeMattersFhs() const = 0; // True if output result depends on ths size virtual int instrCount() const override { return widthInstrs(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode*) const override { return true; } }; @@ -2180,7 +2125,6 @@ public: void thsp(AstNode* nodep) { return setOp3p(nodep); } void attrp(AstAttrOf* nodep) { return setOp4p((AstNode*)nodep); } // METHODS - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode*) const override { return true; } }; @@ -2242,7 +2186,6 @@ public: virtual bool hasDType() const override { return true; } virtual bool cleanRhs() const { return true; } virtual int instrCount() const override { return widthInstrs(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode*) const override { return true; } virtual string verilogKwd() const override { return "="; } virtual bool brokeLhsMustBeLvalue() const = 0; @@ -2267,7 +2210,6 @@ public: AstNode* bodysp() const { return op4p(); } // op4 = body of loop virtual bool isGateOptimizable() const override { return false; } virtual int instrCount() const override { return instrCountBranch(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -2293,7 +2235,6 @@ public: virtual bool isGateOptimizable() const override { return false; } virtual bool isGateDedupable() const override { return true; } virtual int instrCount() const override { return instrCountBranch(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } void branchPred(VBranchPred flag) { m_branchPred = flag; } VBranchPred branchPred() const { return m_branchPred; } @@ -2390,7 +2331,6 @@ protected: public: ASTNODE_BASE_FUNCS(NodeText) virtual void dump(std::ostream& str = std::cout) const override; - virtual V3Hash sameHash() const override { return V3Hash(text()); } virtual bool same(const AstNode* samep) const override { const AstNodeText* asamep = static_cast(samep); return text() == asamep->text(); @@ -2511,10 +2451,12 @@ private: bool m_packed; bool m_isFourstate; MemberNameMap m_members; + const int m_uniqueNum; protected: AstNodeUOrStructDType(AstType t, FileLine* fl, VSigning numericUnpack) - : AstNodeDType{t, fl} { + : AstNodeDType{t, fl} + , m_uniqueNum{uniqueNumInc()} { // VSigning::NOSIGN overloaded to indicate not packed m_packed = (numericUnpack != VSigning::NOSIGN); m_isFourstate = false; // V3Width computes @@ -2523,6 +2465,7 @@ protected: public: ASTNODE_BASE_FUNCS(NodeUOrStructDType) + int uniqueNum() const { return m_uniqueNum; } virtual const char* broken() const override; virtual void dump(std::ostream& str) const override; virtual bool isCompound() const override { return false; } // Because don't support unpacked @@ -2601,9 +2544,6 @@ public: && rangenp()->sameTree(asamep->rangenp()) && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp())); } - virtual V3Hash sameHash() const override { - return V3Hash(V3Hash(m_refDTypep), V3Hash(hi()), V3Hash(lo())); - } virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } @@ -2688,7 +2628,6 @@ public: virtual void cloneRelink() override; virtual const char* broken() const override; virtual int instrCount() const override { return instrCountCall(); } - virtual V3Hash sameHash() const override { return V3Hash(funcp()); } virtual bool same(const AstNode* samep) const override { const AstNodeCCall* asamep = static_cast(samep); return (funcp() == asamep->funcp() && argTypes() == asamep->argTypes()); @@ -2983,6 +2922,9 @@ public: // Inline AstNVisitor METHODS inline void AstNVisitor::iterate(AstNode* nodep) { nodep->accept(*this); } +inline void AstNVisitor::iterateNull(AstNode* nodep) { + if (VL_LIKELY(nodep)) nodep->accept(*this); +} inline void AstNVisitor::iterateChildren(AstNode* nodep) { nodep->iterateChildren(*this); } inline void AstNVisitor::iterateChildrenBackwards(AstNode* nodep) { nodep->iterateChildrenBackwards(*this); diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index b8a2621a5..d88e700fe 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -170,7 +170,6 @@ public: virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); } virtual string emitC() override { V3ERROR_NA_RETURN(""); } virtual bool cleanOut() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(num().toHash()); } virtual bool same(const AstNode* samep) const override { const AstConst* sp = static_cast(samep); return num().isCaseEq(sp->num()); @@ -226,7 +225,6 @@ public: bool littleEndian() const { return leftConst() < rightConst(); } virtual void dump(std::ostream& str) const override; virtual string emitC() { V3ERROR_NA_RETURN(""); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -241,7 +239,6 @@ public: ASTNODE_NODE_FUNCS(BracketRange) virtual string emitC() { V3ERROR_NA_RETURN(""); } virtual string emitVerilog() { V3ERROR_NA_RETURN(""); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } // Will be removed in V3Width, which relies on this // being a child not a dtype pointed node @@ -257,7 +254,6 @@ public: ASTNODE_NODE_FUNCS(UnsizedRange) virtual string emitC() { V3ERROR_NA_RETURN(""); } virtual string emitVerilog() { return "[]"; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -473,27 +469,27 @@ private: string m_name; void* m_containerp; // In what scope is the name unique, so we can know what are duplicate // definitions (arbitrary value) - int m_uniqueNum; + const int m_uniqueNum; public: AstDefImplicitDType(FileLine* fl, const string& name, void* containerp, VFlagChildDType, AstNodeDType* dtp) : ASTGEN_SUPER(fl) , m_name{name} - , m_containerp{containerp} { + , m_containerp{containerp} + , m_uniqueNum{uniqueNumInc()} { childDTypep(dtp); // Only for parser dtypep(nullptr); // V3Width will resolve - m_uniqueNum = uniqueNumInc(); } ASTNODE_NODE_FUNCS(DefImplicitDType) + int uniqueNum() const { return m_uniqueNum; } virtual bool same(const AstNode* samep) const override { const AstDefImplicitDType* sp = static_cast(samep); - return m_uniqueNum == sp->m_uniqueNum; + return uniqueNum() == sp->uniqueNum(); } virtual bool similarDType(AstNodeDType* samep) const override { return type() == samep->type() && same(samep); } - virtual V3Hash sameHash() const override { return V3Hash(m_uniqueNum); } virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); } // op1 = Range of variable AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } @@ -557,7 +553,6 @@ public: } virtual string prettyDTypeName() const override; virtual void dumpSmall(std::ostream& str) const override; - virtual V3Hash sameHash() const override { return V3Hash(m_refDTypep); } virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); } virtual AstNodeDType* getChild2DTypep() const override { return keyChildDTypep(); } virtual bool isHeavy() const override { return true; } @@ -657,7 +652,6 @@ public: } virtual string prettyDTypeName() const override; virtual void dumpSmall(std::ostream& str) const override; - virtual V3Hash sameHash() const override { return V3Hash(m_refDTypep); } virtual bool isHeavy() const override { return true; } virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); } // op1 = Range of variable @@ -775,7 +769,6 @@ public: && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()); } virtual void dumpSmall(std::ostream& str) const override; - virtual V3Hash sameHash() const override { return V3Hash(m_refDTypep); } virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); } // op1 = Range of variable AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } @@ -873,9 +866,6 @@ private: public: ASTNODE_NODE_FUNCS(BasicDType) virtual void dump(std::ostream& str) const override; - virtual V3Hash sameHash() const override { - return V3Hash(V3Hash(m.m_keyword), V3Hash(m.m_nrange.hi())); - } // width/widthMin/numeric compared elsewhere virtual bool same(const AstNode* samep) const override { const AstBasicDType* sp = static_cast(samep); @@ -983,9 +973,6 @@ public: virtual bool similarDType(AstNodeDType* samep) const override { return skipRefp()->similarDType(samep->skipRefp()); } - virtual V3Hash sameHash() const override { - return V3Hash(m_refDTypep); - } // node's type() included elsewhere virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); } // op1 = Range of variable AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } @@ -1038,9 +1025,6 @@ public: virtual bool similarDType(AstNodeDType* samep) const override { return this == samep || (type() == samep->type() && same(samep)); } - virtual V3Hash sameHash() const override { - return V3Hash(V3Hash(m_classp), V3Hash(m_classOrPackagep)); - } virtual void dump(std::ostream& str = std::cout) const override; virtual void dumpSmall(std::ostream& str) const override; virtual string name() const override { return classp() ? classp()->name() : ""; } @@ -1096,7 +1080,6 @@ public: virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } virtual bool similarDType(AstNodeDType* samep) const override { return this == samep; } - virtual V3Hash sameHash() const override { return V3Hash(m_cellp); } virtual int widthAlignBytes() const override { return 1; } virtual int widthTotalBytes() const override { return 1; } FileLine* modportFileline() const { return m_modportFileline; } @@ -1156,7 +1139,6 @@ public: && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()); } virtual void dumpSmall(std::ostream& str) const override; - virtual V3Hash sameHash() const override { return V3Hash(m_refDTypep); } virtual string prettyDTypeName() const override; virtual bool isHeavy() const override { return true; } virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); } @@ -1231,9 +1213,6 @@ public: virtual bool similarDType(AstNodeDType* samep) const override { return skipRefp()->similarDType(samep->skipRefp()); } - virtual V3Hash sameHash() const override { - return V3Hash(V3Hash(m_typedefp), V3Hash(m_classOrPackagep)); - } virtual void dump(std::ostream& str = std::cout) const override; virtual string name() const override { return m_name; } virtual string prettyDTypeName() const override { @@ -1403,7 +1382,6 @@ public: virtual AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } virtual int widthAlignBytes() const override { return 1; } virtual int widthTotalBytes() const override { return 1; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool isCompound() const override { return false; } }; @@ -1470,17 +1448,17 @@ class AstEnumDType final : public AstNodeDType { private: string m_name; // Name from upper typedef, if any AstNodeDType* m_refDTypep; // Elements are of this type after V3Width - int m_uniqueNum; + const int m_uniqueNum; public: AstEnumDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* itemsp) - : ASTGEN_SUPER(fl) { + : ASTGEN_SUPER(fl) + , m_uniqueNum{uniqueNumInc()} { childDTypep(dtp); // Only for parser refDTypep(nullptr); addNOp2p(itemsp); dtypep(nullptr); // V3Width will resolve widthFromSub(subDTypep()); - m_uniqueNum = uniqueNumInc(); } ASTNODE_NODE_FUNCS(EnumDType) virtual const char* broken() const override { @@ -1491,12 +1469,12 @@ public: virtual void cloneRelink() override { if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep(); } + int uniqueNum() const { return m_uniqueNum; } virtual bool same(const AstNode* samep) const override { const AstEnumDType* sp = static_cast(samep); - return m_uniqueNum == sp->m_uniqueNum; + return uniqueNum() == sp->uniqueNum(); } virtual bool similarDType(AstNodeDType* samep) const override { return this == samep; } - virtual V3Hash sameHash() const override { return V3Hash(m_uniqueNum); } virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Data type void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } @@ -1594,7 +1572,6 @@ public: return true; } // esp for V3Const::ifSameAssign virtual bool isPredictOptimizable() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } virtual int instrCount() const override { return widthInstrs(); } // Special operators @@ -1636,7 +1613,6 @@ public: return true; } // esp for V3Const::ifSameAssign virtual bool isPredictOptimizable() const override { return false; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } virtual int instrCount() const override { return widthInstrs(); } }; @@ -1664,7 +1640,6 @@ public: virtual bool cleanRhs() const override { return true; } virtual bool sizeMattersLhs() const override { return false; } virtual bool sizeMattersRhs() const override { return false; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -1678,7 +1653,6 @@ public: addNOp2p(elementsp); } ASTNODE_NODE_FUNCS(SelLoopVars) - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } virtual bool maybePointedTo() const override { return false; } AstNode* fromp() const { return op1p(); } @@ -1770,7 +1744,6 @@ public: virtual bool sizeMattersLhs() const override { return false; } virtual bool sizeMattersRhs() const override { return false; } virtual bool sizeMattersThs() const override { return false; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode*) const override { return true; } virtual int instrCount() const override { return widthInstrs() * (VN_CAST(lsbp(), Const) ? 3 : 10); @@ -1816,7 +1789,6 @@ public: virtual bool sizeMattersLhs() const override { return false; } virtual bool sizeMattersRhs() const override { return false; } virtual bool sizeMattersThs() const override { return false; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode*) const override { return true; } virtual int instrCount() const override { return 10; } // Removed before matters AstNode* fromp() const { @@ -1888,7 +1860,6 @@ public: virtual string name() const override { return m_name; } // * = Var name virtual bool hasDType() const override { return true; } virtual void name(const string& name) override { m_name = name; } - virtual V3Hash sameHash() const override { return V3Hash(m_name); } virtual bool same(const AstNode* samep) const override { const AstCMethodHard* asamep = static_cast(samep); return (m_name == asamep->m_name); @@ -2273,7 +2244,6 @@ public: } virtual string name() const override { return m_name; } // * = Scope name ASTNODE_NODE_FUNCS(DefParam) - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode*) const override { return true; } AstNode* rhsp() const { return op1p(); } // op1 = Assign from string path() const { return m_path; } @@ -2410,9 +2380,6 @@ public: } ASTNODE_NODE_FUNCS(VarRef) virtual void dump(std::ostream& str) const override; - virtual V3Hash sameHash() const override { - return V3Hash(V3Hash(varp()->name()), V3Hash(hiernameToProt())); - } virtual bool same(const AstNode* samep) const override { return same(static_cast(samep)); } @@ -2469,7 +2436,6 @@ public: virtual string emitC() override { V3ERROR_NA_RETURN(""); } virtual bool cleanOut() const override { return true; } virtual int instrCount() const override { return widthInstrs(); } - virtual V3Hash sameHash() const override { return V3Hash(V3Hash(varp()), V3Hash(dotted())); } virtual bool same(const AstNode* samep) const override { const AstVarXRef* asamep = static_cast(samep); return (hiernameToProt() == asamep->hiernameToProt() @@ -2545,7 +2511,6 @@ public: ASTNODE_NODE_FUNCS(Arg) virtual string name() const override { return m_name; } // * = Pin name, ""=go by number virtual void name(const string& name) override { m_name = name; } - virtual V3Hash sameHash() const override { return V3Hash(); } void exprp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expression connected to pin, nullptr if unconnected AstNode* exprp() const { return op1p(); } @@ -2695,7 +2660,6 @@ public: } virtual void dump(std::ostream& str) const override; virtual string name() const override { return m_name; } - virtual V3Hash sameHash() const override { return V3Hash(m_name); } virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); } virtual string emitC() override { V3ERROR_NA_RETURN(""); } virtual bool cleanOut() const override { return false; } @@ -3005,7 +2969,6 @@ public: ASTNODE_NODE_FUNCS(ParseRef) virtual void dump(std::ostream& str) const override; virtual string name() const override { return m_name; } // * = Var name - virtual V3Hash sameHash() const override { return V3Hash(V3Hash(m_expect), V3Hash(m_name)); } virtual bool same(const AstNode* samep) const override { const AstParseRef* asamep = static_cast(samep); return (expect() == asamep->expect() && m_name == asamep->m_name); @@ -3047,7 +3010,6 @@ public: return (m_classOrPackageNodep == static_cast(samep)->m_classOrPackageNodep); } - virtual V3Hash sameHash() const override { return V3Hash(m_classOrPackageNodep); } virtual void dump(std::ostream& str = std::cout) const override; virtual string name() const override { return m_name; } // * = Var name AstNode* classOrPackageNodep() const { return m_classOrPackageNodep; } @@ -3171,7 +3133,6 @@ public: addNOp2p(exprp); } ASTNODE_NODE_FUNCS(WithParse) - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } // AstNode* funcrefp() const { return op1p(); } @@ -3192,7 +3153,6 @@ public: , m_name{name} , m_index(index) {} ASTNODE_NODE_FUNCS(LambdaArgRef) - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } virtual string emitVerilog() override { return name(); } virtual string emitC() override { V3ERROR_NA_RETURN(""); } @@ -3220,7 +3180,6 @@ public: addNOp3p(exprp); } ASTNODE_NODE_FUNCS(With) - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } virtual bool hasDType() const override { return true; } virtual const char* broken() const override { @@ -3269,7 +3228,6 @@ public: , m_edgeType{VEdgeType::ET_NEVER} {} ASTNODE_NODE_FUNCS(SenItem) virtual void dump(std::ostream& str) const override; - virtual V3Hash sameHash() const override { return V3Hash(edgeType()); } virtual bool same(const AstNode* samep) const override { return edgeType() == static_cast(samep)->edgeType(); } @@ -3306,7 +3264,6 @@ public: ASTNODE_NODE_FUNCS(SenTree) virtual void dump(std::ostream& str) const override; virtual bool maybePointedTo() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(); } bool isMulti() const { return m_multi; } // op1 = Sensitivity list AstSenItem* sensesp() const { return VN_CAST(op1p(), SenItem); } @@ -3379,7 +3336,6 @@ public: addNOp2p(bodysp); } ASTNODE_NODE_FUNCS(AlwaysPublic) - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } // AstSenTree* sensesp() const { return VN_CAST(op1p(), SenTree); } // op1 = Sensitivity list @@ -3525,7 +3481,6 @@ public: virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); } virtual string emitC() override { V3ERROR_NA_RETURN(""); } virtual bool cleanOut() const override { return false; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode*) const override { return true; } }; @@ -3543,7 +3498,6 @@ public: , m_name{name} {} ASTNODE_NODE_FUNCS(Comment) virtual string name() const override { return m_name; } // * = Text - virtual V3Hash sameHash() const override { return V3Hash(); } // Ignore name in comments virtual bool same(const AstNode* samep) const override { return true; } // Ignore name in comments @@ -3623,7 +3577,6 @@ public: const string& hier() const { return m_hier; } void hier(const string& flag) { m_hier = flag; } void comment(const string& flag) { m_text = flag; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { const AstCoverDecl* asamep = static_cast(samep); return (fileline() == asamep->fileline() && linescov() == asamep->linescov() @@ -3657,7 +3610,6 @@ public: } virtual void dump(std::ostream& str) const override; virtual int instrCount() const override { return 1 + 2 * instrCountLd(); } - virtual V3Hash sameHash() const override { return V3Hash(declp()); } virtual bool same(const AstNode* samep) const override { return declp() == static_cast(samep)->declp(); } @@ -3681,7 +3633,6 @@ public: } ASTNODE_NODE_FUNCS(CoverToggle) virtual int instrCount() const override { return 3 + instrCountBranch() + instrCountLd(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } virtual bool isGateOptimizable() const override { return false; } virtual bool isPredictOptimizable() const override { return true; } @@ -3703,7 +3654,6 @@ public: setOp1p(lhsp); } ASTNODE_NODE_FUNCS(Delay) - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } // AstNode* lhsp() const { return op1p(); } // op2 = Statements to evaluate @@ -3820,7 +3770,6 @@ public: ASTNODE_NODE_FUNCS(SFormatF) virtual string name() const override { return m_text; } virtual int instrCount() const override { return instrCountPli(); } - virtual V3Hash sameHash() const override { return V3Hash(text()); } virtual bool hasDType() const override { return true; } virtual bool same(const AstNode* samep) const override { return text() == static_cast(samep)->text(); @@ -3882,7 +3831,6 @@ public: } // SPECIAL: $display has 'visual' ordering virtual bool isOutputter() const override { return true; } // SPECIAL: $display makes output virtual bool isUnlikely() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(displayType()); } virtual bool same(const AstNode* samep) const override { return displayType() == static_cast(samep)->displayType(); } @@ -3915,7 +3863,6 @@ public: virtual bool isPredictOptimizable() const override { return false; } virtual bool isOutputter() const override { return true; } virtual bool cleanOut() const { return true; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } VDumpCtlType ctlType() const { return m_ctlType; } AstNode* exprp() const { return op1p(); } // op2 = Expressions to output @@ -3949,7 +3896,6 @@ public: } // SPECIAL: $display has 'visual' ordering virtual bool isOutputter() const override { return true; } // SPECIAL: $display makes output virtual bool isUnlikely() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(displayType()); } virtual bool same(const AstNode* samep) const override { return displayType() == static_cast(samep)->displayType(); } @@ -3988,7 +3934,6 @@ public: virtual bool isOutputter() const override { return false; } virtual bool cleanOut() const { return false; } virtual int instrCount() const override { return instrCountPli(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter AstSFormatF* fmtp() const { return VN_CAST(op1p(), SFormatF); } @@ -4012,7 +3957,6 @@ public: virtual bool isPure() const override { return true; } virtual bool isOutputter() const override { return false; } virtual int instrCount() const override { return 0; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } AstNode* lhsp() const { return op1p(); } // op1 = Expressions to eval void lhsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to eval @@ -4054,7 +3998,6 @@ public: virtual bool isPure() const override { return false; } virtual bool isOutputter() const override { return true; } virtual bool isUnlikely() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } AstNode* filep() const { return op2p(); } void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); } @@ -4077,7 +4020,6 @@ public: virtual bool isPure() const override { return false; } virtual bool isOutputter() const override { return true; } virtual bool isUnlikely() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } AstNode* filep() const { return op1p(); } AstNode* filenamep() const { return op2p(); } @@ -4100,7 +4042,6 @@ public: virtual bool isPure() const override { return false; } virtual bool isOutputter() const override { return true; } virtual bool isUnlikely() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } AstNode* filep() const { return op1p(); } AstNode* filenamep() const { return op2p(); } @@ -4121,7 +4062,6 @@ public: virtual bool isPure() const override { return false; } virtual bool isOutputter() const override { return true; } virtual bool isUnlikely() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } AstNode* filep() const { return op2p(); } void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); } @@ -4150,7 +4090,6 @@ public: virtual bool isPure() const override { return false; } // SPECIAL: has 'visual' ordering virtual bool isOutputter() const override { return true; } // SPECIAL: makes output virtual bool cleanOut() const override { return false; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } AstNode* memp() const { return op1p(); } void memp(AstNode* nodep) { setOp1p(nodep); } @@ -4180,7 +4119,6 @@ public: virtual bool isOutputter() const override { return true; } virtual bool isUnlikely() const override { return true; } virtual bool cleanOut() const override { return false; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } AstNode* filep() const { return op2p(); } void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); } @@ -4204,7 +4142,6 @@ public: virtual bool isOutputter() const override { return true; } virtual bool isUnlikely() const override { return true; } virtual bool cleanOut() const override { return false; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } AstNode* filep() const { return op2p(); } void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); } @@ -4231,7 +4168,6 @@ public: virtual bool isPure() const override { return false; } // SPECIAL: has 'visual' ordering virtual bool isOutputter() const override { return true; } // SPECIAL: makes output virtual bool cleanOut() const override { return false; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } AstNode* filep() const { return op2p(); } void filep(AstNode* nodep) { setOp2p(nodep); } @@ -4265,7 +4201,6 @@ public: virtual bool isPure() const override { return false; } // SPECIAL: has 'visual' ordering virtual bool isOutputter() const override { return true; } // SPECIAL: makes output virtual bool cleanOut() const override { return false; } - virtual V3Hash sameHash() const override { return V3Hash(text()); } virtual bool same(const AstNode* samep) const override { return text() == static_cast(samep)->text(); } @@ -4301,7 +4236,6 @@ public: virtual bool isPure() const override { return false; } // SPECIAL: has 'visual' ordering virtual bool isOutputter() const override { return true; } // SPECIAL: makes output virtual bool cleanOut() const override { return false; } - virtual V3Hash sameHash() const override { return V3Hash(text()); } virtual bool same(const AstNode* samep) const override { return text() == static_cast(samep)->text(); } @@ -4332,7 +4266,6 @@ public: virtual bool isPure() const override { return false; } virtual bool isOutputter() const override { return true; } virtual bool isUnlikely() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return isHex() == static_cast(samep)->isHex(); } @@ -4380,7 +4313,6 @@ public: virtual bool isPure() const override { return false; } // Though deleted before opt virtual bool isOutputter() const override { return true; } // Though deleted before opt virtual int instrCount() const override { return instrCountPli(); } - virtual V3Hash sameHash() const override { return V3Hash(m_off); } virtual bool same(const AstNode* samep) const override { return m_off == static_cast(samep)->m_off; } @@ -4401,7 +4333,6 @@ public: virtual bool isPure() const override { return false; } virtual bool isOutputter() const override { return true; } virtual bool isUnlikely() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } AstNode* lhsp() const { return op1p(); } }; @@ -4423,7 +4354,6 @@ public: virtual bool isOutputter() const override { return true; } virtual bool isUnlikely() const override { return true; } virtual bool cleanOut() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } AstNode* lhsp() const { return op1p(); } }; @@ -4445,7 +4375,6 @@ public: virtual bool isHeavy() const override { return true; } virtual bool isPredictOptimizable() const override { return false; } virtual bool cleanOut() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } AstNode* searchp() const { return op1p(); } // op1 = Search expression void searchp(AstNode* nodep) { setOp1p(nodep); } @@ -4471,7 +4400,6 @@ public: virtual bool isGateOptimizable() const override { return false; } virtual bool isPredictOptimizable() const override { return false; } virtual bool cleanOut() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(text()); } virtual bool same(const AstNode* samep) const override { return text() == static_cast(samep)->text(); } @@ -4498,7 +4426,6 @@ public: AstNode* bodysp() const { return op4p(); } // op4 = body of loop virtual bool isGateOptimizable() const override { return false; } virtual int instrCount() const override { return instrCountBranch(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -4516,7 +4443,6 @@ public: return false; } // Not relevant - converted to FOR virtual int instrCount() const override { return instrCountBranch(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -4550,7 +4476,6 @@ public: void addIncsp(AstNode* newp) { addOp4p(newp); } virtual bool isGateOptimizable() const override { return false; } virtual int instrCount() const override { return instrCountBranch(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } // Stop statement searchback here virtual void addBeforeStmt(AstNode* newp, AstNode* belowp) override; @@ -4564,7 +4489,6 @@ public: : ASTGEN_SUPER(fl) {} ASTNODE_NODE_FUNCS(Break) virtual string verilogKwd() const override { return "break"; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool isBrancher() const override { return true; // SPECIAL: We don't process code after breaks } @@ -4576,7 +4500,6 @@ public: : ASTGEN_SUPER(fl) {} ASTNODE_NODE_FUNCS(Continue) virtual string verilogKwd() const override { return "continue"; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool isBrancher() const override { return true; // SPECIAL: We don't process code after breaks } @@ -4621,7 +4544,6 @@ public: } ASTNODE_NODE_FUNCS(Return) virtual string verilogKwd() const override { return "return"; } - virtual V3Hash sameHash() const override { return V3Hash(); } AstNode* lhsp() const { return op1p(); } virtual bool isBrancher() const override { return true; // SPECIAL: We don't process code after breaks @@ -4674,7 +4596,6 @@ public: ASTNODE_NODE_FUNCS(JumpBlock) virtual int instrCount() const override { return 0; } virtual bool maybePointedTo() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } // op1 = Statements AstNode* stmtsp() const { return op1p(); } // op1 = List of statements @@ -4709,7 +4630,6 @@ public: } virtual void dump(std::ostream& str) const override; virtual int instrCount() const override { return 0; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return blockp() == static_cast(samep)->blockp(); } @@ -4737,7 +4657,6 @@ public: } virtual void dump(std::ostream& str) const override; virtual int instrCount() const override { return instrCountBranch(); } - virtual V3Hash sameHash() const override { return V3Hash(labelp()); } virtual bool same(const AstNode* samep) const override { return labelp() == static_cast(samep)->labelp(); } @@ -4795,7 +4714,6 @@ public: virtual bool isGateOptimizable() const override { return false; } virtual bool isPredictOptimizable() const override { return false; } virtual int instrCount() const override { return widthInstrs(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -4815,7 +4733,6 @@ public: virtual bool cleanOut() const override { return true; } virtual int instrCount() const override { return widthInstrs(); } AstNode* defaultp() const { return op1p(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; class AstSetAssoc final : public AstNodeMath { @@ -4838,7 +4755,6 @@ public: AstNode* lhsp() const { return op1p(); } AstNode* keyp() const { return op2p(); } AstNode* valuep() const { return op3p(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -4860,7 +4776,6 @@ public: virtual int instrCount() const override { return widthInstrs(); } AstNode* lhsp() const { return op1p(); } // op1 = expression AstNode* rhsp() const { return op2p(); } // op2 = expression - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -4882,7 +4797,6 @@ public: virtual int instrCount() const override { return widthInstrs(); } AstNode* lhsp() const { return op1p(); } // op1 = expression AstNode* rhsp() const { return op2p(); } // op2 = expression - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -4974,7 +4888,6 @@ public: ASTNODE_NODE_FUNCS(InitItem) virtual bool maybePointedTo() const override { return true; } virtual bool hasDType() const override { return false; } // See valuep()'s dtype instead - virtual V3Hash sameHash() const override { return V3Hash(); } AstNode* valuep() const { return op1p(); } // op1 = Value void valuep(AstNode* nodep) { addOp1p(nodep); } }; @@ -5012,7 +4925,6 @@ public: } } virtual bool hasDType() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { // Only works if exact same children, instead should override comparison // of children list, and instead use map-vs-map key/value compare @@ -5061,7 +4973,6 @@ public: AstNew(FileLine* fl, AstNode* pinsp) : ASTGEN_SUPER(fl, false, "new", pinsp) {} ASTNODE_NODE_FUNCS(New) - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool cleanOut() const { return true; } virtual bool same(const AstNode* samep) const override { return true; } virtual bool hasDType() const override { return true; } @@ -5079,7 +4990,6 @@ public: setNOp1p(rhsp); } ASTNODE_NODE_FUNCS(NewCopy) - virtual V3Hash sameHash() const override { return V3Hash(); } virtual string emitVerilog() override { return "new"; } virtual string emitC() override { V3ERROR_NA_RETURN(""); } virtual bool cleanOut() const override { return true; } @@ -5100,7 +5010,6 @@ public: setNOp2p(rhsp); } ASTNODE_NODE_FUNCS(NewDynamic) - virtual V3Hash sameHash() const override { return V3Hash(); } virtual string emitVerilog() override { return "new"; } virtual string emitC() override { V3ERROR_NA_RETURN(""); } virtual bool cleanOut() const override { return true; } @@ -5121,7 +5030,6 @@ public: , m_pragType{pragType} {} ASTNODE_NODE_FUNCS(Pragma) AstPragmaType pragType() const { return m_pragType; } // *=type of the pragma - virtual V3Hash sameHash() const override { return V3Hash(pragType()); } virtual bool isPredictOptimizable() const override { return false; } virtual bool same(const AstNode* samep) const override { return pragType() == static_cast(samep)->pragType(); @@ -5145,7 +5053,6 @@ public: virtual bool isPure() const override { return false; } virtual bool isOutputter() const override { return true; } virtual int instrCount() const override { return instrCountPli(); } - virtual V3Hash sameHash() const override { return V3Hash(); } void timeunit(const VTimescale& flag) { m_timeunit = flag; } VTimescale timeunit() const { return m_timeunit; } }; @@ -5163,7 +5070,6 @@ public: virtual bool isOutputter() const override { return true; } // SPECIAL: $display makes output virtual bool isUnlikely() const override { return true; } virtual int instrCount() const override { return 0; } // Rarely executes - virtual V3Hash sameHash() const override { return V3Hash(fileline()->lineno()); } virtual bool same(const AstNode* samep) const override { return fileline() == samep->fileline(); } @@ -5182,7 +5088,6 @@ public: virtual bool isOutputter() const override { return true; } // SPECIAL: $display makes output virtual bool isUnlikely() const override { return true; } virtual int instrCount() const override { return 0; } // Rarely executes - virtual V3Hash sameHash() const override { return V3Hash(fileline()->lineno()); } virtual bool same(const AstNode* samep) const override { return fileline() == samep->fileline(); } @@ -5205,7 +5110,6 @@ public: virtual bool cleanOut() const override { return true; } virtual bool cleanLhs() const override { return true; } virtual bool sizeMattersLhs() const override { return false; } - virtual V3Hash sameHash() const override { return V3Hash(fileline()->lineno()); } virtual bool same(const AstNode* samep) const override { return fileline() == samep->fileline(); } @@ -5226,7 +5130,6 @@ public: virtual bool isPure() const override { return false; } virtual bool isOutputter() const override { return false; } virtual int instrCount() const override { return 0; } - virtual V3Hash sameHash() const override { return V3Hash(); } AstSenTree* sensesp() const { return VN_CAST(op1p(), SenTree); } AstNode* stmtsp() const { return op2p(); } }; @@ -5249,7 +5152,6 @@ public: virtual bool isPure() const override { return false; } virtual bool isOutputter() const override { return true; } virtual int instrCount() const override { return instrCountPli(); } - virtual V3Hash sameHash() const override { return V3Hash(); } AstNode* unitsp() const { return op1p(); } AstNode* precisionp() const { return op2p(); } AstNode* suffixp() const { return op3p(); } @@ -5338,7 +5240,6 @@ public: virtual void dump(std::ostream& str) const override; virtual int instrCount() const override { return 10 + 2 * instrCountLd(); } virtual bool hasDType() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(declp()); } virtual bool same(const AstNode* samep) const override { return declp() == static_cast(samep)->declp(); } @@ -5413,7 +5314,6 @@ public: AstNode* fromp() const { return op1p(); } AstNode* dimp() const { return op2p(); } AstAttrType attrType() const { return m_attrType; } - virtual V3Hash sameHash() const override { return V3Hash(m_attrType); } virtual void dump(std::ostream& str = std::cout) const override; }; @@ -5432,7 +5332,6 @@ public: dtypeSetUInt64(); } ASTNODE_NODE_FUNCS(ScopeName) - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return m_dpiExport == static_cast(samep)->m_dpiExport; } @@ -5517,7 +5416,6 @@ public: virtual bool isGateOptimizable() const override { return false; } virtual bool isPredictOptimizable() const override { return false; } virtual int instrCount() const override { return instrCountPli(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } AstNode* seedp() const { return op1p(); } bool reset() const { return m_reset; } @@ -5565,7 +5463,6 @@ public: virtual bool isGateOptimizable() const override { return false; } virtual bool isPredictOptimizable() const override { return false; } virtual int instrCount() const override { return instrCountTime(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } virtual void dump(std::ostream& str = std::cout) const override; void timeunit(const VTimescale& flag) { m_timeunit = flag; } @@ -5587,7 +5484,6 @@ public: virtual bool isGateOptimizable() const override { return false; } virtual bool isPredictOptimizable() const override { return false; } virtual int instrCount() const override { return instrCountTime(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } virtual void dump(std::ostream& str = std::cout) const override; void timeunit(const VTimescale& flag) { m_timeunit = flag; } @@ -5613,7 +5509,6 @@ public: virtual bool isSubstOptimizable() const override { return false; } virtual bool isPredictOptimizable() const override { return false; } virtual int instrCount() const override { return instrCountPli(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -6175,7 +6070,6 @@ public: virtual bool cleanOut() const override { return true; } virtual bool cleanLhs() const override { return true; } virtual bool sizeMattersLhs() const override { return false; } // Special cased in V3Cast - virtual V3Hash sameHash() const override { return V3Hash(size()); } virtual bool same(const AstNode* samep) const override { return size() == static_cast(samep)->size(); } @@ -6198,7 +6092,6 @@ public: virtual bool cleanOut() const override { return true; } virtual bool cleanLhs() const override { return true; } virtual bool sizeMattersLhs() const override { return false; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -6241,7 +6134,6 @@ public: AstNode* filep() const { return op1p(); } void strp(AstNode* nodep) { setOp2p(nodep); } AstNode* strp() const { return op2p(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -8364,7 +8256,6 @@ public: AstNode* exprp() const { return op1p(); } // op1 = expression AstSenTree* sentreep() const { return VN_CAST(op2p(), SenTree); } // op2 = clock domain void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -8388,7 +8279,6 @@ public: AstNode* ticksp() const { return op2p(); } // op2 = ticks or nullptr means 1 AstSenTree* sentreep() const { return VN_CAST(op4p(), SenTree); } // op4 = clock domain void sentreep(AstSenTree* sentreep) { addOp4p(sentreep); } // op4 = clock domain - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -8410,7 +8300,6 @@ public: AstNode* exprp() const { return op1p(); } // op1 = expression AstSenTree* sentreep() const { return VN_CAST(op2p(), SenTree); } // op2 = clock domain void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -8430,7 +8319,6 @@ public: virtual bool cleanOut() const override { V3ERROR_NA_RETURN(""); } virtual int instrCount() const override { return 0; } AstNode* exprp() const { return op1p(); } // op1 = expression - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -8452,7 +8340,6 @@ public: AstNode* exprp() const { return op1p(); } // op1 = expression AstSenTree* sentreep() const { return VN_CAST(op2p(), SenTree); } // op2 = clock domain void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -8527,7 +8414,6 @@ public: void rhsp(AstNode* nodep) { return setOp2p(nodep); } AstSenTree* sentreep() const { return VN_CAST(op4p(), SenTree); } // op4 = clock domain void sentreep(AstSenTree* sentreep) { addOp4p(sentreep); } // op4 = clock domain - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -8591,7 +8477,6 @@ public: } ASTNODE_BASE_FUNCS(NodeCoverOrAssert) virtual string name() const override { return m_name; } // * = Var name - virtual V3Hash sameHash() const override { return V3Hash(name()); } virtual bool same(const AstNode* samep) const override { return samep->name() == name(); } virtual void name(const string& name) override { m_name = name; } virtual void dump(std::ostream& str = std::cout) const override; @@ -8750,7 +8635,6 @@ public: virtual bool isPredictOptimizable() const override { return false; } virtual bool isPure() const override { return false; } virtual bool isOutputter() const override { return true; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } }; @@ -8771,7 +8655,6 @@ public: ASTNODE_BASE_FUNCS(NodeFile) virtual void dump(std::ostream& str) const override; virtual string name() const override { return m_name; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } void tblockp(AstTextBlock* tblockp) { setOp1p(tblockp); } AstTextBlock* tblockp() { return VN_CAST(op1p(), TextBlock); } @@ -8885,7 +8768,6 @@ public: } virtual bool maybePointedTo() const override { return true; } virtual void dump(std::ostream& str = std::cout) const override; - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { const AstCFunc* asamep = static_cast(samep); return ((funcType() == asamep->funcType()) && (rtnTypeVoid() == asamep->rtnTypeVoid()) @@ -9023,7 +8905,6 @@ public: } ASTNODE_NODE_FUNCS(CReturn) virtual int instrCount() const override { return widthInstrs(); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } // AstNode* lhsp() const { return op1p(); } @@ -9055,7 +8936,6 @@ public: virtual bool cleanOut() const override { return m_cleanOut; } virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); } virtual string emitC() override { V3ERROR_NA_RETURN(""); } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } void addBodysp(AstNode* nodep) { addNOp1p(nodep); } AstNode* bodysp() const { return op1p(); } // op1 = expressions to print @@ -9073,7 +8953,6 @@ public: ASTNODE_NODE_FUNCS(CReset) virtual bool isGateOptimizable() const override { return false; } virtual bool isPredictOptimizable() const override { return false; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } AstVarRef* varrefp() const { return VN_CAST(op1p(), VarRef); } // op1 = varref to reset }; @@ -9092,7 +8971,6 @@ public: ASTNODE_NODE_FUNCS(CStmt) virtual bool isGateOptimizable() const override { return false; } virtual bool isPredictOptimizable() const override { return false; } - virtual V3Hash sameHash() const override { return V3Hash(); } virtual bool same(const AstNode* samep) const override { return true; } void addBodysp(AstNode* nodep) { addNOp1p(nodep); } AstNode* bodysp() const { return op1p(); } // op1 = expressions to print diff --git a/src/V3Combine.cpp b/src/V3Combine.cpp index 4fc8f5e6c..b859b455c 100644 --- a/src/V3Combine.cpp +++ b/src/V3Combine.cpp @@ -132,8 +132,7 @@ private: // Remove calls to empty function UASSERT_OBJ(!oldfuncp->user3(), oldfuncp, "Should not be processed yet"); - UINFO(5, " Drop empty CFunc " << std::hex << V3Hash(oldfuncp->user4p()) << " " - << oldfuncp << endl); + UINFO(5, " Drop empty CFunc " << itr.first << " " << oldfuncp << endl); oldfuncp->user3SetOnce(); // Mark replaced m_call.replaceFunc(oldfuncp, nullptr); oldfuncp->unlinkFrBack(); @@ -161,10 +160,8 @@ private: if (!newfuncp->sameTree(oldfuncp)) continue; // Different functions // Replace calls to oldfuncp with calls to newfuncp - UINFO(5, " Replace CFunc " << std::hex << V3Hash(newfuncp->user4p()) << " " - << newfuncp << endl); - UINFO(5, " with " << std::hex << V3Hash(oldfuncp->user4p()) << " " - << oldfuncp << endl); + UINFO(5, " Replace CFunc " << newIt->first << " " << newfuncp << endl); + UINFO(5, " with " << oldIt->first << " " << oldfuncp << endl); ++m_cfuncsCombined; oldfuncp->user3SetOnce(); // Mark replaced m_call.replaceFunc(oldfuncp, newfuncp); diff --git a/src/V3DupFinder.cpp b/src/V3DupFinder.cpp index e6aa43d36..061e659db 100644 --- a/src/V3DupFinder.cpp +++ b/src/V3DupFinder.cpp @@ -30,11 +30,6 @@ //###################################################################### // V3DupFinder class functions -bool V3DupFinder::sameNodes(AstNode* node1p, AstNode* node2p) { - return m_hasher(node1p) == m_hasher(node2p) // Same hash - && node1p->sameTree(node2p); // Same tree -} - V3DupFinder::iterator V3DupFinder::findDuplicate(AstNode* nodep, V3DupFinderUserSame* checkp) { const auto& er = equal_range(m_hasher(nodep)); for (iterator it = er.first; it != er.second; ++it) { diff --git a/src/V3DupFinder.h b/src/V3DupFinder.h index 43a63be0d..0b512462e 100644 --- a/src/V3DupFinder.h +++ b/src/V3DupFinder.h @@ -67,10 +67,6 @@ public: // Insert node into data structure iterator insert(AstNode* nodep) { return emplace(m_hasher(nodep), nodep); } - // Check if nodes are the same (same as node1p->sameTree(node2p), - // but first checks the hashes are equal for speed) - bool sameNodes(AstNode* node1p, AstNode* node2p); - // Return duplicate, if one was inserted, with optional user check for sameness iterator findDuplicate(AstNode* nodep, V3DupFinderUserSame* checkp = nullptr); diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp index a23c89485..f9144db8d 100644 --- a/src/V3Gate.cpp +++ b/src/V3Gate.cpp @@ -919,16 +919,28 @@ private: VL_DEBUG_FUNC; // Declare debug() - bool sameHash(AstNode* node1p, AstNode* 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); + // Regarding the complexity of this funcition 'same': + // Applying this comparison function to a a set of n trees pairwise is O(n^2) in the + // number of comparisons (number of pairs). AstNode::sameTree itself, is O(sizeOfTree) in + // the worst case, which happens if the operands of sameTree are indeed identical copies, + // which means this line is O(n^2*sizeOfTree), iff you are comparing identical copies of + // the same tree. In practice the identity comparison over the pointers, and the short + // circuiting in sameTree means that for comparing the same tree instance to itself, or + // trees of different types/shapes is a lot closer to O(1), so this 'same' function is + // Omega(n^2) and O(n^2*sizeOfTree), and in practice as we are mostly comparing the same + // instance to itself or different trees, the complexity should be closer to the lower + // bound. + // + // Also if you see where this 'same' function is used within isSame, it's only ever + // comparing AstActive nodes, which are very likely not to compare equals (and for the + // purposes of V3Gate, we probably only care about them either being identical instances, + // or having the same sensitivities anyway, so if this becomes a problem, it can be + // improved which should also speed things up), and AstNodeMath for if conditions, which + // are hopefully small, and to be safe they should probably be only considered same when + // identical instances (otherwise if writing the condition between 2 ifs don't really + // merge). + return node1p == node2p || (node1p && node1p->sameTree(node2p)); } public: diff --git a/src/V3Hash.cpp b/src/V3Hash.cpp new file mode 100644 index 000000000..2f1b33003 --- /dev/null +++ b/src/V3Hash.cpp @@ -0,0 +1,27 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// DESCRIPTION: Verilator: Hash calculation +// +// Code available from: https://verilator.org +// +//************************************************************************* +// +// Copyright 2003-2021 by Wilson Snyder. This program is free software; you +// can redistribute it and/or modify it under the terms of either the GNU +// Lesser General Public License Version 3 or the Perl Artistic License +// Version 2.0. +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 +// +//************************************************************************* + +#include "V3Hash.h" + +#include +#include + +V3Hash::V3Hash(const std::string& val) + : m_value{static_cast(std::hash{}(val))} {} + +std::ostream& operator<<(std::ostream& os, const V3Hash& rhs) { + return os << std::hex << std::setw(8) << std::setfill('0') << rhs.value(); +} diff --git a/src/V3Hash.h b/src/V3Hash.h new file mode 100644 index 000000000..41a81140c --- /dev/null +++ b/src/V3Hash.h @@ -0,0 +1,65 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// DESCRIPTION: Verilator: Hash calculation +// +// Code available from: https://verilator.org +// +//************************************************************************* +// +// Copyright 2003-2021 by Wilson Snyder. This program is free software; you +// can redistribute it and/or modify it under the terms of either the GNU +// Lesser General Public License Version 3 or the Perl Artistic License +// Version 2.0. +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 +// +//************************************************************************* + +#ifndef VERILATOR_V3HASH_H_ +#define VERILATOR_V3HASH_H_ + +#include +#include + +//###################################################################### +// V3Hash -- Generic hashing + +class V3Hash final { + // A 32-bit hash value. A value of 0 is illegal. + uint32_t m_value; + +public: + // METHODS + uint32_t value() const { return m_value; } + + // OPERATORS + bool operator==(const V3Hash& rh) const { return m_value == rh.m_value; } + bool operator!=(const V3Hash& rh) const { return m_value != rh.m_value; } + bool operator<(const V3Hash& rh) const { return m_value < rh.m_value; } + V3Hash operator+(uint32_t value) const { + const uint64_t prod = (static_cast(m_value) * 31) + value; + return V3Hash(static_cast(prod ^ (prod >> 32))); + } + V3Hash operator+(int32_t value) const { return *this + static_cast(value); } + V3Hash operator+(const V3Hash& that) const { return *this + that.m_value; } + + V3Hash& operator+=(const V3Hash& that) { + *this = *this + that.m_value; + return *this; + } + V3Hash& operator+=(uint32_t value) { return *this += V3Hash(value); } + V3Hash& operator+=(int32_t value) { return *this += V3Hash(value); } + V3Hash& operator+=(const std::string& that) { return *this += V3Hash(that); } + + // CONSTRUCTORS + V3Hash() + : m_value{1} {} + explicit V3Hash(uint32_t val) + : m_value{val | 1} {} + explicit V3Hash(int32_t val) + : m_value{static_cast(val)} {} + explicit V3Hash(const std::string& val); +}; + +std::ostream& operator<<(std::ostream& os, const V3Hash& rhs); + +#endif // Guard diff --git a/src/V3Hasher.cpp b/src/V3Hasher.cpp index 4a8f51742..625e923a3 100644 --- a/src/V3Hasher.cpp +++ b/src/V3Hasher.cpp @@ -1,6 +1,6 @@ // -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* -// DESCRIPTION: Verilator: Hashed common code into functions +// DESCRIPTION: Verilator: AstNode hash computation // // Code available from: https://verilator.org // @@ -19,6 +19,8 @@ #include "V3Hasher.h" +#include + //###################################################################### // Visitor that computes node hashes @@ -29,38 +31,426 @@ private: // AstUser4InUse in V3Hasher.h // STATE - V3Hash m_lowerHash; // Hash of the statement we're building + V3Hash m_hash; // Hash value accumulator const bool m_cacheInUser4; // Use user4 to cache each V3Hash? // METHODS VL_DEBUG_FUNC; // Declare debug() - //-------------------- - virtual void visit(AstVar*) override {} - virtual void visit(AstTypedef*) override {} - virtual void visit(AstParamTypeDType*) override {} + V3Hash hashNodeAndIterate(AstNode* nodep, bool hashDType, bool hashChildren, + std::function&& f) { + if (m_cacheInUser4 && nodep->user4()) { + return V3Hash(nodep->user4()); + } else { + VL_RESTORER(m_hash); + // Reset accumulator + m_hash = V3Hash(nodep->type()); // Node type + f(); // Node specific hash + if (hashDType && nodep != nodep->dtypep()) iterateNull(nodep->dtypep()); // Node dtype + if (hashChildren) iterateChildrenConst(nodep); // Children + if (m_cacheInUser4) nodep->user4(m_hash.value()); + return m_hash; + } + } + + // VISITORS + + constexpr static bool HASH_DTYPE = true; + constexpr static bool HASH_CHILDREN = true; + + // Each visitor below contributes to the hash any node specific content + // that is not dependent on either of the following, as these are + // included by default by hashNode: + // - Node type (as given by AstNode::type()) + // - Node dtype (unless !hashDType) + // - child nodes (unless !hashChildren) + // + // The hash must be stable, which means in particular it cannot rely on + // pointer values, or any other value that might differ between separate + // invocations of Verilator over the same design. + // + // Note there is a circularity problem where some child nodes can back + // to their ancestral nodes via member pointers, which can lead to an + // infinite traversal. To break this, nodes that are subject to such + // referencing and represent code which can reasonably be assumed not to + // be equivalent to any other code, are hashed either by name (e.g.: + // AstNodeModule), or by unique identifier (e.g.: AstNodeUOrStructDType). + + //------------------------------------------------------------ + // AstNode - Warns to help find missing cases virtual void visit(AstNode* nodep) override { - V3Hash thisHash; - if (!m_cacheInUser4 || !nodep->user4()) { - VL_RESTORER(m_lowerHash); - { - m_lowerHash = nodep->sameHash(); - UASSERT_OBJ(!m_lowerHash.isIllegal(), nodep, - "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(V3Hash(nodep->type() << 6), V3Hash(nodep->dtypep()))); - // Now update m_lowerHash for our children's (and next children) contributions - iterateChildrenConst(nodep); - // Store the hash value - if (m_cacheInUser4) { nodep->user4(m_lowerHash.fullValue()); } - thisHash = m_lowerHash; +#if VL_DEBUG + UINFO(0, "%Warning: Hashing node as AstNode: " << nodep); +#endif + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {}); + } + + //------------------------------------------------------------ + // AstNodeDType + virtual void visit(AstNodeArrayDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { + iterateNull(nodep->virtRefDTypep()); + m_hash += nodep->left(); + m_hash += nodep->right(); + }); + } + virtual void visit(AstNodeUOrStructDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, false, [=]() { // + m_hash += nodep->uniqueNum(); + }); + } + virtual void visit(AstParamTypeDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { + m_hash += nodep->name(); + m_hash += nodep->varType(); + }); + } + virtual void visit(AstMemberDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { // + m_hash += nodep->name(); + }); + } + virtual void visit(AstDefImplicitDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->uniqueNum(); + }); + } + virtual void visit(AstAssocArrayDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { + iterateNull(nodep->virtRefDTypep()); + iterateNull(nodep->virtRefDType2p()); + }); + } + virtual void visit(AstDynArrayDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { // + iterateNull(nodep->virtRefDTypep()); + }); + } + virtual void visit(AstUnsizedArrayDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { // + iterateNull(nodep->virtRefDTypep()); + }); + } + virtual void visit(AstBasicDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { + m_hash += nodep->keyword(); + m_hash += nodep->nrange().left(); + m_hash += nodep->nrange().right(); + }); + } + virtual void visit(AstConstDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + iterateNull(nodep->virtRefDTypep()); + }); + } + virtual void visit(AstClassRefDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { // + iterateNull(nodep->classp()); + }); + } + virtual void visit(AstIfaceRefDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { // + iterateNull(nodep->cellp()); + }); + } + virtual void visit(AstQueueDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { // + iterateNull(nodep->virtRefDTypep()); + }); + } + virtual void visit(AstRefDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { + m_hash += nodep->name(); + iterateNull(nodep->typedefp()); + iterateNull(nodep->refDTypep()); + }); + } + virtual void visit(AstVoidDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() {}); + } + virtual void visit(AstEnumDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, false, [=]() { // + m_hash += nodep->uniqueNum(); + }); + } + + //------------------------------------------------------------ + // AstNodeMath + virtual void visit(AstNodeMath* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {}); + } + virtual void visit(AstConst* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->num().toHash(); + }); + } + virtual void visit(AstNullCheck* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {}); + } + virtual void visit(AstCCast* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->size(); + }); + } + virtual void visit(AstVarRef* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { + if (nodep->varScopep()) { + iterateNull(nodep->varScopep()); + } else { + iterateNull(nodep->varp()); + m_hash += nodep->hiernameToProt(); } - } - // Update what will become the above node's hash - m_lowerHash += m_cacheInUser4 ? V3Hash(nodep->user4()) : thisHash; + }); + } + virtual void visit(AstVarXRef* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { + iterateNull(nodep->varp()); + m_hash += nodep->dotted(); + }); + } + virtual void visit(AstMemberSel* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->name(); + }); + } + virtual void visit(AstFScanF* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->text(); + }); + } + virtual void visit(AstSScanF* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->text(); + }); + } + virtual void visit(AstTestPlusArgs* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->text(); + }); + } + + //------------------------------------------------------------ + // AstNodeStmt + virtual void visit(AstNodeStmt* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() {}); + } + virtual void visit(AstNodeText* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { // + m_hash += nodep->text(); + }); + } + virtual void visit(AstNodeCCall* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { // + iterateNull(nodep->funcp()); + }); + } + virtual void visit(AstNodeFTaskRef* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { + iterateNull(nodep->taskp()); + iterateNull(nodep->classOrPackagep()); + }); + } + virtual void visit(AstCMethodHard* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { // + m_hash += nodep->name(); + }); + } + virtual void visit(AstCoverInc* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { // + iterateNull(nodep->declp()); + }); + } + virtual void visit(AstDisplay* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { // + m_hash += nodep->displayType(); + }); + } + virtual void visit(AstMonitorOff* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { // + m_hash += nodep->off(); + }); + } + virtual void visit(AstJumpGo* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { // + iterateNull(nodep->labelp()); + }); + } + virtual void visit(AstTraceInc* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { // + iterateNull(nodep->declp()); + }); + } + virtual void visit(AstNodeCoverOrAssert* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { // + m_hash += nodep->name(); + }); + } + + //------------------------------------------------------------ + // AstNode direct descendents + virtual void visit(AstNodeRange* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {}); + } + virtual void visit(AstNodeModule* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, false, [=]() { + m_hash += nodep->origName(); + m_hash += nodep->hierName(); + }); + } + virtual void visit(AstNodePreSel* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {}); + } + virtual void visit(AstClassExtends* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {}); + } + virtual void visit(AstSelLoopVars* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {}); + } + virtual void visit(AstDefParam* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {}); + } + virtual void visit(AstArg* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {}); + } + virtual void visit(AstParseRef* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { + m_hash += nodep->expect(); + m_hash += nodep->name(); + }); + } + virtual void visit(AstClassOrPackageRef* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + iterateNull(nodep->classOrPackageNodep()); + }); + } + virtual void visit(AstSenItem* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->edgeType(); + }); + } + virtual void visit(AstSenTree* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {}); + } + virtual void visit(AstSFormatF* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->text(); + }); + } + virtual void visit(AstElabDisplay* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->displayType(); + }); + } + virtual void visit(AstInitItem* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {}); + } + virtual void visit(AstInitArray* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {}); + } + virtual void visit(AstPragma* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->pragType(); + }); + } + virtual void visit(AstAttrOf* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->attrType(); + }); + } + virtual void visit(AstNodeFile* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->name(); + }); + } + virtual void visit(AstCFunc* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {}); + } + virtual void visit(AstVar* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { + m_hash += nodep->name(); + m_hash += nodep->varType(); + }); + } + virtual void visit(AstScope* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, false, [=]() { + m_hash += nodep->name(); + iterateNull(nodep->aboveScopep()); + }); + } + virtual void visit(AstVarScope* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { + iterateNull(nodep->varp()); + iterateNull(nodep->scopep()); + }); + } + virtual void visit(AstEnumItem* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->name(); + }); + } + virtual void visit(AstTypedef* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->name(); + }); + } + virtual void visit(AstTypedefFwd* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->name(); + }); + } + virtual void visit(AstActive* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + iterateNull(nodep->sensesp()); + }); + } + virtual void visit(AstCell* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { + m_hash += nodep->name(); + iterateNull(nodep->modp()); + }); + } + virtual void visit(AstCellInline* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { + m_hash += nodep->name(); + iterateNull(nodep->scopep()); + }); + } + virtual void visit(AstNodeFTask* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->name(); + }); + } + virtual void visit(AstModport* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->name(); + }); + } + virtual void visit(AstModportVarRef* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { + m_hash += nodep->name(); + iterateNull(nodep->varp()); + }); + } + virtual void visit(AstModportFTaskRef* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { + m_hash += nodep->name(); + iterateNull(nodep->ftaskp()); + }); + } + virtual void visit(AstNodeProcedure* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {}); + } + virtual void visit(AstNodeBlock* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->name(); + }); + } + virtual void visit(AstPin* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { + m_hash += nodep->name(); + m_hash += nodep->pinNum(); + }); } public: @@ -73,7 +463,7 @@ public: : m_cacheInUser4{false} { iterate(const_cast(nodep)); } - V3Hash finalHash() const { return m_lowerHash; } + V3Hash finalHash() const { return m_hash; } virtual ~HasherVisitor() override = default; }; diff --git a/src/V3Hasher.h b/src/V3Hasher.h index fc90de27f..6207515f1 100644 --- a/src/V3Hasher.h +++ b/src/V3Hasher.h @@ -25,6 +25,7 @@ #include "V3Error.h" #include "V3Ast.h" +#include "V3Hash.h" //============================================================================ diff --git a/src/V3Number.cpp b/src/V3Number.cpp index a5f7491d9..f880996c1 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -883,7 +883,7 @@ string V3Number::toString() const { return str; } -uint32_t V3Number::toHash() const { return m_value[0]; } +V3Hash V3Number::toHash() const { return V3Hash(m_width * (m_value[0] | 1)); } uint32_t V3Number::edataWord(int eword) const { UASSERT(!isFourState(), "edataWord with 4-state " << *this); diff --git a/src/V3Number.h b/src/V3Number.h index ab1bc4dd2..fd0f41f93 100644 --- a/src/V3Number.h +++ b/src/V3Number.h @@ -21,6 +21,7 @@ #include "verilatedos.h" #include "V3Error.h" +#include "V3Hash.h" #include #include @@ -298,7 +299,7 @@ public: string toDecimalS() const; // return ASCII signed decimal number string toDecimalU() const; // return ASCII unsigned decimal number double toDouble() const; - uint32_t toHash() const; + V3Hash toHash() const; uint32_t edataWord(int eword) const; uint8_t dataByte(int byte) const; uint32_t countBits(const V3Number& ctrl) const; diff --git a/src/V3ProtectLib.cpp b/src/V3ProtectLib.cpp index 7c42f868c..e1bae6365 100644 --- a/src/V3ProtectLib.cpp +++ b/src/V3ProtectLib.cpp @@ -88,8 +88,8 @@ private: iterateChildren(nodep); V3Hash hash = V3Hasher::uncachedHash(m_cfilep); - m_hashValuep->addText(fl, cvtToStr(hash.fullValue()) + ";\n"); - m_cHashValuep->addText(fl, cvtToStr(hash.fullValue()) + "U;\n"); + m_hashValuep->addText(fl, cvtToStr(hash.value()) + ";\n"); + m_cHashValuep->addText(fl, cvtToStr(hash.value()) + "U;\n"); m_foundTop = true; } diff --git a/src/V3SenTree.h b/src/V3SenTree.h index 78d5f3a34..5abca02f6 100644 --- a/src/V3SenTree.h +++ b/src/V3SenTree.h @@ -37,7 +37,7 @@ private: // TYPES struct HashSenTree { size_t operator()(const AstSenTree* kp) const { - return V3Hasher::uncachedHash(kp).fullValue(); + return V3Hasher::uncachedHash(kp).value(); } };