Avoid double traversal of maps

The typical find/if-not-exists-insert pattern can be achieved with 1
lookup instead of 2 using emplace with a sentinel value. Also maps value
initialize their values when inserted with the [] operator, this is
defined and so there is no need to explicitly insert zeroes for integer
values.
This commit is contained in:
Geza Lore 2023-10-28 13:38:02 +01:00
parent 30318a6654
commit d60f180f43
25 changed files with 240 additions and 311 deletions

View File

@ -1178,13 +1178,10 @@ AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, VBasicDTypeKwd kwd,
AstBasicDType* AstTypeTable::findInsertSameDType(AstBasicDType* nodep) {
const VBasicTypeKey key{nodep->width(), nodep->widthMin(), nodep->numeric(), nodep->keyword(),
nodep->nrange()};
DetailedMap& mapr = m_detailedMap;
const auto it = mapr.find(key);
if (it != mapr.end()) return it->second;
mapr.emplace(key, nodep);
nodep->generic(true);
auto pair = m_detailedMap.emplace(key, nodep);
if (pair.second) nodep->generic(true);
// No addTypesp; the upper function that called new() is responsible for adding
return nodep;
return pair.first->second;
}
AstConstPool::AstConstPool(FileLine* fl)
@ -1641,13 +1638,13 @@ void AstInitArray::cloneRelink() {
}
}
void AstInitArray::addIndexValuep(uint64_t index, AstNodeExpr* newp) {
const auto it = m_map.find(index);
if (it != m_map.end()) {
it->second->valuep(newp);
} else {
const auto pair = m_map.emplace(index, nullptr);
if (pair.second) {
AstInitItem* const itemp = new AstInitItem{fileline(), newp};
m_map.emplace(index, itemp);
pair.first->second = itemp;
addInitsp(itemp);
} else {
pair.first->second->valuep(newp);
}
}
AstNodeExpr* AstInitArray::getIndexValuep(uint64_t index) const {

View File

@ -400,12 +400,10 @@ public:
bool getEntryMatch(const V3ConfigScopeTraceEntry* entp, const string& scopepart) {
// Return if a entry matches the scopepart, with memoization
const auto& key = V3ConfigScopeTraceEntryMatch{entp, scopepart};
const auto& it = m_matchCache.find(key);
if (it != m_matchCache.end()) return it->second; // Cached
const bool matched = VString::wildmatch(scopepart, entp->m_scope);
m_matchCache.emplace(key, matched);
return matched;
const V3ConfigScopeTraceEntryMatch key{entp, scopepart};
const auto pair = m_matchCache.emplace(key, false);
if (pair.second) pair.first->second = VString::wildmatch(scopepart, entp->m_scope);
return pair.first->second;
}
bool getScopeTraceOn(const string& scope) {

View File

@ -77,7 +77,8 @@ private:
CheckState m_state; // State save-restored on each new coverage scope/block
AstNodeModule* m_modp = nullptr; // Current module to add statement to
bool m_inToggleOff = false; // In function/task etc
std::unordered_map<std::string, int> m_varnames; // Uniquification of inserted variable names
// Uniquification of inserted variable names
std::unordered_map<std::string, uint32_t> m_varnames;
string m_beginHier; // AstBegin hier name for user coverage points
std::unordered_map<int, LinenoSet>
m_handleLines; // All line numbers for a given m_stateHandle
@ -141,13 +142,7 @@ private:
string traceNameForLine(AstNode* nodep, const string& type) {
string name = "vlCoverageLineTrace_" + nodep->fileline()->filebasenameNoExt() + "__"
+ cvtToStr(nodep->fileline()->lineno()) + "_" + type;
const auto it = m_varnames.find(name);
if (it == m_varnames.end()) {
m_varnames.emplace(name, 1);
} else {
const int suffix = (it->second)++;
name += "_" + cvtToStr(suffix);
}
if (const uint32_t suffix = m_varnames[name]++) name += "_" + cvtToStr(suffix);
return name;
}

View File

@ -145,30 +145,26 @@ private:
int width /*0==fromoldvar*/, AstNodeDType* newdtypep) {
// Because we've already scoped it, we may need to add both the AstVar and the AstVarScope
UASSERT_OBJ(oldvarscp->scopep(), oldvarscp, "Var unscoped");
AstVar* varp;
FileLine* const flp = oldvarscp->fileline();
AstNodeModule* const addmodp = oldvarscp->scopep()->modp();
// We need a new AstVar, but only one for all scopes, to match the new AstVarScope
const auto it = m_modVarMap.find(std::make_pair(addmodp, name));
if (it != m_modVarMap.end()) {
// Created module's AstVar earlier under some other scope
varp = it->second;
} else {
const auto pair = m_modVarMap.emplace(std::make_pair(addmodp, name), nullptr);
if (pair.second) {
AstVar* varp = nullptr;
if (newdtypep) {
varp = new AstVar{oldvarscp->fileline(), VVarType::BLOCKTEMP, name, newdtypep};
varp = new AstVar{flp, VVarType::BLOCKTEMP, name, newdtypep};
} else if (width == 0) {
varp = new AstVar{oldvarscp->fileline(), VVarType::BLOCKTEMP, name,
oldvarscp->varp()};
varp = new AstVar{flp, VVarType::BLOCKTEMP, name, oldvarscp->varp()};
varp->dtypeFrom(oldvarscp);
} else { // Used for vset and dimensions, so can zero init
varp = new AstVar{oldvarscp->fileline(), VVarType::BLOCKTEMP, name,
VFlagBitPacked{}, width};
varp = new AstVar{flp, VVarType::BLOCKTEMP, name, VFlagBitPacked{}, width};
}
addmodp->addStmtsp(varp);
m_modVarMap.emplace(std::make_pair(addmodp, name), varp);
pair.first->second = varp;
}
AstVar* const varp = pair.first->second;
AstVarScope* const varscp
= new AstVarScope{oldvarscp->fileline(), oldvarscp->scopep(), varp};
AstVarScope* const varscp = new AstVarScope{flp, oldvarscp->scopep(), varp};
oldvarscp->scopep()->addVarsp(varscp);
return varscp;
}

View File

@ -63,13 +63,7 @@ void V3DupFinder::dumpFile(const string& filename, bool tree) {
for (auto it = cbegin(); true; ++it) {
if (it == cend() || lasthash != it->first) {
if (it != cend()) lasthash = it->first;
if (num_in_bucket) {
if (dist.find(num_in_bucket) == dist.end()) {
dist.emplace(num_in_bucket, 1);
} else {
++dist[num_in_bucket];
}
}
if (num_in_bucket) ++dist[num_in_bucket];
num_in_bucket = 0;
}
if (it == cend()) break;

View File

@ -187,12 +187,9 @@ class EmitCSyms final : EmitCBaseVisitorConst {
const auto scpit = m_vpiScopeCandidates.find(scopeSymString(scp));
if ((scpit != m_vpiScopeCandidates.end())
&& (m_scopeNames.find(scp) == m_scopeNames.end())) {
const auto scopeNameit = m_scopeNames.find(scpit->second.m_symName);
if (scopeNameit == m_scopeNames.end()) {
m_scopeNames.emplace(scpit->second.m_symName, scpit->second);
} else {
scopeNameit->second.m_type = scpit->second.m_type;
}
// If not in m_scopeNames, add it, otherwise just update m_type
const auto pair = m_scopeNames.emplace(scpit->second.m_symName, scpit->second);
if (!pair.second) pair.first->second.m_type = scpit->second.m_type;
}
string::size_type pos = scp.rfind("__DOT__");
if (pos == string::npos) {

View File

@ -991,10 +991,8 @@ public:
string protectIf(const string& old, bool doIt) VL_MT_SAFE_EXCLUDES(m_mutex) {
if (!v3Global.opt.protectIds() || old.empty() || !doIt) return old;
const V3LockGuard lock{m_mutex};
const auto it = m_nameMap.find(old);
if (it != m_nameMap.end()) {
return it->second;
} else {
const auto pair = m_nameMap.emplace(old, "");
if (pair.second) {
string out;
if (v3Global.opt.debugProtect()) {
// This lets us see the symbol being protected to debug cases
@ -1009,16 +1007,15 @@ public:
// See if we can shrink the digest symbol to something smaller
for (size_t len = 6; len < out.size() - 3; len += 3) {
const string tryout = out.substr(0, len);
if (m_newIdSet.find(tryout) == m_newIdSet.end()) {
if (m_newIdSet.insert(tryout).second) {
out = tryout;
break;
}
}
}
m_nameMap.emplace(old, out);
m_newIdSet.insert(out);
return out;
pair.first->second = out;
}
return pair.first->second;
}
string protectWordsIf(const string& old, bool doIt) VL_MT_SAFE {
// Split at " " (for traces), "." (for scopes), "->", "(", "&", ")" (for self pointers)

View File

@ -114,8 +114,8 @@ void V3Global::dumpCheckGlobalTree(const string& stagename, int newNumber, bool
}
const std::string& V3Global::ptrToId(const void* p) {
auto it = m_ptrToId.find(p);
if (it == m_ptrToId.end()) {
const auto pair = m_ptrToId.emplace(p, "");
if (pair.second) {
std::ostringstream os;
if (p) {
os << "(";
@ -125,7 +125,7 @@ const std::string& V3Global::ptrToId(const void* p) {
} else {
os << "0";
}
it = m_ptrToId.emplace(p, os.str()).first;
pair.first->second = os.str();
}
return it->second;
return pair.first->second;
}

View File

@ -306,12 +306,12 @@ public:
//######################################################################
void V3HierBlockPlan::add(const AstNodeModule* modp, const std::vector<AstVar*>& gparams) {
const iterator it = m_blocks.find(modp);
if (it == m_blocks.end()) {
const auto pair = m_blocks.emplace(modp, nullptr);
if (pair.second) {
V3HierBlock* hblockp = new V3HierBlock{modp, gparams};
UINFO(3, "Add " << modp->prettyNameQ() << " with " << gparams.size() << " parameters"
<< std::endl);
m_blocks.emplace(modp, hblockp);
pair.first->second = hblockp;
}
}

View File

@ -157,31 +157,27 @@ public:
// Do we have a old assignment we can nuke?
UINFO(4, " ASSIGNof: " << nodep << endl);
UINFO(7, " new: " << assp << endl);
const auto it = m_map.find(nodep);
if (it != m_map.end()) {
checkRemoveAssign(it);
it->second.simpleAssign(assp);
} else {
m_map.emplace(nodep, LifeVarEntry{LifeVarEntry::SIMPLEASSIGN{}, assp});
const auto pair = m_map.emplace(std::piecewise_construct, //
std::forward_as_tuple(nodep),
std::forward_as_tuple(LifeVarEntry::SIMPLEASSIGN{}, assp));
if (!pair.second) {
checkRemoveAssign(pair.first);
pair.first->second.simpleAssign(assp);
}
// lifeDump();
}
void complexAssign(AstVarScope* nodep) {
UINFO(4, " clearof: " << nodep << endl);
const auto it = m_map.find(nodep);
if (it != m_map.end()) {
it->second.complexAssign();
} else {
m_map.emplace(nodep, LifeVarEntry{LifeVarEntry::COMPLEXASSIGN{}});
}
const auto pair = m_map.emplace(nodep, LifeVarEntry::COMPLEXASSIGN{});
if (!pair.second) pair.first->second.complexAssign();
}
void clearReplaced() { m_replacedVref = false; }
bool replaced() const { return m_replacedVref; }
void varUsageReplace(AstVarScope* nodep, AstVarRef* varrefp) {
// Variable rvalue. If it references a constant, we can replace it
const auto it = m_map.find(nodep);
if (it != m_map.end()) {
if (AstConst* const constp = it->second.constNodep()) {
const auto pair = m_map.emplace(nodep, LifeVarEntry::CONSUMED{});
if (!pair.second) {
if (AstConst* const constp = pair.first->second.constNodep()) {
if (!varrefp->varp()->isSigPublic() && !varrefp->varp()->isUsedVirtIface()) {
// Aha, variable is constant; substitute in.
// We'll later constant propagate
@ -194,27 +190,19 @@ public:
}
}
UINFO(4, " usage: " << nodep << endl);
it->second.consumed();
} else {
m_map.emplace(nodep, LifeVarEntry{LifeVarEntry::CONSUMED{}});
pair.first->second.consumed();
}
}
void complexAssignFind(AstVarScope* nodep) {
const auto it = m_map.find(nodep);
if (it != m_map.end()) {
UINFO(4, " casfind: " << it->first << endl);
it->second.complexAssign();
} else {
m_map.emplace(nodep, LifeVarEntry{LifeVarEntry::COMPLEXASSIGN{}});
const auto pair = m_map.emplace(nodep, LifeVarEntry::COMPLEXASSIGN{});
if (!pair.second) {
UINFO(4, " casfind: " << pair.first->first << endl);
pair.first->second.complexAssign();
}
}
void consumedFind(AstVarScope* nodep) {
const auto it = m_map.find(nodep);
if (it != m_map.end()) {
it->second.consumed();
} else {
m_map.emplace(nodep, LifeVarEntry{LifeVarEntry::CONSUMED{}});
}
const auto pair = m_map.emplace(nodep, LifeVarEntry::CONSUMED{});
if (!pair.second) pair.first->second.consumed();
}
void lifeToAbove() {
// Any varrefs under a if/else branch affect statements outside and after the if/else

View File

@ -195,22 +195,18 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
for (AstNode* subnodep = oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) {
if (AstVar* const oldvarp = VN_CAST(subnodep, Var)) {
if (oldvarp->isIO()) {
if (ioNames.find(oldvarp->name()) != ioNames.end()) {
if (!ioNames.insert(oldvarp->name()).second) {
// UINFO(8, "Multitop dup I/O found: " << oldvarp << endl);
dupNames.insert(oldvarp->name());
} else {
ioNames.insert(oldvarp->name());
}
} else if (v3Global.opt.topIfacesSupported() && oldvarp->isIfaceRef()) {
const AstNodeDType* const subtypep = oldvarp->subDTypep();
if (VN_IS(subtypep, IfaceRefDType)) {
const AstIfaceRefDType* const ifacerefp = VN_AS(subtypep, IfaceRefDType);
if (!ifacerefp->cellp()) {
if (ioNames.find(oldvarp->name()) != ioNames.end()) {
if (!ioNames.insert(oldvarp->name()).second) {
// UINFO(8, "Multitop dup interface found: " << oldvarp << endl);
dupNames.insert(oldvarp->name());
} else {
ioNames.insert(oldvarp->name());
}
}
}
@ -221,12 +217,10 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
const AstIfaceRefDType* const ifacerefp
= VN_AS(arrsubtypep, IfaceRefDType);
if (!ifacerefp->cellp()) {
if (ioNames.find(oldvarp->name()) != ioNames.end()) {
if (!ioNames.insert(oldvarp->name()).second) {
// UINFO(8, "Multitop dup interface array found: " << oldvarp
// << endl);
dupNames.insert(oldvarp->name());
} else {
ioNames.insert(oldvarp->name());
}
}
}

View File

@ -495,14 +495,9 @@ public:
V3List<OrderMoveVertex*>& readyVertices() { return m_readyVertices; }
static OrderMoveDomScope* findCreate(const AstSenTree* domainp, const AstScope* scopep) {
const DomScopeKey key = std::make_pair(domainp, scopep);
const auto iter = s_dsMap.find(key);
if (iter != s_dsMap.end()) {
return iter->second;
} else {
OrderMoveDomScope* domScopep = new OrderMoveDomScope{domainp, scopep};
s_dsMap.emplace(key, domScopep);
return domScopep;
}
const auto pair = s_dsMap.emplace(key, nullptr);
if (pair.second) pair.first->second = new OrderMoveDomScope{domainp, scopep};
return pair.first->second;
}
string name() const {
return string{"MDS:"} + " d=" + cvtToHex(domainp()) + " s=" + cvtToHex(scopep());

View File

@ -356,27 +356,22 @@ class ParamProcessor final {
// cppcheck-has-bug-suppress unreadVariable
if (VL_UNLIKELY(v3Global.opt.debugCollision())) hash = V3Hash{paramStr};
int num;
const auto it = m_valueMap.find(hash);
if (it != m_valueMap.end()) {
num = it->second;
} else {
num = m_nextValue++;
m_valueMap[hash] = num;
}
const auto pair = m_valueMap.emplace(hash, 0);
if (pair.second) pair.first->second = m_nextValue++;
num = pair.first->second;
return std::string{"z"} + cvtToStr(num);
}
string moduleCalcName(const AstNodeModule* srcModp, const string& longname) {
string newname = longname;
if (longname.length() > 30) {
const auto iter = m_longMap.find(longname);
if (iter != m_longMap.end()) {
newname = iter->second;
} else {
const auto pair = m_longMap.emplace(longname, "");
if (pair.second) {
newname = srcModp->name();
// We use all upper case above, so lower here can't conflict
newname += "__pi" + cvtToStr(++m_longId);
m_longMap.emplace(longname, newname);
pair.first->second = newname;
}
newname = pair.first->second;
}
UINFO(4, "Name: " << srcModp->name() << "->" << longname << "->" << newname << endl);
return newname;
@ -496,8 +491,9 @@ class ParamProcessor final {
}
}
auto paramsIt = m_defaultParameterValues.find(modp);
if (paramsIt == m_defaultParameterValues.end()) { // Not cached yet, so check parameters
const auto pair = m_defaultParameterValues.emplace(
std::piecewise_construct, std::forward_as_tuple(modp), std::forward_as_tuple());
if (pair.second) { // Not cached yet, so check parameters
// Using map with key=string so that we can scan it in deterministic order
DefaultValueMap params;
for (AstNode* stmtp = modp->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
@ -511,8 +507,9 @@ class ParamProcessor final {
}
}
}
paramsIt = m_defaultParameterValues.emplace(modp, std::move(params)).first;
pair.first->second = std::move(params);
}
const auto paramsIt = pair.first;
if (paramsIt->second.empty()) return modp->name(); // modp has no parameter
string longname = modp->name();

View File

@ -93,10 +93,9 @@ public:
PartPtrIdMap() = default;
// METHODS
uint64_t findId(const void* ptrp) const {
const auto it = m_id.find(ptrp);
if (it != m_id.end()) return it->second;
m_id[ptrp] = m_nextId;
return m_nextId++;
const auto pair = m_id.emplace(ptrp, m_nextId);
if (pair.second) ++m_nextId;
return pair.first->second;
}
};

View File

@ -178,12 +178,13 @@ private:
const std::string type = AstCDType::typeToHold(items);
const std::string name = "VlRandC<" + type + ", " + cvtToStr(items) + "ULL>";
// Create or reuse (to avoid duplicates) randomization object dtype
auto it = m_randcDtypes.find(name);
if (it != m_randcDtypes.end()) return it->second;
const auto pair = m_randcDtypes.emplace(name, nullptr);
if (pair.second) {
AstCDType* newp = new AstCDType{fl, name};
v3Global.rootp()->typeTablep()->addTypesp(newp);
m_randcDtypes.emplace(name, newp);
return newp;
pair.first->second = newp;
}
return pair.first->second;
}
AstVar* newRandcVarsp(AstVar* varp) {

View File

@ -155,10 +155,9 @@ class SchedGraphBuilder final : public VNVisitor {
// rst), so we use a hash map to get the unique SchedSenVertex. (Note: This creates
// separate vertices for ET_CHANGED and ET_HYBRID over the same expression, but that is
// OK for now).
auto it = m_senVertices.find(*senItemp);
const auto pair = m_senVertices.emplace(*senItemp, nullptr);
// If it does not exist, create it
if (it == m_senVertices.end()) {
if (pair.second) {
// Create the vertex
SchedSenVertex* const vtxp = new SchedSenVertex{m_graphp, senItemp};
@ -168,11 +167,11 @@ class SchedGraphBuilder final : public VNVisitor {
});
// Store back to hash map so we can find it next time
it = m_senVertices.emplace(*senItemp, vtxp).first;
pair.first->second = vtxp;
}
// Cache sensitivity vertex
senItemp->user1p(it->second);
senItemp->user1p(pair.first->second);
}
return senItemp->user1u().to<SchedSenVertex*>();
}

View File

@ -96,8 +96,8 @@ class SenExprBuilder final {
AstNode* scopeExprp = exprp;
if (AstVarRef* const refp = VN_CAST(exprp, VarRef)) scopeExprp = refp->varScopep();
// Create the 'previous value' variable
auto it = m_prev.find(*scopeExprp);
if (it == m_prev.end()) {
const auto pair = m_prev.emplace(*scopeExprp, nullptr);
if (pair.second) {
AstVarScope* prevp;
if (m_scopep->isTop()) {
// For readability, use the scoped signal name if the trigger is a simple AstVarRef
@ -118,7 +118,7 @@ class SenExprBuilder final {
prevp = new AstVarScope{flp, m_scopep, varp};
m_scopep->addVarsp(prevp);
}
it = m_prev.emplace(*scopeExprp, prevp).first;
pair.first->second = prevp;
// Add the initializer init
AstAssign* const initp = new AstAssign{flp, new AstVarRef{flp, prevp, VAccess::WRITE},
@ -126,7 +126,7 @@ class SenExprBuilder final {
m_inits.push_back(initp);
}
AstVarScope* const prevp = it->second;
AstVarScope* const prevp = pair.first->second;
const auto wrPrev = [=]() { return new AstVarRef{flp, prevp, VAccess::WRITE}; };

View File

@ -310,7 +310,7 @@ private:
UASSERT_OBJ(varp->attrSplitVar(), varp, " no split_var metacomment");
const MapIt it = m_map.find(varp);
if (it == m_map.end()) return false; // Not registered
const bool ok = m_map[varp].insert(ref).second;
const bool ok = it->second.insert(ref).second;
return ok;
}

View File

@ -71,12 +71,10 @@ public:
if (m_symPrefix != "") os << " symPrefix=" << m_symPrefix;
os << " n=" << nodep();
os << '\n';
if (VL_UNCOVERABLE(doneSymsr.find(this) != doneSymsr.end())) {
if (VL_UNCOVERABLE(!doneSymsr.insert(this).second)) {
os << indent << "| ^ duplicate, so no children printed\n"; // LCOV_EXCL_LINE
} else {
doneSymsr.insert(this);
for (IdNameMap::const_iterator it = m_idNameMap.begin(); it != m_idNameMap.end();
++it) {
for (auto it = m_idNameMap.begin(); it != m_idNameMap.end(); ++it) {
if (numLevels >= 1) {
it->second->dumpIterate(os, doneSymsr, indent + "| ", numLevels - 1,
it->first);

View File

@ -85,10 +85,8 @@ public:
// METHODS
void addVertex(const T_Key& key) {
const auto itr = m_vertices.find(key);
UASSERT(itr == m_vertices.end(), "Vertex already exists with same key");
Vertex* v = new Vertex{this, key};
m_vertices[key] = v;
const bool newEntry = m_vertices.emplace(key, new Vertex{this, key}).second;
UASSERT(newEntry, "Vertex already exists with same key");
}
// For purposes of TSP, we are using non-directional graphs.

View File

@ -971,19 +971,21 @@ private:
// Only create one DPI Import prototype or DPI Export entry point for each unique cname as
// it is illegal for the user to attach multiple tasks with different signatures to one DPI
// cname.
const auto it = m_dpiNames.find(nodep->cname());
if (it == m_dpiNames.end()) {
const auto pair = m_dpiNames.emplace(std::piecewise_construct, //
std::forward_as_tuple(nodep->cname()),
std::forward_as_tuple(nodep, signature, nullptr));
if (pair.second) {
// First time encountering this cname. Create Import prototype / Export entry point
AstCFunc* const funcp = nodep->dpiExport() ? makeDpiExportDispatcher(nodep, rtnvarp)
: makeDpiImportPrototype(nodep, rtnvarp);
m_dpiNames.emplace(nodep->cname(), std::make_tuple(nodep, signature, funcp));
std::get<2>(pair.first->second) = funcp;
return funcp;
} else {
// Seen this cname import before. Check if it's the same prototype.
const AstNodeFTask* firstNodep;
string firstSignature;
AstCFunc* firstFuncp;
std::tie(firstNodep, firstSignature, firstFuncp) = it->second;
std::tie(firstNodep, firstSignature, firstFuncp) = pair.first->second;
if (signature != firstSignature) {
// Different signature, so error.
nodep->v3error("Duplicate declaration of DPI function with different signature: '"
@ -1779,16 +1781,13 @@ void V3Task::taskConnectWrap(AstNodeFTaskRef* nodep, const V3TaskConnects& tconn
// Make wrapper name such that is same iff same args are defaulted
std::string newname = nodep->name() + "__Vtcwrap";
for (const AstVar* varp : argWrap) newname += "_" + cvtToStr(varp->pinNum());
const auto namekey = std::make_pair(nodep->taskp(), newname);
auto& wrapMapr = statep->wrapMap();
const auto it = wrapMapr.find(namekey);
AstNodeFTask* newTaskp;
if (it != wrapMapr.end()) {
newTaskp = it->second;
} else {
newTaskp = taskConnectWrapNew(nodep->taskp(), newname, tconnects, argWrap);
wrapMapr.emplace(namekey, newTaskp);
const auto pair = statep->wrapMap().emplace(std::piecewise_construct,
std::forward_as_tuple(nodep->taskp(), newname),
std::forward_as_tuple(nullptr));
if (pair.second) {
pair.first->second = taskConnectWrapNew(nodep->taskp(), newname, tconnects, argWrap);
}
AstNodeFTask* const newTaskp = pair.first->second;
// Remove the defaulted arguments from original outside call
for (const auto& tconnect : tconnects) {

View File

@ -549,16 +549,11 @@ class TristateVisitor final : public TristateBaseVisitor {
}
void mapInsertLhsVarRef(AstVarRef* nodep) {
AstVar* const key = nodep->varp();
const auto it = m_lhsmap.find(key);
UINFO(9, " mapInsertLhsVarRef " << nodep << endl);
if (it == m_lhsmap.end()) { // Not found
RefStrengthVec* const refsp = new RefStrengthVec;
refsp->push_back(RefStrength{nodep, m_currentStrength});
m_lhsmap.emplace(key, refsp);
} else {
it->second->push_back(RefStrength{nodep, m_currentStrength});
}
AstVar* const key = nodep->varp();
const auto pair = m_lhsmap.emplace(key, nullptr);
if (pair.second) pair.first->second = new RefStrengthVec;
pair.first->second->push_back(RefStrength{nodep, m_currentStrength});
}
AstNodeExpr* newEnableDeposit(AstSel* selp, AstNodeExpr* enp) {

View File

@ -2296,15 +2296,14 @@ private:
}
num.opAssign(constp->num());
// Look for duplicates
if (inits.find(num) != inits.end()) { // IEEE says illegal
const AstNode* const otherp = inits.find(num)->second;
const auto pair = inits.emplace(num, itemp);
if (!pair.second) { // IEEE says illegal
const AstNode* const otherp = pair.first->second;
itemp->v3error("Overlapping enumeration value: "
<< itemp->prettyNameQ() << '\n'
<< itemp->warnContextPrimary() << '\n'
<< otherp->warnOther() << "... Location of original declaration\n"
<< otherp->warnContextSecondary());
} else {
inits.emplace(num, itemp);
}
num.opAdd(one, constp->num());
}
@ -3985,12 +3984,10 @@ private:
= VN_CAST(patp->keyp(), NodeDType)) {
// data_type: default_value
const string dtype = nodedtypep->dtypep()->prettyDTypeName();
auto it = dtypemap.find(dtype);
if (it == dtypemap.end()) {
dtypemap.emplace(dtype, patp);
} else {
const auto pair = dtypemap.emplace(dtype, patp);
if (!pair.second) {
// Override stored default_value
it->second = patp->cloneTree(false);
pair.first->second = patp->cloneTree(false);
}
} else {
// Undefined pattern
@ -7192,8 +7189,10 @@ private:
}
AstVar* dimensionVarp(AstNodeDType* nodep, VAttrType attrType, uint32_t msbdim) {
// Return a variable table which has specified dimension properties for this variable
const auto pos = m_tableMap.find(std::make_pair(nodep, attrType));
if (pos != m_tableMap.end()) return pos->second;
const auto pair = m_tableMap.emplace(std::piecewise_construct, //
std::forward_as_tuple(nodep, attrType),
std::forward_as_tuple(nullptr));
if (pair.second) {
AstNodeArrayDType* const vardtypep
= new AstUnpackArrayDType{nodep->fileline(), nodep->findSigned32DType(),
new AstRange(nodep->fileline(), msbdim, 0)};
@ -7214,8 +7213,9 @@ private:
initp->addValuep(dimensionValue(nodep->fileline(), nodep, attrType, i));
}
userIterate(varp, nullptr); // May have already done $unit so must do this var
m_tableMap.emplace(std::make_pair(nodep, attrType), varp);
return varp;
pair.first->second = varp;
}
return pair.first->second;
}
uint64_t enumMaxValue(const AstNode* errNodep, const AstEnumDType* adtypep) {
// Most enums unless overridden are 32 bits, so we size array
@ -7237,11 +7237,10 @@ private:
}
return maxval;
}
AstVar* enumVarp(AstEnumDType* nodep, VAttrType attrType, bool assoc, uint32_t msbdim) {
AstVar* enumVarp(AstEnumDType* const nodep, VAttrType attrType, bool assoc, uint32_t msbdim) {
// Return a variable table which has specified dimension properties for this variable
const auto& tableMapr = nodep->tableMap();
const auto pos = tableMapr.find(attrType);
if (pos != tableMapr.end()) return pos->second;
const auto pair = nodep->tableMap().emplace(attrType, nullptr);
if (pair.second) {
UINFO(9, "Construct Venumtab attr=" << attrType.ascii() << " assoc=" << assoc
<< " max=" << msbdim << " for " << nodep << endl);
AstNodeDType* basep;
@ -7280,7 +7279,8 @@ private:
if (attrType == VAttrType::ENUM_NAME) {
initp->defaultp(new AstConst{nodep->fileline(), AstConst::String{}, ""});
} else if (attrType == VAttrType::ENUM_NEXT || attrType == VAttrType::ENUM_PREV) {
initp->defaultp(new AstConst{nodep->fileline(), V3Number{nodep, nodep->width(), 0}});
initp->defaultp(
new AstConst{nodep->fileline(), V3Number{nodep, nodep->width(), 0}});
} else if (attrType == VAttrType::ENUM_VALID) {
initp->defaultp(new AstConst{nodep->fileline(), AstConst::BitFalse{}});
} else {
@ -7300,9 +7300,11 @@ private:
UASSERT_OBJ(vconstp, nodep, "Enum item without constified value");
const uint64_t i = vconstp->toUQuad();
if (attrType == VAttrType::ENUM_NAME) {
values[i] = new AstConst{nodep->fileline(), AstConst::String{}, itemp->name()};
values[i]
= new AstConst{nodep->fileline(), AstConst::String{}, itemp->name()};
} else if (attrType == VAttrType::ENUM_NEXT) {
values[i] = (nextp ? nextp : firstp)->valuep()->cloneTree(false); // A const
values[i]
= (nextp ? nextp : firstp)->valuep()->cloneTree(false); // A const
} else if (attrType == VAttrType::ENUM_PREV) {
values[i] = prevp->valuep()->cloneTree(false); // A const
} else if (attrType == VAttrType::ENUM_VALID) {
@ -7323,8 +7325,9 @@ private:
}
}
userIterate(varp, nullptr); // May have already done $unit so must do this var
nodep->tableMap().emplace(attrType, varp);
return varp;
pair.first->second = varp;
}
return pair.first->second;
}
PatVecMap patVectorMap(AstPattern* nodep, const VNumRange& range) {
@ -7340,10 +7343,9 @@ private:
<< patp->keyp()->prettyTypeName());
}
}
if (patmap.find(element) != patmap.end()) {
const bool newEntry = patmap.emplace(element, patp).second;
if (!newEntry) {
patp->v3error("Assignment pattern key used multiple times: " << element);
} else {
patmap.emplace(element, patp);
}
element += range.leftToRightInc();
}

View File

@ -139,18 +139,10 @@ public:
}
VlcPoint& pointNumber(uint64_t num) { return m_points[num]; }
uint64_t findAddPoint(const string& name, uint64_t count) {
uint64_t pointnum;
const auto iter = m_nameMap.find(name);
if (iter != m_nameMap.end()) {
pointnum = iter->second;
const auto pair = m_nameMap.emplace(name, m_numPoints);
if (pair.second) m_points.emplace_back(name, m_numPoints++);
const uint64_t pointnum = pair.first->second;
m_points[pointnum].countInc(count);
} else {
pointnum = m_numPoints++;
VlcPoint point{name, pointnum};
point.countInc(count);
m_points.push_back(point);
m_nameMap.emplace(point.name(), point.pointNum());
}
return pointnum;
}
};

View File

@ -36,7 +36,7 @@ private:
using PointsSet = std::set<const VlcPoint*>;
// MEMBERS
int m_lineno; ///< Line number
const int m_lineno; ///< Line number
uint64_t m_count = 0; ///< Count
bool m_ok = false; ///< Coverage is above threshold
PointsSet m_points; // Points on this line
@ -94,9 +94,7 @@ public:
// METHODS
void lineIncCount(int lineno, uint64_t count, bool ok, const VlcPoint* pointp) {
auto lit = m_lines.find(lineno);
if (lit == m_lines.end()) lit = m_lines.emplace(lineno, VlcSourceCount{lineno}).first;
VlcSourceCount& sc = lit->second;
VlcSourceCount& sc = m_lines.emplace(lineno, lineno).first->second;
sc.incCount(count, ok);
sc.insertPoint(pointp);
}