diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 4fd19133c..37b16324e 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -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 { diff --git a/src/V3Config.cpp b/src/V3Config.cpp index 82aea8a9f..69a55e7fc 100644 --- a/src/V3Config.cpp +++ b/src/V3Config.cpp @@ -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) { diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index 4d04e00cc..c1a5bed9f 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -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 m_varnames; // Uniquification of inserted variable names + // Uniquification of inserted variable names + std::unordered_map m_varnames; string m_beginHier; // AstBegin hier name for user coverage points std::unordered_map 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; } diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 35f18d0b0..0b4450376 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -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; } diff --git a/src/V3DupFinder.cpp b/src/V3DupFinder.cpp index 58a889931..c58859b0a 100644 --- a/src/V3DupFinder.cpp +++ b/src/V3DupFinder.cpp @@ -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; diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 79c12b996..fc197d784 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -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) { diff --git a/src/V3File.cpp b/src/V3File.cpp index 97a26d572..a51372f8f 100644 --- a/src/V3File.cpp +++ b/src/V3File.cpp @@ -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) diff --git a/src/V3Global.cpp b/src/V3Global.cpp index 905b2e63d..454787fe9 100644 --- a/src/V3Global.cpp +++ b/src/V3Global.cpp @@ -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; } diff --git a/src/V3HierBlock.cpp b/src/V3HierBlock.cpp index e59a8cb36..294613e18 100644 --- a/src/V3HierBlock.cpp +++ b/src/V3HierBlock.cpp @@ -306,12 +306,12 @@ public: //###################################################################### void V3HierBlockPlan::add(const AstNodeModule* modp, const std::vector& 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; } } diff --git a/src/V3Life.cpp b/src/V3Life.cpp index 84ee05d60..821365623 100644 --- a/src/V3Life.cpp +++ b/src/V3Life.cpp @@ -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 diff --git a/src/V3LinkLevel.cpp b/src/V3LinkLevel.cpp index 9c0500239..f784f0707 100644 --- a/src/V3LinkLevel.cpp +++ b/src/V3LinkLevel.cpp @@ -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()); } } } diff --git a/src/V3Order.cpp b/src/V3Order.cpp index 3c8a3b86f..415505c0d 100644 --- a/src/V3Order.cpp +++ b/src/V3Order.cpp @@ -495,14 +495,9 @@ public: V3List& 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()); diff --git a/src/V3Param.cpp b/src/V3Param.cpp index dc7aed79c..53c01c77c 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -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(); diff --git a/src/V3Partition.h b/src/V3Partition.h index 5aba6b009..72d4e5b92 100644 --- a/src/V3Partition.h +++ b/src/V3Partition.h @@ -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; } }; diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 18eb63df2..755e13fb4 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -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; - AstCDType* newp = new AstCDType{fl, name}; - v3Global.rootp()->typeTablep()->addTypesp(newp); - m_randcDtypes.emplace(name, newp); - return newp; + const auto pair = m_randcDtypes.emplace(name, nullptr); + if (pair.second) { + AstCDType* newp = new AstCDType{fl, name}; + v3Global.rootp()->typeTablep()->addTypesp(newp); + pair.first->second = newp; + } + return pair.first->second; } AstVar* newRandcVarsp(AstVar* varp) { diff --git a/src/V3SchedPartition.cpp b/src/V3SchedPartition.cpp index a5cbfd3c9..e381b2727 100644 --- a/src/V3SchedPartition.cpp +++ b/src/V3SchedPartition.cpp @@ -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(); } diff --git a/src/V3SenExprBuilder.h b/src/V3SenExprBuilder.h index 3928c7ea5..70a981696 100644 --- a/src/V3SenExprBuilder.h +++ b/src/V3SenExprBuilder.h @@ -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}; }; diff --git a/src/V3SplitVar.cpp b/src/V3SplitVar.cpp index 54e6d5e76..adfc8e8c6 100644 --- a/src/V3SplitVar.cpp +++ b/src/V3SplitVar.cpp @@ -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; } diff --git a/src/V3SymTable.h b/src/V3SymTable.h index f1ba43274..3fcdabb90 100644 --- a/src/V3SymTable.h +++ b/src/V3SymTable.h @@ -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); diff --git a/src/V3TSP.cpp b/src/V3TSP.cpp index 583db4ab4..916e95d0d 100644 --- a/src/V3TSP.cpp +++ b/src/V3TSP.cpp @@ -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. diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 0bfa6cea0..9bf42e04d 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -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) { diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index a584d1748..444a49ebc 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -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) { diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 57804cfb5..8c653c2eb 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -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,30 +7189,33 @@ 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; - AstNodeArrayDType* const vardtypep - = new AstUnpackArrayDType{nodep->fileline(), nodep->findSigned32DType(), - new AstRange(nodep->fileline(), msbdim, 0)}; - AstInitArray* const initp = new AstInitArray{nodep->fileline(), vardtypep, nullptr}; - v3Global.rootp()->typeTablep()->addTypesp(vardtypep); - AstVar* const varp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, - "__Vdimtab_" + VString::downcase(attrType.ascii()) - + cvtToStr(m_dtTables++), - vardtypep}; - varp->isConst(true); - varp->isStatic(true); - varp->valuep(initp); - // Add to root, as don't know module we are in, and aids later structure sharing - v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(varp); - // Element 0 is a non-index and has speced values - initp->addValuep(dimensionValue(nodep->fileline(), nodep, attrType, 0)); - for (unsigned i = 1; i < msbdim + 1; ++i) { - initp->addValuep(dimensionValue(nodep->fileline(), nodep, attrType, i)); + 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)}; + AstInitArray* const initp = new AstInitArray{nodep->fileline(), vardtypep, nullptr}; + v3Global.rootp()->typeTablep()->addTypesp(vardtypep); + AstVar* const varp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, + "__Vdimtab_" + VString::downcase(attrType.ascii()) + + cvtToStr(m_dtTables++), + vardtypep}; + varp->isConst(true); + varp->isStatic(true); + varp->valuep(initp); + // Add to root, as don't know module we are in, and aids later structure sharing + v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(varp); + // Element 0 is a non-index and has speced values + initp->addValuep(dimensionValue(nodep->fileline(), nodep, attrType, 0)); + for (unsigned i = 1; i < msbdim + 1; ++i) { + initp->addValuep(dimensionValue(nodep->fileline(), nodep, attrType, i)); + } + userIterate(varp, nullptr); // May have already done $unit so must do this var + pair.first->second = varp; } - userIterate(varp, nullptr); // May have already done $unit so must do this var - m_tableMap.emplace(std::make_pair(nodep, attrType), varp); - return 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,94 +7237,97 @@ 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; - UINFO(9, "Construct Venumtab attr=" << attrType.ascii() << " assoc=" << assoc - << " max=" << msbdim << " for " << nodep << endl); - AstNodeDType* basep; - if (attrType == VAttrType::ENUM_NAME) { - basep = nodep->findStringDType(); - } else if (attrType == VAttrType::ENUM_VALID) { - // TODO in theory we could bit-pack the bits in the table, but - // would require additional operations to extract, so only - // would be worth it for larger tables which perhaps could be - // better handled with equation generation? - basep = nodep->findBitDType(); - } else { - basep = nodep->dtypep(); - } - AstNodeDType* vardtypep; - if (assoc) { - vardtypep = new AstAssocArrayDType{nodep->fileline(), basep, nodep}; - } else { - vardtypep = new AstUnpackArrayDType{nodep->fileline(), basep, - new AstRange(nodep->fileline(), msbdim, 0)}; - } - AstInitArray* const initp = new AstInitArray{nodep->fileline(), vardtypep, nullptr}; - v3Global.rootp()->typeTablep()->addTypesp(vardtypep); - AstVar* const varp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, - "__Venumtab_" + VString::downcase(attrType.ascii()) - + cvtToStr(m_dtTables++), - vardtypep}; - varp->lifetime(VLifetime::STATIC); - varp->isConst(true); - varp->isStatic(true); - varp->valuep(initp); - // Add to root, as don't know module we are in, and aids later structure sharing - v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(varp); + 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; + if (attrType == VAttrType::ENUM_NAME) { + basep = nodep->findStringDType(); + } else if (attrType == VAttrType::ENUM_VALID) { + // TODO in theory we could bit-pack the bits in the table, but + // would require additional operations to extract, so only + // would be worth it for larger tables which perhaps could be + // better handled with equation generation? + basep = nodep->findBitDType(); + } else { + basep = nodep->dtypep(); + } + AstNodeDType* vardtypep; + if (assoc) { + vardtypep = new AstAssocArrayDType{nodep->fileline(), basep, nodep}; + } else { + vardtypep = new AstUnpackArrayDType{nodep->fileline(), basep, + new AstRange(nodep->fileline(), msbdim, 0)}; + } + AstInitArray* const initp = new AstInitArray{nodep->fileline(), vardtypep, nullptr}; + v3Global.rootp()->typeTablep()->addTypesp(vardtypep); + AstVar* const varp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, + "__Venumtab_" + VString::downcase(attrType.ascii()) + + cvtToStr(m_dtTables++), + vardtypep}; + varp->lifetime(VLifetime::STATIC); + varp->isConst(true); + varp->isStatic(true); + varp->valuep(initp); + // Add to root, as don't know module we are in, and aids later structure sharing + v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(varp); - // Default for all unspecified values - 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}}); - } else if (attrType == VAttrType::ENUM_VALID) { - initp->defaultp(new AstConst{nodep->fileline(), AstConst::BitFalse{}}); - } else { - nodep->v3fatalSrc("Bad case"); - } + // Default for all unspecified values + 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}}); + } else if (attrType == VAttrType::ENUM_VALID) { + initp->defaultp(new AstConst{nodep->fileline(), AstConst::BitFalse{}}); + } else { + nodep->v3fatalSrc("Bad case"); + } - // Find valid values and populate - UASSERT_OBJ(nodep->itemsp(), nodep, "enum without items"); - std::map values; - { - AstEnumItem* const firstp = nodep->itemsp(); - const AstEnumItem* prevp = firstp; // Prev must start with last item - while (prevp->nextp()) prevp = VN_AS(prevp->nextp(), EnumItem); - for (AstEnumItem* itemp = firstp; itemp;) { - AstEnumItem* const nextp = VN_AS(itemp->nextp(), EnumItem); - const AstConst* const vconstp = VN_AS(itemp->valuep(), Const); - 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()}; - } else if (attrType == VAttrType::ENUM_NEXT) { - 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) { - values[i] = new AstConst{nodep->fileline(), AstConst::BitTrue{}}; - } else { - nodep->v3fatalSrc("Bad case"); + // Find valid values and populate + UASSERT_OBJ(nodep->itemsp(), nodep, "enum without items"); + std::map values; + { + AstEnumItem* const firstp = nodep->itemsp(); + const AstEnumItem* prevp = firstp; // Prev must start with last item + while (prevp->nextp()) prevp = VN_AS(prevp->nextp(), EnumItem); + for (AstEnumItem* itemp = firstp; itemp;) { + AstEnumItem* const nextp = VN_AS(itemp->nextp(), EnumItem); + const AstConst* const vconstp = VN_AS(itemp->valuep(), Const); + 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()}; + } else if (attrType == VAttrType::ENUM_NEXT) { + 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) { + values[i] = new AstConst{nodep->fileline(), AstConst::BitTrue{}}; + } else { + nodep->v3fatalSrc("Bad case"); + } + prevp = itemp; + itemp = nextp; } - prevp = itemp; - itemp = nextp; } - } - // Add all specified values to table - if (assoc) { - for (const auto& itr : values) initp->addIndexValuep(itr.first, itr.second); - } else { - for (uint64_t i = 0; i < (msbdim + 1); ++i) { - if (values[i]) initp->addIndexValuep(i, values[i]); + // Add all specified values to table + if (assoc) { + for (const auto& itr : values) initp->addIndexValuep(itr.first, itr.second); + } else { + for (uint64_t i = 0; i < (msbdim + 1); ++i) { + if (values[i]) initp->addIndexValuep(i, values[i]); + } } + userIterate(varp, nullptr); // May have already done $unit so must do this var + pair.first->second = varp; } - userIterate(varp, nullptr); // May have already done $unit so must do this var - nodep->tableMap().emplace(attrType, varp); - return 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(); } diff --git a/src/VlcPoint.h b/src/VlcPoint.h index 5c51b7adf..a4618daea 100644 --- a/src/VlcPoint.h +++ b/src/VlcPoint.h @@ -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; - 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()); - } + 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); return pointnum; } }; diff --git a/src/VlcSource.h b/src/VlcSource.h index 523b60861..74584be63 100644 --- a/src/VlcSource.h +++ b/src/VlcSource.h @@ -36,7 +36,7 @@ private: using PointsSet = std::set; // 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); }