string -> V3Hash

This commit is contained in:
Todd Strader 2026-07-02 17:12:13 -04:00
parent d85f04ec4b
commit 189cf47393
3 changed files with 23 additions and 34 deletions

View File

@ -18,6 +18,7 @@
#include "V3Control.h" #include "V3Control.h"
#include "V3Hash.h"
#include "V3InstrCount.h" #include "V3InstrCount.h"
#include "V3String.h" #include "V3String.h"
@ -843,6 +844,7 @@ class V3ControlResolver final {
std::vector<V3ControlHierVarEntry> m_hierVarAttrs; // -path public attrs std::vector<V3ControlHierVarEntry> m_hierVarAttrs; // -path public attrs
V3ControlHierTreeNode m_hierVarTreeRoot; // Prefix tree over m_hierVarAttrs V3ControlHierTreeNode m_hierVarTreeRoot; // Prefix tree over m_hierVarAttrs
std::unordered_map<std::string, V3ControlHierTreeNode*> m_hierVarCellPaths; std::unordered_map<std::string, V3ControlHierTreeNode*> m_hierVarCellPaths;
std::map<V3Hash, int> m_hierVarVariants; // Interned hier variant hashes
std::unordered_map<string, std::unordered_map<string, uint64_t>> std::unordered_map<string, std::unordered_map<string, uint64_t>>
m_profileData; // Access to profile_data records m_profileData; // Access to profile_data records
uint8_t m_mode = NONE; uint8_t m_mode = NONE;
@ -865,6 +867,7 @@ public:
std::unordered_map<std::string, V3ControlHierTreeNode*>& hierVarCellPaths() { std::unordered_map<std::string, V3ControlHierTreeNode*>& hierVarCellPaths() {
return m_hierVarCellPaths; return m_hierVarCellPaths;
} }
std::map<V3Hash, int>& hierVarVariants() { return m_hierVarVariants; }
void addProfileData(FileLine* fl, const string& hierDpi, uint64_t cost) { void addProfileData(FileLine* fl, const string& hierDpi, uint64_t cost) {
// Empty key for hierarchical DPI wrapper costs. // Empty key for hierarchical DPI wrapper costs.
@ -1519,43 +1522,29 @@ void V3Control::applyHierVarAttrs(AstNetlist* netlistp) {
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// V3Param time per-cell -path unique cloning // V3Param time per-cell -path unique cloning
static void appendNodeSignature(const V3ControlHierTreeNode* nodep, std::string& out) {
// Leaf vars: "<name>=<attr>;" sorted by (name, attr). static V3Hash hashNodeMarkings(const V3ControlHierTreeNode* nodep) {
std::vector<std::pair<std::string, VAttrType>> vars = nodep->m_vars; uint32_t varsXor = 0; // Order-independent accumulator over the leaf var set
std::sort(vars.begin(), vars.end(), [](const auto& a, const auto& b) { for (const auto& var : nodep->m_vars) {
if (a.first != b.first) return a.first < b.first; varsXor ^= (V3Hash{var.first} + V3Hash{static_cast<int32_t>(var.second)}).value();
return a.second.ascii() < b.second.ascii();
});
// NOCOMMIT -- is this too verbose?
out += "v{";
for (const auto& var : vars) {
out += var.first;
out += "=";
out += var.second.ascii();
out += ";";
} }
out += "}"; V3Hash hash{varsXor};
// Child scopes: "<key>(<kind>:<subsig>)" in sorted key order (std::map).
out += "c{";
for (const auto& child : nodep->m_children) { for (const auto& child : nodep->m_children) {
out += child.first; hash += V3Hash{child.first} + V3Hash{static_cast<int32_t>(child.second->m_kind)}
out += ":"; + hashNodeMarkings(child.second.get());
out += std::to_string(static_cast<int>(child.second->m_kind));
out += "(";
appendNodeSignature(child.second.get(), out);
out += ")";
} }
out += "}"; return hash;
} }
// -path'ed public marking as a string for V3Param uniquification and cloning // Variant ID if -path'ed, else -1
std::string V3Control::cellPathPublicSignature(const std::string& cellInstancePath) { int V3Control::cellPathPublicVariant(const std::string& cellInstancePath) {
const auto& cellPaths = V3ControlResolver::s().hierVarCellPaths(); const auto& cellPaths = V3ControlResolver::s().hierVarCellPaths();
const auto it = cellPaths.find(cellInstancePath); const auto it = cellPaths.find(cellInstancePath);
if (it == cellPaths.end()) return ""; if (it == cellPaths.end()) return -1; // Not a -path'ed cell; no clone needed
std::string sig; auto& variants = V3ControlResolver::s().hierVarVariants();
appendNodeSignature(it->second, sig); const V3Hash hash = hashNodeMarkings(it->second);
return sig; const auto pair = variants.emplace(hash, static_cast<int>(variants.size()));
return pair.first->second;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -67,7 +67,7 @@ public:
static void addHierVarAttr(FileLine* fl, const string& path, VAttrType type); static void addHierVarAttr(FileLine* fl, const string& path, VAttrType type);
static void applyHierVarAttrs(AstNetlist* netlistp); static void applyHierVarAttrs(AstNetlist* netlistp);
static std::string cellPathPublicSignature(const std::string& cellInstancePath); static int cellPathPublicVariant(const std::string& cellInstancePath);
static void applyHierVarScopes(AstNetlist* netlistp); static void applyHierVarScopes(AstNetlist* netlistp);
static void applyCase(AstCase* nodep); static void applyCase(AstCase* nodep);

View File

@ -1963,10 +1963,10 @@ class ParamProcessor final {
string longname = srcModp->name() + "_"; string longname = srcModp->name() + "_";
// Clone for .vlt -path'ed variants // Clone for .vlt -path'ed variants
if (VN_IS(nodep, Cell)) { if (VN_IS(nodep, Cell)) {
const string pubSig = V3Control::cellPathPublicSignature(srcModp->someInstanceName()); const int pubVariant = V3Control::cellPathPublicVariant(srcModp->someInstanceName());
if (!pubSig.empty()) { if (pubVariant >= 0) {
any_overrides = true; any_overrides = true;
longname += "__Vhier" + V3Hash{pubSig}.toString(); longname += "__Vhier" + cvtToStr(pubVariant);
} }
} }
if (debug() >= 9 && paramsp) paramsp->dumpTreeAndNext(cout, "- cellparams: "); if (debug() >= 9 && paramsp) paramsp->dumpTreeAndNext(cout, "- cellparams: ");