mirror of
https://github.com/verilator/verilator.git
synced 2025-04-16 01:26:54 +00:00
Rework Ast hashing to be stable (#2974)
Rework Ast hashing to be stable Eliminated reliance on pointer values in AstNode hashes in order to make them stable. This requires moving the sameHash functions into a visitor, as nodes pointed to via members (and not child nodes) need to be hashed themselves. The hashes are now stable (as far as I could test them), and the impact on verilation time is small enough not to be reliably measurable.
This commit is contained in:
parent
fd35492226
commit
8814111724
@ -203,6 +203,7 @@ RAW_OBJS = \
|
||||
V3GraphDfa.o \
|
||||
V3GraphPathChecker.o \
|
||||
V3GraphTest.o \
|
||||
V3Hash.o \
|
||||
V3Hasher.o \
|
||||
V3HierBlock.o \
|
||||
V3Inline.o \
|
||||
|
@ -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
|
||||
|
||||
|
76
src/V3Ast.h
76
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<const AstNodeText*>(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<const AstNodeCCall*>(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);
|
||||
|
142
src/V3AstNodes.h
142
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<const AstConst*>(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<const AstDefImplicitDType*>(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<const AstBasicDType*>(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() : "<unlinked>"; }
|
||||
@ -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<const AstEnumDType*>(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<const AstCMethodHard*>(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<const AstVarRef*>(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<const AstVarXRef*>(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<const AstParseRef*>(samep);
|
||||
return (expect() == asamep->expect() && m_name == asamep->m_name);
|
||||
@ -3047,7 +3010,6 @@ public:
|
||||
return (m_classOrPackageNodep
|
||||
== static_cast<const AstClassOrPackageRef*>(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<const AstSenItem*>(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<const AstCoverDecl*>(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<const AstCoverInc*>(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<const AstSFormatF*>(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<const AstDisplay*>(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<const AstElabDisplay*>(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<const AstFScanF*>(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<const AstSScanF*>(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<const AstNodeReadWriteMem*>(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<const AstMonitorOff*>(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<const AstTestPlusArgs*>(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<const AstJumpLabel*>(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<const AstJumpGo*>(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<const AstPragma*>(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<const AstTraceInc*>(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<const AstScopeName*>(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<const AstCCast*>(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<const AstCFunc*>(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
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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:
|
||||
|
27
src/V3Hash.cpp
Normal file
27
src/V3Hash.cpp
Normal file
@ -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 <functional>
|
||||
#include <iomanip>
|
||||
|
||||
V3Hash::V3Hash(const std::string& val)
|
||||
: m_value{static_cast<uint32_t>(std::hash<std::string>{}(val))} {}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const V3Hash& rhs) {
|
||||
return os << std::hex << std::setw(8) << std::setfill('0') << rhs.value();
|
||||
}
|
65
src/V3Hash.h
Normal file
65
src/V3Hash.h
Normal file
@ -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 <cstdint>
|
||||
#include <string>
|
||||
|
||||
//######################################################################
|
||||
// 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<uint64_t>(m_value) * 31) + value;
|
||||
return V3Hash(static_cast<uint32_t>(prod ^ (prod >> 32)));
|
||||
}
|
||||
V3Hash operator+(int32_t value) const { return *this + static_cast<uint32_t>(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<uint32_t>(val)} {}
|
||||
explicit V3Hash(const std::string& val);
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const V3Hash& rhs);
|
||||
|
||||
#endif // Guard
|
442
src/V3Hasher.cpp
442
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 <functional>
|
||||
|
||||
//######################################################################
|
||||
// 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<void()>&& 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<AstNode*>(nodep));
|
||||
}
|
||||
V3Hash finalHash() const { return m_lowerHash; }
|
||||
V3Hash finalHash() const { return m_hash; }
|
||||
virtual ~HasherVisitor() override = default;
|
||||
};
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "V3Error.h"
|
||||
#include "V3Ast.h"
|
||||
#include "V3Hash.h"
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
@ -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);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include "V3Error.h"
|
||||
#include "V3Hash.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user