diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aec91fd2299..64cf30f8413 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -383,40 +383,6 @@ jobs: - name: build run: cmake --build out - # Duplicates build-asan. Please keep in sync - build-cxx20: - name: c++20 - # Make sure we can still build on older Ubuntu - runs-on: ubuntu-22.04 - env: - CC: "gcc" - CXX: "g++" - steps: - - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - uses: actions/checkout@v4 - with: - submodules: true - - name: install ninja - run: sudo apt-get install ninja-build - - name: install v8 - run: | - npm install jsvu -g - jsvu --os=default --engines=v8 - - name: install Python dev dependencies - run: pip3 install -r requirements-dev.txt - - name: cmake - run: | - mkdir -p out - cmake -S . -B out -G Ninja -DCMAKE_INSTALL_PREFIX=out/install -DCMAKE_C_COMPILER="$CC" -DCMAKE_CXX_COMPILER="$CXX" -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=20 - - name: build - run: cmake --build out - - name: test - run: | - python check.py --binaryen-bin=out/bin lit - python check.py --binaryen-bin=out/bin gtest - # Ensures we can build in no-asserts mode (just building). build-noasserts: name: noasserts diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a097fe7bfc..ae653bd4b71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ include(GNUInstallDirs) # The C++ standard whose features are required to build Binaryen. # Keep in sync with scripts/test/shared.py cxx_standard # The if condition allows embedding in a project with a higher default C++ standard set -set(REQUIRED_CXX_STANDARD 17) +set(REQUIRED_CXX_STANDARD 20) if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD ${REQUIRED_CXX_STANDARD}) elseif(CMAKE_CXX_STANDARD LESS ${REQUIRED_CXX_STANDARD}) diff --git a/README.md b/README.md index d1897f1b1d4..8198b49cc76 100644 --- a/README.md +++ b/README.md @@ -412,7 +412,9 @@ After that you can build with CMake: cmake . && make ``` -A C++17 compiler is required. On macOS, you need to install `cmake`, for example, via `brew install cmake`. Note that you can also use `ninja` as your generator: `cmake -G Ninja . && ninja`. +A C++20 compiler is required. On macOS, you need to install `cmake`, for +example, via `brew install cmake`. Note that you can also use `ninja` as your +generator: `cmake -G Ninja . && ninja`. To avoid the gtest dependency, you can pass `-DBUILD_TESTS=OFF` to cmake. diff --git a/scripts/test/shared.py b/scripts/test/shared.py index dff00d50fd2..3d36fb35fa1 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -27,7 +27,7 @@ # The C++ standard whose features are required to build Binaryen. # Keep in sync with CMakeLists.txt CXX_STANDARD -cxx_standard = 17 +cxx_standard = 20 def parse_args(args): diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 702346a6be1..d7dcb8224f0 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -5816,7 +5816,7 @@ void BinaryenClearPassArguments(void) { globalPassOptions.arguments.clear(); } bool BinaryenHasPassToSkip(const char* pass) { assert(pass); - return globalPassOptions.passesToSkip.count(pass); + return globalPassOptions.passesToSkip.contains(pass); } void BinaryenAddPassToSkip(const char* pass) { @@ -5873,7 +5873,7 @@ void BinaryenModuleRunPasses(BinaryenModuleRef module, passRunner.options = globalPassOptions; for (BinaryenIndex i = 0; i < numPasses; i++) { passRunner.add(passes[i], - globalPassOptions.arguments.count(passes[i]) > 0 + globalPassOptions.arguments.contains(passes[i]) ? globalPassOptions.arguments[passes[i]] : std::optional()); } @@ -6125,7 +6125,7 @@ void BinaryenFunctionRunPasses(BinaryenFunctionRef func, passRunner.options = globalPassOptions; for (BinaryenIndex i = 0; i < numPasses; i++) { passRunner.add(passes[i], - globalPassOptions.arguments.count(passes[i]) > 0 + globalPassOptions.arguments.contains(passes[i]) ? globalPassOptions.arguments[passes[i]] : std::optional()); } diff --git a/src/cfg/Relooper.cpp b/src/cfg/Relooper.cpp index c681094cf08..29471426616 100644 --- a/src/cfg/Relooper.cpp +++ b/src/cfg/Relooper.cpp @@ -40,7 +40,7 @@ namespace CFG { template static bool contains(const T& container, const U& contained) { - return !!container.count(contained); + return container.contains(contained); } // Rendering utilities @@ -667,7 +667,7 @@ struct Optimizer : public RelooperRecursor { // Add a branch to the target (which may be the unchanged original) in // the set of new branches. If it's a replacement, it may collide, and // we need to merge. - if (NewBranchesOut.count(Replacement)) { + if (NewBranchesOut.contains(Replacement)) { #if RELOOPER_OPTIMIZER_DEBUG std::cout << " merge\n"; #endif @@ -915,7 +915,7 @@ struct Optimizer : public RelooperRecursor { return false; } for (auto& [ABlock, ABranch] : A->BranchesOut) { - if (B->BranchesOut.count(ABlock) == 0) { + if (!B->BranchesOut.contains(ABlock)) { return false; } auto* BBranch = B->BranchesOut[ABlock]; @@ -1578,7 +1578,7 @@ void Relooper::Calculate(Block* Entry) { // jumped to forward, without using the label variable bool Checked = false; for (auto* Entry : *Entries) { - if (InitialEntries.count(Entry)) { + if (InitialEntries.contains(Entry)) { Checked = true; break; } diff --git a/src/cfg/cfg-traversal.h b/src/cfg/cfg-traversal.h index d156c7b1c9e..2afc76a6835 100644 --- a/src/cfg/cfg-traversal.h +++ b/src/cfg/cfg-traversal.h @@ -616,7 +616,7 @@ struct CFGWalker : public PostWalker { queue.erase(iter); alive.insert(curr); for (auto* out : curr->out) { - if (!alive.count(out)) { + if (!alive.contains(out)) { queue.insert(out); } } @@ -626,7 +626,7 @@ struct CFGWalker : public PostWalker { void unlinkDeadBlocks(std::unordered_set alive) { for (auto& block : basicBlocks) { - if (!alive.count(block.get())) { + if (!alive.contains(block.get())) { block->in.clear(); block->out.clear(); continue; @@ -634,13 +634,13 @@ struct CFGWalker : public PostWalker { block->in.erase(std::remove_if(block->in.begin(), block->in.end(), [&alive](BasicBlock* other) { - return !alive.count(other); + return !alive.contains(other); }), block->in.end()); block->out.erase(std::remove_if(block->out.begin(), block->out.end(), [&alive](BasicBlock* other) { - return !alive.count(other); + return !alive.contains(other); }), block->out.end()); } @@ -664,17 +664,17 @@ struct CFGWalker : public PostWalker { std::cout << "<==\nCFG [" << message << "]:\n"; generateDebugIds(); for (auto& block : basicBlocks) { - assert(debugIds.count(block.get()) > 0); + assert(debugIds.contains(block.get())); std::cout << " block " << debugIds[block.get()] << " (" << block.get() << "):\n"; block->contents.dump(static_cast(this)->getFunction()); for (auto& in : block->in) { - assert(debugIds.count(in) > 0); + assert(debugIds.contains(in)); assert(std::find(in->out.begin(), in->out.end(), block.get()) != in->out.end()); // must be a parallel link back } for (auto& out : block->out) { - assert(debugIds.count(out) > 0); + assert(debugIds.contains(out)); std::cout << " out: " << debugIds[out] << "\n"; assert(std::find(out->in.begin(), out->in.end(), block.get()) != out->in.end()); // must be a parallel link back diff --git a/src/cfg/liveness-traversal.h b/src/cfg/liveness-traversal.h index 650ee4f47fb..49e8532220c 100644 --- a/src/cfg/liveness-traversal.h +++ b/src/cfg/liveness-traversal.h @@ -222,7 +222,7 @@ struct LivenessWalker : public CFGWalker { // keep working while stuff is flowing std::unordered_set queue; for (auto& curr : CFGWalker::basicBlocks) { - if (liveBlocks.count(curr.get()) == 0) { + if (!liveBlocks.contains(curr.get())) { continue; // ignore dead blocks } queue.insert(curr.get()); diff --git a/src/ir/ExpressionAnalyzer.cpp b/src/ir/ExpressionAnalyzer.cpp index a6f11a7c4be..477c4bfc526 100644 --- a/src/ir/ExpressionAnalyzer.cpp +++ b/src/ir/ExpressionAnalyzer.cpp @@ -353,7 +353,7 @@ struct Hasher { // (block $x (br $x)) // (block $y (br $y)) // But if the name is not known to us, hash the absolute one. - if (!internalNames.count(curr)) { + if (!internalNames.contains(curr)) { rehash(digest, 1); // Perform the same hashing as a generic name. visitNonScopeName(curr); diff --git a/src/ir/LocalGraph.cpp b/src/ir/LocalGraph.cpp index 3c764ef3c40..b059fb6fd34 100644 --- a/src/ir/LocalGraph.cpp +++ b/src/ir/LocalGraph.cpp @@ -341,7 +341,7 @@ struct LocalGraphFlower auto index = get->index; // We must never repeat work. - assert(!getSetsMap.count(get)); + assert(!getSetsMap.contains(get)); // Regardless of what we do below, ensure an entry for this get, so that we // know we computed it. @@ -410,7 +410,7 @@ struct LocalGraphFlower auto index = set->index; // We must never repeat work. - assert(!setInfluences.count(set)); + assert(!setInfluences.contains(set)); // In theory we could flow the set forward, but to keep things simple we // reuse the logic for flowing gets backwards: We flow all the gets of the @@ -419,7 +419,7 @@ struct LocalGraphFlower // doing work for local indexes we don't care about. for (auto* get : getsByIndex[index]) { // Don't repeat work. - if (!getSetsMap.count(get)) { + if (!getSetsMap.contains(get)) { computeGetSets(get); } } @@ -632,7 +632,7 @@ void LocalGraph::computeSSAIndexes() { } } -bool LocalGraph::isSSA(Index x) { return SSAIndexes.count(x); } +bool LocalGraph::isSSA(Index x) { return SSAIndexes.contains(x); } // LazyLocalGraph @@ -672,7 +672,7 @@ LazyLocalGraph::~LazyLocalGraph() { void LazyLocalGraph::computeGetSets(LocalGet* get) const { // We must never repeat work. - assert(!getSetsMap.count(get)); + assert(!getSetsMap.contains(get)); if (!flower) { makeFlower(); @@ -682,7 +682,7 @@ void LazyLocalGraph::computeGetSets(LocalGet* get) const { void LazyLocalGraph::computeSetInfluences(LocalSet* set) const { // We must never repeat work. - assert(!setInfluences.count(set)); + assert(!setInfluences.contains(set)); if (!flower) { makeFlower(); @@ -705,7 +705,7 @@ void LazyLocalGraph::computeGetInfluences() const { bool LazyLocalGraph::computeSSA(Index index) const { // We must never repeat work. - assert(!SSAIndexes.count(index)); + assert(!SSAIndexes.contains(index)); if (!flower) { makeFlower(); diff --git a/src/ir/branch-hints.h b/src/ir/branch-hints.h index 2cd13916e94..c5558bec1fc 100644 --- a/src/ir/branch-hints.h +++ b/src/ir/branch-hints.h @@ -39,7 +39,7 @@ inline std::optional get(Expression* expr, Function* func) { inline void set(Expression* expr, std::optional likely, Function* func) { // When we are writing an empty hint, do not create an empty annotation if one // did not exist. - if (!likely && !func->codeAnnotations.count(expr)) { + if (!likely && !func->codeAnnotations.contains(expr)) { return; } func->codeAnnotations[expr].branchLikely = likely; diff --git a/src/ir/branch-utils.h b/src/ir/branch-utils.h index c2f1b2a5b1e..ef39f15727f 100644 --- a/src/ir/branch-utils.h +++ b/src/ir/branch-utils.h @@ -418,7 +418,7 @@ class BranchSeekerCache { } bool hasBranch(Expression* curr, Name target) { - bool result = getBranches(curr).count(target); + bool result = getBranches(curr).contains(target); #if BRANCH_UTILS_DEBUG assert(bresult == BranchSeeker::has(curr, target)); #endif diff --git a/src/ir/debuginfo.h b/src/ir/debuginfo.h index 143675cb3b8..d7293d7f841 100644 --- a/src/ir/debuginfo.h +++ b/src/ir/debuginfo.h @@ -34,7 +34,7 @@ inline void copyOriginalToReplacement(Expression* original, // if there is no debug info we do want to copy, as a replacement operation // suggests the new code plays the same role (it is an optimized version of // the old), but if the code is already annotated, trust that. - if (debugLocations.empty() || debugLocations.count(replacement)) { + if (debugLocations.empty() || debugLocations.contains(replacement)) { return; } diff --git a/src/ir/effects.h b/src/ir/effects.h index ee26be2841c..1e05ab0fb7c 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -385,12 +385,13 @@ class EffectAnalyzer { // write-write, write-read, and read-write conflicts on a local prevent // reordering. for (auto local : localsWritten) { - if (other.localsRead.count(local) || other.localsWritten.count(local)) { + if (other.localsRead.contains(local) || + other.localsWritten.contains(local)) { return true; } } for (auto local : localsRead) { - if (other.localsWritten.count(local)) { + if (other.localsWritten.contains(local)) { return true; } } @@ -401,13 +402,13 @@ class EffectAnalyzer { return true; } for (auto global : globalsWritten) { - if (other.mutableGlobalsRead.count(global) || - other.globalsWritten.count(global)) { + if (other.mutableGlobalsRead.contains(global) || + other.globalsWritten.contains(global)) { return true; } } for (auto global : mutableGlobalsRead) { - if (other.globalsWritten.count(global)) { + if (other.globalsWritten.contains(global)) { return true; } } @@ -568,7 +569,7 @@ class EffectAnalyzer { // expression is not inside a try-catch_all. It is hard to figure out // whether the original try-delegate's body throws or not at this point. if (curr->name.is()) { - if (self->parent.delegateTargets.count(curr->name) && + if (self->parent.delegateTargets.contains(curr->name) && self->parent.tryDepth == 0) { self->parent.throws_ = true; } diff --git a/src/ir/local-graph.h b/src/ir/local-graph.h index e582751fa22..27734301967 100644 --- a/src/ir/local-graph.h +++ b/src/ir/local-graph.h @@ -218,7 +218,7 @@ struct LazyLocalGraph : public LocalGraphBase { if (iter == SSAIndexes.end()) { auto ret = computeSSA(index); // The result must have been memoized. - assert(SSAIndexes.count(index)); + assert(SSAIndexes.contains(index)); return ret; } return iter->second; diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp index 834d990b383..d88f21ee24a 100644 --- a/src/ir/module-splitting.cpp +++ b/src/ir/module-splitting.cpp @@ -422,8 +422,8 @@ void ModuleSplitter::classifyFunctions() { configSecondaryFuncs.insert(funcs.begin(), funcs.end()); } for (auto& func : primary.functions) { - if (func->imported() || !configSecondaryFuncs.count(func->name) || - segmentReferrers.count(func->name)) { + if (func->imported() || !configSecondaryFuncs.contains(func->name) || + segmentReferrers.contains(func->name)) { primaryFuncs.insert(func->name); } else { assert(func->name != primary.start && "The start function must be kept"); @@ -484,7 +484,7 @@ void ModuleSplitter::moveSecondaryFunctions() { for (auto& funcNames : config.secondaryFuncs) { auto secondary = initSecondary(primary); for (auto funcName : funcNames) { - if (allSecondaryFuncs.count(funcName)) { + if (allSecondaryFuncs.contains(funcName)) { auto* func = primary.getFunction(funcName); ModuleUtils::copyFunction(func, *secondary); primary.removeFunction(funcName); @@ -531,7 +531,7 @@ void ModuleSplitter::thunkExportedSecondaryFunctions() { Builder builder(primary); for (auto& ex : primary.exports) { if (ex->kind != ExternalKind::Function || - !allSecondaryFuncs.count(*ex->getInternalName())) { + !allSecondaryFuncs.contains(*ex->getInternalName())) { continue; } Name trampoline = getTrampoline(*ex->getInternalName()); @@ -578,7 +578,7 @@ void ModuleSplitter::indirectReferencesToSecondaryFunctions() { // 1. ref.func's target func is in one of the secondary modules and // 2. the current module is a different module (either the primary module // or a different secondary module) - if (parent.allSecondaryFuncs.count(curr->func) && + if (parent.allSecondaryFuncs.contains(curr->func) && (currModule == &parent.primary || parent.secondaries.at(parent.funcToSecondaryIndex.at(curr->func)) .get() != currModule)) { @@ -632,7 +632,7 @@ void ModuleSplitter::indirectReferencesToSecondaryFunctions() { std::vector relevantRefFuncs; for (auto* refFunc : refFuncs) { assert(refFunc->func == name); - if (!ignore.count(refFunc)) { + if (!ignore.contains(refFunc)) { relevantRefFuncs.push_back(refFunc); } } @@ -656,7 +656,7 @@ void ModuleSplitter::indirectCallsToSecondaryFunctions() { CallIndirector(ModuleSplitter& parent) : parent(parent) {} void visitCall(Call* curr) { // Return if the call's target is not in one of the secondary module. - if (!parent.allSecondaryFuncs.count(curr->target)) { + if (!parent.allSecondaryFuncs.contains(curr->target)) { return; } // Return if the current module is the same module as the call's target, @@ -705,12 +705,12 @@ void ModuleSplitter::exportImportCalledPrimaryFunctions() { : primaryFuncs(primaryFuncs), calledPrimaryToModules(calledPrimaryToModules) {} void visitCall(Call* curr) { - if (primaryFuncs.count(curr->target)) { + if (primaryFuncs.contains(curr->target)) { calledPrimaryToModules[curr->target].insert(getModule()); } } void visitRefFunc(RefFunc* curr) { - if (primaryFuncs.count(curr->func)) { + if (primaryFuncs.contains(curr->func)) { calledPrimaryToModules[curr->func].insert(getModule()); } } @@ -746,7 +746,7 @@ void ModuleSplitter::setupTablePatching() { if (!ref) { return; } - if (!allSecondaryFuncs.count(ref->func)) { + if (!allSecondaryFuncs.contains(ref->func)) { return; } assert(table == tableManager.activeTable->name); @@ -1055,7 +1055,7 @@ void ModuleSplitter::shareImportableItems() { auto getUsingSecondaries = [&](const Name& name, auto UsedNames::* field) { std::vector usingModules; for (size_t i = 0; i < secondaries.size(); ++i) { - if ((secondaryUsed[i].*field).count(name)) { + if ((secondaryUsed[i].*field).contains(name)) { usingModules.push_back(secondaries[i].get()); } } @@ -1073,7 +1073,7 @@ void ModuleSplitter::shareImportableItems() { for (auto& memory : primary.memories) { auto usingSecondaries = getUsingSecondaries(memory->name, &UsedNames::memories); - bool usedInPrimary = primaryUsed.memories.count(memory->name); + bool usedInPrimary = primaryUsed.memories.contains(memory->name); if (!usedInPrimary && usingSecondaries.size() == 1) { auto* secondary = usingSecondaries[0]; @@ -1096,7 +1096,7 @@ void ModuleSplitter::shareImportableItems() { for (auto& table : primary.tables) { auto usingSecondaries = getUsingSecondaries(table->name, &UsedNames::tables); - bool usedInPrimary = primaryUsed.tables.count(table->name); + bool usedInPrimary = primaryUsed.tables.contains(table->name); if (!usedInPrimary && usingSecondaries.size() == 1) { auto* secondary = usingSecondaries[0]; @@ -1135,7 +1135,7 @@ void ModuleSplitter::shareImportableItems() { auto usingSecondaries = getUsingSecondaries(global->name, &UsedNames::globals); - bool inPrimary = primaryUsed.globals.count(global->name); + bool inPrimary = primaryUsed.globals.contains(global->name); if (!inPrimary && usingSecondaries.empty()) { // It's not used anywhere, so delete it. Unlike other unused module items @@ -1183,7 +1183,7 @@ void ModuleSplitter::shareImportableItems() { // If we are exporting this global from the primary module, we should // create a trampoline here, because we skipped doing it for global // initializers in indirectReferencesToSecondaryFunctions. - if (allSecondaryFuncs.count(ref->func)) { + if (allSecondaryFuncs.contains(ref->func)) { ref->func = getTrampoline(ref->func); } } @@ -1204,7 +1204,7 @@ void ModuleSplitter::shareImportableItems() { std::vector tagsToRemove; for (auto& tag : primary.tags) { auto usingSecondaries = getUsingSecondaries(tag->name, &UsedNames::tags); - bool usedInPrimary = primaryUsed.tags.count(tag->name); + bool usedInPrimary = primaryUsed.tags.contains(tag->name); if (!usedInPrimary && usingSecondaries.size() == 1) { auto* secondary = usingSecondaries[0]; diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp index 5b815eb4fea..01f4e1cbc65 100644 --- a/src/ir/module-utils.cpp +++ b/src/ir/module-utils.cpp @@ -265,7 +265,7 @@ void copyModuleItems(const Module& in, Module& out) { } for (auto& [type, names] : in.typeNames) { - if (!out.typeNames.count(type)) { + if (!out.typeNames.contains(type)) { out.typeNames[type] = names; } } @@ -390,7 +390,7 @@ struct TypeInfos { note(sig.results); } } - bool contains(HeapType type) { return info.count(type); } + bool contains(HeapType type) { return info.contains(type); } }; struct CodeScanner : PostWalker { diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h index 4316c34224f..50b67df7cea 100644 --- a/src/ir/module-utils.h +++ b/src/ir/module-utils.h @@ -315,7 +315,7 @@ struct ParallelFunctionAnalysis { } void doWalkFunction(Function* curr) { - assert(map.count(curr)); + assert(map.contains(curr)); work(curr, map[curr]); } diff --git a/src/ir/names.cpp b/src/ir/names.cpp index f18a08916a8..fc5ed9e58cc 100644 --- a/src/ir/names.cpp +++ b/src/ir/names.cpp @@ -66,7 +66,7 @@ std::string MinifiedNameGenerator::getName() { m *= (validLaterChars.size() + 1); } name = ss.str(); - } while (reserved.count(name)); + } while (reserved.contains(name)); return name; } diff --git a/src/ir/names.h b/src/ir/names.h index c10b70b5231..61fc137f5a8 100644 --- a/src/ir/names.h +++ b/src/ir/names.h @@ -126,7 +126,7 @@ template inline Name getValidNameGivenExisting(Name root, const T& existingNames) { return getValidName( root, - [&](Name test) { return !existingNames.count(test); }, + [&](Name test) { return !existingNames.contains(test); }, existingNames.size()); } diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp index 93abdb80599..905349f1c68 100644 --- a/src/ir/possible-contents.cpp +++ b/src/ir/possible-contents.cpp @@ -939,7 +939,7 @@ struct InfoCollector // If this goes to a public table, then we must root the output, as the // table could contain anything at all, and calling functions there could // return anything at all. - if (shared.publicTables.count(curr->table)) { + if (shared.publicTables.contains(curr->table)) { addRoot(curr); } // TODO: the table identity could also be used here in more ways @@ -1736,8 +1736,8 @@ void TNHOracle::scan(Function* func, // not important in optimized code, as the most refined cast would be // the only one to exist there, so it's ok to keep things simple here. if (getFunction()->isParam(get->index) && type != get->type && - info.castParams.count(get->index) == 0 && - !writtenParams.count(get->index)) { + !info.castParams.contains(get->index) && + !writtenParams.contains(get->index)) { info.castParams[get->index] = type; } } @@ -2940,7 +2940,7 @@ void Flower::flowToTargetsAfterUpdate(LocationIndex locationIndex, void Flower::connectDuringFlow(Location from, Location to) { auto newLink = LocationLink{from, to}; auto newIndexLink = getIndexes(newLink); - if (links.count(newIndexLink) == 0) { + if (!links.contains(newIndexLink)) { // This is a new link. Add it to the known links. links.insert(newIndexLink); @@ -3359,7 +3359,7 @@ void Flower::dump(Location location) { << *loc->expr << " : " << loc->tupleIndex << '\n'; } else if (auto* loc = std::get_if(&location)) { std::cout << " dataloc "; - if (wasm.typeNames.count(loc->type)) { + if (wasm.typeNames.contains(loc->type)) { std::cout << '$' << wasm.typeNames[loc->type].name; } else { std::cout << loc->type << '\n'; diff --git a/src/ir/possible-contents.h b/src/ir/possible-contents.h index a5fdb51edc0..b7270b840d2 100644 --- a/src/ir/possible-contents.h +++ b/src/ir/possible-contents.h @@ -397,7 +397,7 @@ class PossibleContents { if (t.isRef()) { auto h = t.getHeapType(); o << " HT: " << h; - if (wasm && wasm->typeNames.count(h)) { + if (wasm && wasm->typeNames.contains(h)) { o << " $" << wasm->typeNames[h].name; } if (t.isNullable()) { diff --git a/src/ir/table-utils.cpp b/src/ir/table-utils.cpp index 364f7ba324a..cb10aff82b9 100644 --- a/src/ir/table-utils.cpp +++ b/src/ir/table-utils.cpp @@ -53,7 +53,7 @@ std::set getFunctionsNeedingElemDeclare(Module& wasm) { for (auto& kv : analysis.map) { auto& names = kv.second; for (auto name : names) { - if (!tableNames.count(name)) { + if (!tableNames.contains(name)) { ret.insert(name); } } diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp index 9a2ad2bd352..69f29101c86 100644 --- a/src/ir/type-updating.cpp +++ b/src/ir/type-updating.cpp @@ -350,7 +350,7 @@ void GlobalTypeRewriter::mapTypeNamesAndIndices(const TypeMap& oldToNewTypes) { // replaces the old. Rename the old name in a unique way to avoid // confusion in the case that it remains used. auto deduped = Names::getValidName( - names.name, [&](Name test) { return !seenTypeNames.count(test); }); + names.name, [&](Name test) { return !seenTypeNames.contains(test); }); names.name = deduped; // Use `insert` to avoid overwriting the entry for the old type if it has // already appeared as a new type. @@ -451,7 +451,7 @@ void handleNonDefaultableLocals(Function* func, Module& wasm) { Builder builder(wasm); for (auto** getp : FindAllPointers(func->body).list) { auto* get = (*getp)->cast(); - if (badIndexes.count(get->index)) { + if (badIndexes.contains(get->index)) { *getp = fixLocalGet(get, wasm); } } @@ -469,7 +469,7 @@ void handleNonDefaultableLocals(Function* func, Module& wasm) { if (!set->isTee() || set->type == Type::unreachable) { continue; } - if (badIndexes.count(set->index)) { + if (badIndexes.contains(set->index)) { auto type = func->getLocalType(set->index); auto validType = getValidLocalType(type, wasm.features); if (type.isRef()) { @@ -571,7 +571,7 @@ void updateParamTypes(Function* func, for (auto* set : sets.list) { auto index = set->index; - if (func->isParam(index) && !paramFixups.count(index) && + if (func->isParam(index) && !paramFixups.contains(index) && !Type::isSubType(set->value->type, newParamTypes[index])) { paramFixups[index] = Builder::addVar(func, func->getLocalType(index)); } diff --git a/src/pass.h b/src/pass.h index 1f78cf1beb0..f5088e5e7ee 100644 --- a/src/pass.h +++ b/src/pass.h @@ -263,7 +263,7 @@ struct PassOptions { } private: - bool hasArgument(std::string key) { return arguments.count(key) > 0; } + bool hasArgument(std::string key) { return arguments.contains(key); } std::string getArgument(std::string key, std::string errorTextIfMissing) { if (!hasArgument(key)) { diff --git a/src/passes/AbstractTypeRefining.cpp b/src/passes/AbstractTypeRefining.cpp index dae66c2ccc6..b75153e3d2d 100644 --- a/src/passes/AbstractTypeRefining.cpp +++ b/src/passes/AbstractTypeRefining.cpp @@ -128,7 +128,7 @@ struct AbstractTypeRefining : public Pass { for (auto type : subTypes.getSubTypesFirstSort()) { // If any of our subtypes are created, so are we. for (auto subType : subTypes.getImmediateSubTypes(type)) { - if (createdTypesOrSubTypes.count(subType)) { + if (createdTypesOrSubTypes.contains(subType)) { createdTypesOrSubTypes.insert(type); break; } @@ -155,7 +155,7 @@ struct AbstractTypeRefining : public Pass { // in particular). Types abstractTypes; for (auto type : subTypes.types) { - if (createdTypes.count(type) == 0) { + if (!createdTypes.contains(type)) { abstractTypes.insert(type); } } @@ -168,7 +168,7 @@ struct AbstractTypeRefining : public Pass { // chains where we want to refine a type A to a subtype of a subtype of // it. for (auto type : subTypes.getSubTypesFirstSort()) { - if (!abstractTypes.count(type)) { + if (!abstractTypes.contains(type)) { continue; } @@ -183,7 +183,7 @@ struct AbstractTypeRefining : public Pass { // is relevant, if nothing is ever created of the others or their // subtypes. for (auto subType : typeSubTypes) { - if (createdTypesOrSubTypes.count(subType)) { + if (createdTypesOrSubTypes.contains(subType)) { if (!refinedType) { // This is the first relevant thing, and hopefully will remain // the only one. @@ -256,7 +256,7 @@ struct AbstractTypeRefining : public Pass { // never-created types to the bottom type. // // We check this first as it is the most powerful change. - if (createdTypesOrSubTypes.count(type) == 0) { + if (!createdTypesOrSubTypes.contains(type)) { mapping[type] = type.getBottom(); continue; } diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp index 48f9cc59419..a8410a24c05 100644 --- a/src/passes/Asyncify.cpp +++ b/src/passes/Asyncify.cpp @@ -506,7 +506,7 @@ class PatternMatcher { } bool match(Name funcName) { - if (names.count(funcName) > 0) { + if (names.contains(funcName)) { return true; } else { for (auto& pattern : patterns) { @@ -521,7 +521,7 @@ class PatternMatcher { void checkPatternsMatches() { for (auto& pattern : patterns) { - if (patternsMatched.count(pattern) == 0) { + if (!patternsMatched.contains(pattern)) { std::cerr << "warning: Asyncify " << designation << "list contained a non-matching pattern: " << unescaped[pattern] << " (" << pattern << ")\n"; @@ -1068,12 +1068,12 @@ struct AsyncifyFlow : public Pass { // At least one of our children may change the state. Clump them as // necessary. while (1) { - if (processed.count(list[i])) { + if (processed.contains(list[i])) { list[i] = results.back(); results.pop_back(); } else { Index begin = i; - while (begin > 0 && !processed.count(list[begin - 1])) { + while (begin > 0 && !processed.contains(list[begin - 1])) { begin--; } // We have a range of [begin, i] in which the state cannot change, @@ -1601,7 +1601,7 @@ struct AsyncifyLocals : public WalkerPass> { // location. TODO look more precisely inside basic blocks, as one might stop // being live in the middle for (auto* block : walker.liveBlocks) { - if (walker.relevantBasicBlocks.count(block)) { + if (walker.relevantBasicBlocks.contains(block)) { for (auto local : block->contents.start) { relevantLiveLocals.insert(local); } @@ -1617,7 +1617,7 @@ struct AsyncifyLocals : public WalkerPass> { auto numLocals = func->getNumLocals(); Index total = 0; for (Index i = 0; i < numLocals; i++) { - if (!relevantLiveLocals.count(i)) { + if (!relevantLiveLocals.contains(i)) { continue; } total += getByteSize(func->getLocalType(i)); @@ -1629,7 +1629,7 @@ struct AsyncifyLocals : public WalkerPass> { builder->makeLocalSet(tempIndex, builder->makeGetStackPos())); Index offset = 0; for (Index i = 0; i < numLocals; i++) { - if (!relevantLiveLocals.count(i)) { + if (!relevantLiveLocals.contains(i)) { continue; } auto localType = func->getLocalType(i); @@ -1674,7 +1674,7 @@ struct AsyncifyLocals : public WalkerPass> { builder->makeLocalSet(tempIndex, builder->makeGetStackPos())); Index offset = 0; for (Index i = 0; i < numLocals; i++) { - if (!relevantLiveLocals.count(i)) { + if (!relevantLiveLocals.contains(i)) { continue; } auto localType = func->getLocalType(i); diff --git a/src/passes/CoalesceLocals.cpp b/src/passes/CoalesceLocals.cpp index 93c3d8d0051..438528008fb 100644 --- a/src/passes/CoalesceLocals.cpp +++ b/src/passes/CoalesceLocals.cpp @@ -177,7 +177,7 @@ void CoalesceLocals::calculateInterferences() { auto* func = getFunction(); for (auto& curr : basicBlocks) { - if (liveBlocks.count(curr.get()) == 0) { + if (!liveBlocks.contains(curr.get())) { continue; // ignore dead blocks } diff --git a/src/passes/CodeFolding.cpp b/src/passes/CodeFolding.cpp index 1fc738a377d..65e3e3471ed 100644 --- a/src/passes/CodeFolding.cpp +++ b/src/passes/CodeFolding.cpp @@ -209,7 +209,7 @@ struct CodeFolding if (!curr->name.is()) { return; } - if (unoptimizables.count(curr->name) > 0) { + if (unoptimizables.contains(curr->name)) { return; } auto iter = breakTails.find(curr->name); @@ -356,10 +356,10 @@ struct CodeFolding } // see if anything is untoward, and we should not do this for (auto& tail : tails) { - if (tail.expr && modifieds.count(tail.expr) > 0) { + if (tail.expr && modifieds.contains(tail.expr)) { return; } - if (modifieds.count(tail.block) > 0) { + if (modifieds.contains(tail.block)) { return; } // if we were not modified, then we should be valid for processing @@ -549,10 +549,10 @@ struct CodeFolding std::remove_if(tails.begin(), tails.end(), [&](Tail& tail) { - if (tail.expr && modifieds.count(tail.expr) > 0) { + if (tail.expr && modifieds.contains(tail.expr)) { return true; } - if (tail.block && modifieds.count(tail.block) > 0) { + if (tail.block && modifieds.contains(tail.block)) { return true; } return false; diff --git a/src/passes/CodePushing.cpp b/src/passes/CodePushing.cpp index 65eedba6bac..67bef95c468 100644 --- a/src/passes/CodePushing.cpp +++ b/src/passes/CodePushing.cpp @@ -396,13 +396,13 @@ class Pusher { const Expression* otherArm, EffectAnalyzer& armEffects, const EffectAnalyzer& otherArmEffects) { - if (!arm || !armEffects.localsRead.count(index) || - otherArmEffects.localsRead.count(index)) { + if (!arm || !armEffects.localsRead.contains(index) || + otherArmEffects.localsRead.contains(index)) { // No arm, or this arm has no read of the index, or the other arm // reads the index. return false; } - if (postIfEffects.localsRead.count(index) && + if (postIfEffects.localsRead.contains(index) && (!otherArm || otherArm->type != Type::unreachable)) { // The local is read later, which is bad, and there is no unreachable // in the other arm which as mentioned above is the only thing that diff --git a/src/passes/DeadArgumentElimination.cpp b/src/passes/DeadArgumentElimination.cpp index da8e69a7417..0d446900e75 100644 --- a/src/passes/DeadArgumentElimination.cpp +++ b/src/passes/DeadArgumentElimination.cpp @@ -185,7 +185,7 @@ struct DAEScanner if (numParams > 0) { auto usedParams = ParamUtils::getUsedParams(func, getModule()); for (Index i = 0; i < numParams; i++) { - if (usedParams.count(i) == 0) { + if (!usedParams.contains(i)) { info->unusedParams.insert(i); } } @@ -506,7 +506,7 @@ struct DAE : public Pass { } bool allDropped = std::all_of(calls.begin(), calls.end(), [&](Call* call) { - return allDroppedCalls.count(call); + return allDroppedCalls.contains(call); }); if (!allDropped) { continue; diff --git a/src/passes/DeadArgumentElimination2.cpp b/src/passes/DeadArgumentElimination2.cpp index c52b69a37c9..11dc2cec1fb 100644 --- a/src/passes/DeadArgumentElimination2.cpp +++ b/src/passes/DeadArgumentElimination2.cpp @@ -920,7 +920,7 @@ struct Optimizer // out the parameter. if (curr->index < funcInfo->paramUsages.size() && !funcInfo->paramUsages[curr->index] && - funcInfo->paramGets.count(curr)) { + funcInfo->paramGets.contains(curr)) { for (Index i = expressionStack.size(); i > 0; --i) { auto* expr = expressionStack[i - 1]; if (expr->is() || expr->is() || @@ -1048,7 +1048,7 @@ struct Optimizer // or non-concrete expression it ultimately flows into. return; } - if (!removedExpressions.count(curr)) { + if (!removedExpressions.contains(curr)) { // We're keeping this one. return; } @@ -1071,7 +1071,7 @@ struct Optimizer Expression* Optimizer::getReplacement(Expression* curr) { Builder builder(*getModule()); - if (!removedExpressions.count(curr)) { + if (!removedExpressions.contains(curr)) { // This expression is not removed, so none of its children are either. (If // they were, they would already have been removed.) if (!curr->type.isConcrete()) { @@ -1158,7 +1158,7 @@ Expression* Optimizer::getReplacement(Expression* curr) { static void scan(Collector* self, Expression** currp) { Expression* curr = *currp; - if (!self->removedExpressions.count(curr)) { + if (!self->removedExpressions.contains(curr)) { // The expressions we are removing form a sub-tree starting at the // root expression. There is therefore never a removed expression // inside a non-removed expression. We can just collect this diff --git a/src/passes/DuplicateFunctionElimination.cpp b/src/passes/DuplicateFunctionElimination.cpp index e797cd843aa..b86d657dc51 100644 --- a/src/passes/DuplicateFunctionElimination.cpp +++ b/src/passes/DuplicateFunctionElimination.cpp @@ -75,12 +75,12 @@ struct DuplicateFunctionElimination : public Pass { // O(N^2) here unless the hash is quite poor. for (Index i = 0; i < size - 1; i++) { auto* first = group[i]; - if (duplicates.count(first->name)) { + if (duplicates.contains(first->name)) { continue; } for (Index j = i + 1; j < size; j++) { auto* second = group[j]; - if (duplicates.count(second->name)) { + if (duplicates.contains(second->name)) { continue; } if (FunctionUtils::equal(first, second)) { @@ -95,7 +95,7 @@ struct DuplicateFunctionElimination : public Pass { if (replacements.size() > 0) { // remove the duplicates module->removeFunctions( - [&](Function* func) { return duplicates.count(func->name) > 0; }); + [&](Function* func) { return duplicates.contains(func->name); }); OptUtils::replaceFunctions(getPassRunner(), *module, replacements); } else { break; diff --git a/src/passes/GlobalEffects.cpp b/src/passes/GlobalEffects.cpp index fbfb278e93f..06e25edf090 100644 --- a/src/passes/GlobalEffects.cpp +++ b/src/passes/GlobalEffects.cpp @@ -127,7 +127,7 @@ struct GenerateGlobalEffects : public Pass { // We must not already have an entry for this call (that would imply we // are doing wasted work). - assert(!callers[called].count(caller)); + assert(!callers[called].contains(caller)); // Apply the new call information. callers[called].insert(caller); @@ -140,7 +140,7 @@ struct GenerateGlobalEffects : public Pass { // auto& calledInfo = analysis.map[module->getFunction(called)]; for (auto calledByCalled : calledInfo.calledFunctions) { - if (!callers[calledByCalled].count(caller)) { + if (!callers[calledByCalled].contains(caller)) { work.push({caller, calledByCalled}); } } @@ -151,7 +151,7 @@ struct GenerateGlobalEffects : public Pass { // itself then it might recurse infinitely, which we consider an effect (a // trap). for (auto& [func, info] : analysis.map) { - if (callers[func->name].count(func->name)) { + if (callers[func->name].contains(func->name)) { if (info.effects) { info.effects->trap = true; } diff --git a/src/passes/GlobalRefining.cpp b/src/passes/GlobalRefining.cpp index 1cb4aed7c29..87dc5b259cf 100644 --- a/src/passes/GlobalRefining.cpp +++ b/src/passes/GlobalRefining.cpp @@ -89,7 +89,7 @@ struct GlobalRefining : public Pass { PublicTypeValidator publicTypeValidator(module->features); for (auto& global : module->globals) { - if (global->imported() || unoptimizable.count(global->name)) { + if (global->imported() || unoptimizable.contains(global->name)) { continue; } @@ -112,7 +112,7 @@ struct GlobalRefining : public Pass { } // Do not make invalid types public. - if (exportedGlobals.count(global.get()) && + if (exportedGlobals.contains(global.get()) && !publicTypeValidator.isValidPublicType(newType)) { continue; } diff --git a/src/passes/GlobalStructInference.cpp b/src/passes/GlobalStructInference.cpp index 26e6f38cee6..ae9d14488be 100644 --- a/src/passes/GlobalStructInference.cpp +++ b/src/passes/GlobalStructInference.cpp @@ -224,7 +224,7 @@ struct GlobalStructInference : public Pass { curr = *super; // As above, avoid adding pointless data for anything unoptimizable. - if (!unoptimizable.count(curr)) { + if (!unoptimizable.contains(curr)) { for (auto global : globals) { typeGlobals[curr].push_back(global); } @@ -382,7 +382,7 @@ struct GlobalStructInference : public Pass { if (auto* get = ref->dynCast()) { // The global.get must be valid, and not in the process of being // rewritten to point to a new un-nested global. - if (!unnestingGlobalGets.count(get)) { + if (!unnestingGlobalGets.contains(get)) { auto* global = wasm.getGlobal(get->name); if (!global->mutable_ && !global->imported()) { if (auto* structNew = global->init->dynCast()) { diff --git a/src/passes/GlobalTypeOptimization.cpp b/src/passes/GlobalTypeOptimization.cpp index d19cfc3cf27..dcb28817ea0 100644 --- a/src/passes/GlobalTypeOptimization.cpp +++ b/src/passes/GlobalTypeOptimization.cpp @@ -217,7 +217,7 @@ struct GlobalTypeOptimization : public Pass { // fixed, and then subtypes can decide how to sort fields that they append. for (auto type : HeapTypeOrdering::supertypesFirst(propagator.subTypes.types)) { - if (!type.isStruct() || publicTypesSet.count(type)) { + if (!type.isStruct() || publicTypesSet.contains(type)) { continue; } auto& fields = type.getStruct().fields; @@ -295,7 +295,7 @@ struct GlobalTypeOptimization : public Pass { // reordered fields even if we ourselves are not removing anything, and we // must update to match the parent's order. auto super = type.getDeclaredSuperType(); - auto superHasUpdates = super && indexesAfterRemovals.count(*super); + auto superHasUpdates = super && indexesAfterRemovals.contains(*super); if (!removableIndexes.empty() || superHasUpdates) { // We are removing fields. Reorder them to allow that, as in the general // case we can only remove fields from the end, so that if our subtypes @@ -354,7 +354,7 @@ struct GlobalTypeOptimization : public Pass { for (Index i = 0; i < superIndexes.size(); ++i) { auto superIndex = superIndexes[i]; if (superIndex == RemovedField) { - if (removableIndexes.count(i)) { + if (removableIndexes.contains(i)) { // This was removed in the super, and in us as well. indexesAfterRemoval[i] = RemovedField; } else { @@ -385,7 +385,7 @@ struct GlobalTypeOptimization : public Pass { // Go over the fields only defined in us, and not in any super. for (Index i = numSuperFields; i < fields.size(); ++i) { - if (removableIndexes.count(i)) { + if (removableIndexes.contains(i)) { indexesAfterRemoval[i] = RemovedField; } else { indexesAfterRemoval[i] = next++; diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp index 1a52af2a92e..3517dc7ce11 100644 --- a/src/passes/Heap2Local.cpp +++ b/src/passes/Heap2Local.cpp @@ -573,7 +573,7 @@ struct EscapeAnalyzer { // Check that the gets can only read from the specific known sets. for (auto* get : gets) { for (auto* set : localGraph.getSets(get)) { - if (sets.count(set) == 0) { + if (!sets.contains(set)) { return false; } } @@ -589,7 +589,7 @@ struct EscapeAnalyzer { // We can only replace something relevant that we found in the analysis. // (Not only would anything else be invalid to process, but also we wouldn't // know what interaction to give the replacement.) - assert(reachedInteractions.count(old)); + assert(reachedInteractions.contains(old)); // The replacement should have the same interaction as the thing it // replaces, since it is a drop-in replacement for it. The one exception is diff --git a/src/passes/HeapStoreOptimization.cpp b/src/passes/HeapStoreOptimization.cpp index e4d3d7a1cb2..c720c5f0a41 100644 --- a/src/passes/HeapStoreOptimization.cpp +++ b/src/passes/HeapStoreOptimization.cpp @@ -227,8 +227,8 @@ struct HeapStoreOptimization // occurred; or, if it writes to that local, then it would cross another // write). auto setValueEffects = effects(set->value); - if (setValueEffects.localsRead.count(refLocalIndex) || - setValueEffects.localsWritten.count(refLocalIndex)) { + if (setValueEffects.localsRead.contains(refLocalIndex) || + setValueEffects.localsWritten.contains(refLocalIndex)) { return false; } diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp index d127ebdc8e2..86377067f6f 100644 --- a/src/passes/I64ToI32Lowering.cpp +++ b/src/passes/I64ToI32Lowering.cpp @@ -385,7 +385,7 @@ struct I64ToI32Lowering : public WalkerPass> { if (!getFunction()) { return; // if in a global init, skip - we already handled that. } - if (!originallyI64Globals.count(curr->name)) { + if (!originallyI64Globals.contains(curr->name)) { return; } curr->type = Type::i32; @@ -398,7 +398,7 @@ struct I64ToI32Lowering : public WalkerPass> { } void visitGlobalSet(GlobalSet* curr) { - if (!originallyI64Globals.count(curr->name)) { + if (!originallyI64Globals.contains(curr->name)) { return; } if (handleUnreachable(curr)) { diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp index ff5cac479b0..13d0b7630f1 100644 --- a/src/passes/Inlining.cpp +++ b/src/passes/Inlining.cpp @@ -207,7 +207,7 @@ struct FunctionInfoScanner void visitCall(Call* curr) { // can't add a new element in parallel - assert(infos.count(curr->target) > 0); + assert(infos.contains(curr->target)); infos[curr->target].refs++; // having a call infos[getFunction()->name].hasCalls = true; @@ -228,7 +228,7 @@ struct FunctionInfoScanner } void visitRefFunc(RefFunc* curr) { - assert(infos.count(curr->func) > 0); + assert(infos.contains(curr->func)); infos[curr->func].refs++; } @@ -337,10 +337,10 @@ struct Planner : public WalkerPass> { } else { isUnreachable = curr->type == Type::unreachable; } - if (state->inlinableFunctions.count(curr->target) && !isUnreachable && + if (state->inlinableFunctions.contains(curr->target) && !isUnreachable && curr->target != getFunction()->name) { // can't add a new element in parallel - assert(state->actionsForFunction.count(getFunction()->name) > 0); + assert(state->actionsForFunction.contains(getFunction()->name)); state->actionsForFunction[getFunction()->name].emplace_back( getCurrentPointer(), getModule()->getFunction(curr->target), @@ -470,7 +470,9 @@ struct Updater : public TryDepthWalker { // callsite to branch out of it then execute the call before returning to // the caller. auto name = Names::getValidName( - "__return_call", [&](Name test) { return !blockNames.count(test); }, i); + "__return_call", + [&](Name test) { return !blockNames.contains(test); }, + i); blockNames.insert(name); info.branch->name = name; Block* oldBody = builder->makeBlock(body->list, body->type); @@ -544,7 +546,7 @@ static void doCodeInlining(Module* module, auto callNames = hoistCall ? BranchUtils::NameSet{} : BranchUtils::BranchAccumulator::get(call); block->name = Names::getValidName(block->name, [&](Name test) { - return !fromNames.count(test) && !callNames.count(test); + return !fromNames.contains(test) && !callNames.contains(test); }); } @@ -568,7 +570,7 @@ static void doCodeInlining(Module* module, auto intoNames = BranchUtils::BranchAccumulator::get(into->body); auto bodyName = Names::getValidName(Name("__original_body"), - [&](Name test) { return !intoNames.count(test); }); + [&](Name test) { return !intoNames.contains(test); }); if (retType.isConcrete()) { into->body = builder.makeBlock( bodyName, {builder.makeReturn(into->body)}, Type::none); @@ -1014,7 +1016,7 @@ struct FunctionSplitter { // Finish the locals check mentioned above. if (finalItem) { for (auto* get : FindAll(finalItem).list) { - if (writtenLocals.count(get->index)) { + if (writtenLocals.contains(get->index)) { return InliningMode::Uninlineable; } } @@ -1412,7 +1414,7 @@ struct Inlining : public Pass { // avoid risk of races // note that we do not risk stalling progress, as each iteration() will // inline at least one call before hitting this - if (inlinedUses.count(func->name)) { + if (inlinedUses.contains(func->name)) { continue; } for (auto& action : state.actionsForFunction[name]) { @@ -1421,7 +1423,7 @@ struct Inlining : public Pass { // avoid risk of races // note that we do not risk stalling progress, as each iteration() will // inline at least one call before hitting this - if (inlinedInto.count(inlinedFunction)) { + if (inlinedInto.contains(inlinedFunction)) { continue; } Name inlinedName = inlinedFunction->name; @@ -1472,7 +1474,7 @@ struct Inlining : public Pass { module->removeFunctions([&](Function* func) { auto name = func->name; auto& info = infos[name]; - return inlinedUses.count(name) && inlinedUses[name] == info.refs && + return inlinedUses.contains(name) && inlinedUses[name] == info.refs && !info.usedGlobally; }); } diff --git a/src/passes/InstrumentBranchHints.cpp b/src/passes/InstrumentBranchHints.cpp index ac87b8f5ecf..656397a5ad1 100644 --- a/src/passes/InstrumentBranchHints.cpp +++ b/src/passes/InstrumentBranchHints.cpp @@ -344,7 +344,7 @@ struct DeleteBranchHints : public InstrumentationProcessor { if (auto info = getInstrumentation(curr->condition)) { if (auto* c = info->call->operands[0]->template dynCast()) { auto id = c->value.geti32(); - if (idsToDelete.count(id)) { + if (idsToDelete.contains(id)) { // Remove the branch hint. getFunction()->codeAnnotations[curr].branchLikely = {}; } diff --git a/src/passes/J2CLItableMerging.cpp b/src/passes/J2CLItableMerging.cpp index 03f44fcdc53..68e610755d2 100644 --- a/src/passes/J2CLItableMerging.cpp +++ b/src/passes/J2CLItableMerging.cpp @@ -165,9 +165,9 @@ struct J2CLItableMerging : public Pass { if (!g->type.isStruct()) { continue; } - if (structInfoByVtableType.count(g->type.getHeapType())) { + if (structInfoByVtableType.contains(g->type.getHeapType())) { tableGlobalsByType[g->type.getHeapType()] = g.get(); - } else if (structInfoByITableType.count(g->type.getHeapType())) { + } else if (structInfoByITableType.contains(g->type.getHeapType())) { tableGlobalsByType[g->type.getHeapType()] = g.get(); } } diff --git a/src/passes/LegalizeJSInterface.cpp b/src/passes/LegalizeJSInterface.cpp index 7621b7e23a9..7b6a4c44cdd 100644 --- a/src/passes/LegalizeJSInterface.cpp +++ b/src/passes/LegalizeJSInterface.cpp @@ -370,7 +370,7 @@ struct LegalizeAndPruneJSInterface : public LegalizeJSInterface { for (auto& func : module->functions) { // If the function is neither exported nor imported, no problem. auto imported = func->imported(); - auto exported = exportedFunctions.count(func->name); + auto exported = exportedFunctions.contains(func->name); if (!imported && !exported) { continue; } diff --git a/src/passes/LocalCSE.cpp b/src/passes/LocalCSE.cpp index a5221ed0079..0233d17061d 100644 --- a/src/passes/LocalCSE.cpp +++ b/src/passes/LocalCSE.cpp @@ -315,7 +315,7 @@ struct Scanner // requesting replacement. And then when we see the second A, all it needs // to update is the second B. for (auto* child : ChildIterator(curr)) { - if (!requestInfos.count(child)) { + if (!requestInfos.contains(child)) { // The child never had a request. While it repeated (since the parent // repeats), it was not relevant for the optimization so we never // created a requestInfo for it. @@ -459,7 +459,7 @@ struct Checker void visitExpression(Expression* curr) { // This is the first time we encounter this expression. - assert(!activeOriginals.count(curr)); + assert(!activeOriginals.contains(curr)); // Given the current expression, see what it invalidates of the currently- // hashed expressions, if there are any. @@ -612,7 +612,7 @@ struct Applier if (originalInfo.requests) { // This is a valid request of an original value. Get the value from the // local. - assert(originalLocalMap.count(info.original)); + assert(originalLocalMap.contains(info.original)); replaceCurrent( Builder(*getModule()) .makeLocalGet(originalLocalMap[info.original], curr->type)); diff --git a/src/passes/LocalSubtyping.cpp b/src/passes/LocalSubtyping.cpp index a26637684b7..583c10cf25f 100644 --- a/src/passes/LocalSubtyping.cpp +++ b/src/passes/LocalSubtyping.cpp @@ -151,7 +151,7 @@ struct LocalSubtyping : public WalkerPass> { // Remove non-nullability if we disallow that in locals. if (newType.isNonNullable()) { - if (cannotBeNonNullable.count(i)) { + if (cannotBeNonNullable.contains(i)) { newType = newType.with(Nullable); } } else if (!newType.isDefaultable()) { diff --git a/src/passes/LoopInvariantCodeMotion.cpp b/src/passes/LoopInvariantCodeMotion.cpp index 6c7aecbc71f..6add5134a79 100644 --- a/src/passes/LoopInvariantCodeMotion.cpp +++ b/src/passes/LoopInvariantCodeMotion.cpp @@ -241,7 +241,7 @@ struct LoopInvariantCodeMotion // to just outside the loop will preserve those relationships. // TODO: this still counts curr's sets as inside the loop, which // might matter in non-flat mode. - if (loopSets.count(set)) { + if (loopSets.contains(set)) { return true; } } diff --git a/src/passes/Metrics.cpp b/src/passes/Metrics.cpp index b5dba58b3a8..50b735ed63b 100644 --- a/src/passes/Metrics.cpp +++ b/src/passes/Metrics.cpp @@ -213,7 +213,7 @@ struct Metrics continue; } o << " " << left << setw(15) << key << ": " << setw(8) << value; - if (lastCounts.count(key)) { + if (lastCounts.contains(key)) { int before = lastCounts[key]; int after = value; if (after - before) { diff --git a/src/passes/MinimizeRecGroups.cpp b/src/passes/MinimizeRecGroups.cpp index 6a3c3223034..306426af5b9 100644 --- a/src/passes/MinimizeRecGroups.cpp +++ b/src/passes/MinimizeRecGroups.cpp @@ -93,7 +93,7 @@ struct TypeSCCs includedTypes(types.cbegin(), types.cend()) {} void pushChildren(HeapType parent) { for (auto child : parent.getReferencedHeapTypes()) { - if (includedTypes.count(child)) { + if (includedTypes.contains(child)) { push(child); } } @@ -651,7 +651,7 @@ struct MinimizeRecGroups : Pass { while (!workList.empty()) { auto curr = workList.back(); workList.pop_back(); - if (!typeSet.count(curr)) { + if (!typeSet.contains(curr)) { continue; } if (seen.insert(curr).second) { diff --git a/src/passes/Monomorphize.cpp b/src/passes/Monomorphize.cpp index 9f02d00402e..2798eaec4ba 100644 --- a/src/passes/Monomorphize.cpp +++ b/src/passes/Monomorphize.cpp @@ -380,7 +380,7 @@ struct CallContext { // that because if a parent is immovable then we can't move the children // into the context (if we did, they would execute after the parent, but // it needs their values). - bool currImmovable = immovable.count(curr) > 0; + bool currImmovable = immovable.contains(curr); if (!currImmovable) { // This might be movable or immovable. Check both effect interactions // (as described before, we want to move this past immovable code) and @@ -433,7 +433,7 @@ struct CallContext { return nullptr; } - if (!immovable.count(child)) { + if (!immovable.contains(child)) { // This can be moved; let the copy happen. return nullptr; } diff --git a/src/passes/NameTypes.cpp b/src/passes/NameTypes.cpp index 0e18f30945a..5bf0c8523da 100644 --- a/src/passes/NameTypes.cpp +++ b/src/passes/NameTypes.cpp @@ -40,7 +40,7 @@ struct NameTypes : public Pass { // it. size_t i = 0; for (auto& type : types) { - if (module->typeNames.count(type) == 0 || + if (!module->typeNames.contains(type) || module->typeNames[type].name.size() >= NameLenLimit) { module->typeNames[type].name = "type_" + std::to_string(i++); } @@ -60,7 +60,7 @@ struct NameTypes : public Pass { } if (name.size() > 1 && name.back() == '_') { name.pop_back(); - if (!used.count(name)) { + if (!used.contains(name)) { names.name = name; used.insert(name); } diff --git a/src/passes/OnceReduction.cpp b/src/passes/OnceReduction.cpp index 7fcb1d3f288..814483d51e0 100644 --- a/src/passes/OnceReduction.cpp +++ b/src/passes/OnceReduction.cpp @@ -593,7 +593,7 @@ struct OnceReduction : public Pass { // remove the logic if we are calling such a function. (As a result, // the order of iteration matters here, and so the outer loop in this // function must be deterministic.) - if (!removedExitLogic.count(call->target)) { + if (!removedExitLogic.contains(call->target)) { ExpressionManipulator::nop(list[0]); ExpressionManipulator::nop(list[1]); removedExitLogic.insert(func->name); diff --git a/src/passes/OptimizeAddedConstants.cpp b/src/passes/OptimizeAddedConstants.cpp index fd584083641..ff6e0600f88 100644 --- a/src/passes/OptimizeAddedConstants.cpp +++ b/src/passes/OptimizeAddedConstants.cpp @@ -355,7 +355,7 @@ struct OptimizeAddedConstants Builder(*getModule()).addVar(getFunction(), Type::i32); } - bool isPropagatable(LocalSet* set) { return propagatable.count(set); } + bool isPropagatable(LocalSet* set) { return propagatable.contains(set); } private: bool propagated; diff --git a/src/passes/Outlining.cpp b/src/passes/Outlining.cpp index 6a83fac69ac..c52213fdc61 100644 --- a/src/passes/Outlining.cpp +++ b/src/passes/Outlining.cpp @@ -222,7 +222,7 @@ std::vector StringifyProcessor::dedupe( // sequences with the same endIdx, and we generally prefer to outline // longer repeat sequences. uint32_t endIdx = substring.Length + startIdx; - if (seen.count(endIdx)) { + if (seen.contains(endIdx)) { seenEndIdx = true; break; } diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp index aa32d376c61..a5f8da4b42c 100644 --- a/src/passes/Precompute.cpp +++ b/src/passes/Precompute.cpp @@ -705,7 +705,7 @@ struct Precompute InsertOrderedMap stackMap; void visitSelect(Select* curr) { - if (parent.partiallyPrecomputable.count(curr)) { + if (parent.partiallyPrecomputable.contains(curr)) { stackMap[curr] = expressionStack; } } @@ -743,7 +743,7 @@ struct Precompute Index selectIndex = stack.size() - 1; assert(selectIndex >= 1); - if (modified.count(select)) { + if (modified.contains(select)) { // This select was modified; go to the next one. continue; } @@ -754,7 +754,7 @@ struct Precompute for (Index parentIndex = selectIndex - 1; parentIndex != Index(-1); parentIndex--) { auto* parent = stack[parentIndex]; - if (modified.count(parent)) { + if (modified.contains(parent)) { // This parent was modified; exit the loop on parents as no upper // parent is valid to try either. break; @@ -918,7 +918,7 @@ struct Precompute // Given a set, see if it has a constant value. If so, note that on // setValues and add to the work list. auto checkConstantSet = [&](LocalSet* set) { - if (setValues.count(set)) { + if (setValues.contains(set)) { // Already known to be constant. return; } @@ -959,7 +959,7 @@ struct Precompute // The same, for a get. auto checkConstantGet = [&](LocalGet* get) { - if (getValues.count(get)) { + if (getValues.contains(get)) { // Already known to be constant. return; } diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 267199bc7b5..5432a2f471b 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -188,14 +188,14 @@ struct PrintSExpression : public UnifiedExpressionVisitor { // Use indices for any remaining type names, skipping any that are already // used. for (auto type : types) { - if (parent.currModule->typeNames.count(type)) { + if (parent.currModule->typeNames.contains(type)) { ++i; continue; } Name name; do { name = std::to_string(i++); - } while (usedNames.count(name)); + } while (usedNames.contains(name)); fallbackNames[type] = {name, {}}; } } diff --git a/src/passes/ReReloop.cpp b/src/passes/ReReloop.cpp index cdd6b3a74de..f31736940cf 100644 --- a/src/passes/ReReloop.cpp +++ b/src/passes/ReReloop.cpp @@ -239,7 +239,7 @@ struct ReReloop final : public Pass { } // the default may be among the targets, in which case, we can't add it // simply as it would be a duplicate, so create a temp block - if (targetValues.count(curr->default_) == 0) { + if (!targetValues.contains(curr->default_)) { parent.addSwitchBranch( before, parent.getBreakTarget(curr->default_), std::set()); } else { diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp index d081c51539e..bb539a5c823 100644 --- a/src/passes/RemoveUnusedBrs.cpp +++ b/src/passes/RemoveUnusedBrs.cpp @@ -1994,7 +1994,7 @@ struct RemoveUnusedBrs : public WalkerPass> { Index i = 0; while (1) { defaultName = "tablify|" + std::to_string(i++); - if (usedNames.count(defaultName) == 0) { + if (!usedNames.contains(defaultName)) { break; } } diff --git a/src/passes/RemoveUnusedModuleElements.cpp b/src/passes/RemoveUnusedModuleElements.cpp index fac3223ffb6..34418009cf4 100644 --- a/src/passes/RemoveUnusedModuleElements.cpp +++ b/src/passes/RemoveUnusedModuleElements.cpp @@ -397,7 +397,7 @@ struct Analyzer { // We must not have a type in both calledSignatures and // uncalledRefFuncMap: once it is called, we do not track RefFuncs for // it any more. - assert(calledSignatures.count(subType) == 0); + assert(!calledSignatures.contains(subType)); for (Name target : iter->second) { use({ModuleElementKind::Function, target}); @@ -454,11 +454,11 @@ struct Analyzer { auto element = ModuleElement{ModuleElementKind::Function, func}; auto type = module->getFunction(func)->type.getHeapType(); - if (calledSignatures.count(type)) { + if (calledSignatures.contains(type)) { // We must not have a type in both calledSignatures and // uncalledRefFuncMap: once it is called, we do not track RefFuncs for it // any more. - assert(uncalledRefFuncMap.count(type) == 0); + assert(!uncalledRefFuncMap.contains(type)); // We've seen a RefFunc for this, so it is used. use(element); @@ -471,7 +471,7 @@ struct Analyzer { } void useStructField(StructField structField) { - if (!readStructFields.count(structField)) { + if (!readStructFields.contains(structField)) { // Avoid a structured binding as the C++ spec does not allow capturing // them in lambdas, which we need below. auto type = structField.first; @@ -509,7 +509,7 @@ struct Analyzer { auto curr = moduleQueue.back(); moduleQueue.pop_back(); - assert(used.count(curr)); + assert(used.contains(curr)); auto& [kind, value] = curr; switch (kind) { case ModuleElementKind::Function: { @@ -649,7 +649,7 @@ struct Analyzer { // If this struct field has already been read, then we should use the // contents there now. - auto useOperandNow = readStructFields.count(structField); + auto useOperandNow = readStructFields.contains(structField); // Side effects are tricky to reason about - the side effects must happen // even if we never read the struct field - so give up and consider it @@ -909,17 +909,18 @@ struct RemoveUnusedModuleElements : public Pass { // We need to emit something in the output if it has either a reference or // a use. Situations where we can do better (for the case of a reference // without any use) are handled separately below. - return analyzer.used.count(element) || analyzer.referenced.count(element); + return analyzer.used.contains(element) || + analyzer.referenced.contains(element); }; module->removeFunctions([&](Function* curr) { auto element = ModuleElement{ModuleElementKind::Function, curr->name}; - if (analyzer.used.count(element)) { + if (analyzer.used.contains(element)) { // This is used. return false; } - if (analyzer.referenced.count(element)) { + if (analyzer.referenced.contains(element)) { // This is not used, but has a reference. See comment above on // uncalledRefFuncs. if (!curr->imported()) { diff --git a/src/passes/ReorderGlobals.cpp b/src/passes/ReorderGlobals.cpp index 7e84edb94fb..51c40a76007 100644 --- a/src/passes/ReorderGlobals.cpp +++ b/src/passes/ReorderGlobals.cpp @@ -56,11 +56,11 @@ struct UseCountScanner : public WalkerPass> { void visitGlobalGet(GlobalGet* curr) { // We can't add a new element to the map in parallel. - assert(counts.count(curr->name) > 0); + assert(counts.contains(curr->name)); counts[curr->name]++; } void visitGlobalSet(GlobalSet* curr) { - assert(counts.count(curr->name) > 0); + assert(counts.contains(curr->name)); counts[curr->name]++; } diff --git a/src/passes/SSAify.cpp b/src/passes/SSAify.cpp index 8e827d0fcd0..91822f2c7e5 100644 --- a/src/passes/SSAify.cpp +++ b/src/passes/SSAify.cpp @@ -178,7 +178,7 @@ struct SSAify : public Pass { set->value = tee; // the value may have been something we tracked the location // of. if so, update that, since we moved it into the tee - if (graph.locations.count(value) > 0) { + if (graph.locations.contains(value)) { assert(graph.locations[value] == &set->value); graph.locations[value] = &tee->value; } diff --git a/src/passes/SafeHeap.cpp b/src/passes/SafeHeap.cpp index f81dc60bcbc..fe5b21507fb 100644 --- a/src/passes/SafeHeap.cpp +++ b/src/passes/SafeHeap.cpp @@ -95,7 +95,7 @@ struct AccessInstrumenter : public WalkerPass> { : ignoreFunctions(ignoreFunctions) {} void visitLoad(Load* curr) { - if (ignoreFunctions.count(getFunction()->name) != 0 || + if (ignoreFunctions.contains(getFunction()->name) || curr->type == Type::unreachable) { return; } @@ -108,7 +108,7 @@ struct AccessInstrumenter : public WalkerPass> { } void visitStore(Store* curr) { - if (ignoreFunctions.count(getFunction()->name) != 0 || + if (ignoreFunctions.contains(getFunction()->name) || curr->type == Type::unreachable) { return; } diff --git a/src/passes/SignaturePruning.cpp b/src/passes/SignaturePruning.cpp index 10abe59057a..ae920839fd4 100644 --- a/src/passes/SignaturePruning.cpp +++ b/src/passes/SignaturePruning.cpp @@ -277,7 +277,7 @@ struct SignaturePruning : public Pass { // to prune them. SortedVector unusedParams; for (Index i = 0; i < numParams; i++) { - if (usedParams.count(i) == 0) { + if (!usedParams.contains(i)) { unusedParams.insert(i); } } diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp index 4cd44b195e1..14cd6f6de9e 100644 --- a/src/passes/SimplifyGlobals.cpp +++ b/src/passes/SimplifyGlobals.cpp @@ -191,7 +191,7 @@ struct GlobalUseScanner : public WalkerPass> { // See if we read that global in the condition expression. EffectAnalyzer conditionEffects(getPassOptions(), *getModule(), condition); - if (!conditionEffects.mutableGlobalsRead.count(writtenGlobal)) { + if (!conditionEffects.mutableGlobalsRead.contains(writtenGlobal)) { return Name(); } // As above, confirm we see an actual global.get, and not a call to one with @@ -666,8 +666,8 @@ struct SimplifyGlobals : public Pass { // Go all the way back. for (auto& global : module->globals) { auto child = global->name; - if (copiedParentMap.count(child)) { - while (copiedParentMap.count(copiedParentMap[child])) { + if (copiedParentMap.contains(child)) { + while (copiedParentMap.contains(copiedParentMap[child])) { copiedParentMap[child] = copiedParentMap[copiedParentMap[child]]; } } diff --git a/src/passes/SimplifyLocals.cpp b/src/passes/SimplifyLocals.cpp index 8df317bee12..bf7902443bc 100644 --- a/src/passes/SimplifyLocals.cpp +++ b/src/passes/SimplifyLocals.cpp @@ -203,7 +203,7 @@ struct SimplifyLocals // post-block cleanups if (curr->name.is()) { - if (unoptimizableBlocks.count(curr->name)) { + if (unoptimizableBlocks.contains(curr->name)) { sinkables.clear(); unoptimizableBlocks.erase(curr->name); } @@ -431,7 +431,7 @@ struct SimplifyLocals if (set && self->canSink(set)) { Index index = set->index; - assert(self->sinkables.count(index) == 0); + assert(!self->sinkables.contains(index)); self->sinkables.emplace(std::pair{ index, SinkableInfo(currp, self->getPassOptions(), *self->getModule())}); @@ -503,7 +503,7 @@ struct SimplifyLocals } void optimizeBlockReturn(Block* block) { - if (!block->name.is() || unoptimizableBlocks.count(block->name) > 0) { + if (!block->name.is() || unoptimizableBlocks.contains(block->name)) { return; } auto breaks = std::move(blockBreaks[block->name]); @@ -521,7 +521,7 @@ struct SimplifyLocals for (auto& [index, _] : sinkables) { bool inAll = true; for (size_t j = 0; j < breaks.size(); j++) { - if (breaks[j].sinkables.count(index) == 0) { + if (!breaks[j].sinkables.contains(index)) { inAll = false; break; } @@ -673,7 +673,7 @@ struct SimplifyLocals } else { // Look for a shared index. for (auto& [index, _] : ifTrue) { - if (ifFalse.count(index) > 0) { + if (ifFalse.contains(index)) { goodIndex = index; found = true; break; diff --git a/src/passes/Souperify.cpp b/src/passes/Souperify.cpp index 826c3f350f2..9ed11e550a4 100644 --- a/src/passes/Souperify.cpp +++ b/src/passes/Souperify.cpp @@ -394,7 +394,7 @@ struct Trace { for (auto* use : uses) { // A non-set use (a drop or return etc.) is definitely external. // Otherwise, check if internal or external. - if (use == nullptr || origins.count(use) == 0) { + if (use == nullptr || !origins.contains(use)) { if (debug() >= 2) { std::cout << "found external use for\n"; dump(node, std::cout); @@ -506,7 +506,7 @@ struct Printer { } if (node->isExpr() || node->isPhi()) { if (node->origin != trace.toInfer->origin && - trace.hasExternalUses.count(node) > 0) { + trace.hasExternalUses.contains(node)) { std::cout << " (hasExternalUses)"; printedHasExternalUses = true; } diff --git a/src/passes/SpillPointers.cpp b/src/passes/SpillPointers.cpp index cfa432a4ed4..50229f7e707 100644 --- a/src/passes/SpillPointers.cpp +++ b/src/passes/SpillPointers.cpp @@ -94,7 +94,7 @@ struct SpillPointers bool spilled = false; Index spillLocal = -1; for (auto& curr : basicBlocks) { - if (liveBlocks.count(curr.get()) == 0) { + if (!liveBlocks.contains(curr.get())) { continue; // ignore dead blocks } auto& liveness = curr->contents; @@ -121,7 +121,7 @@ struct SpillPointers } else if (action.isOther()) { std::vector toSpill; for (auto index : live) { - if (pointerMap.count(index) > 0) { + if (pointerMap.contains(index)) { toSpill.push_back(index); } } @@ -171,7 +171,7 @@ struct SpillPointers auto* set = builder.makeLocalSet(temp, operand); block->list.push_back(set); block->finalize(); - if (actualPointers.count(&operand) > 0) { + if (actualPointers.contains(&operand)) { // this is something we track, and it's moving - update actualPointers[&operand] = &set->value; } diff --git a/src/passes/StringLifting.cpp b/src/passes/StringLifting.cpp index 7b8f456217f..cd3a8ffabb6 100644 --- a/src/passes/StringLifting.cpp +++ b/src/passes/StringLifting.cpp @@ -110,7 +110,7 @@ struct StringLifting : public Pass { Fatal() << "StringLifting: string.const section entry is not a string"; } - if (importedStrings.count(global->name)) { + if (importedStrings.contains(global->name)) { Fatal() << "StringLifting: string.const section tramples other const"; } importedStrings[global->name] = item->getIString(); diff --git a/src/passes/StringLowering.cpp b/src/passes/StringLowering.cpp index cf2efad280e..b4641bda134 100644 --- a/src/passes/StringLowering.cpp +++ b/src/passes/StringLowering.cpp @@ -177,14 +177,15 @@ struct StringGathering : public Pass { module->globals.begin(), module->globals.end(), [&](const std::unique_ptr& a, const std::unique_ptr& b) { - return definingNames.count(a->name) && !definingNames.count(b->name); + return definingNames.contains(a->name) && + !definingNames.contains(b->name); }); } void replaceStrings(Module* module) { Builder builder(*module); for (auto** stringPtr : stringPtrs) { - if (stringPtrsToPreserve.count(stringPtr)) { + if (stringPtrsToPreserve.contains(stringPtr)) { continue; } auto* stringConst = (*stringPtr)->cast(); diff --git a/src/passes/TypeFinalizing.cpp b/src/passes/TypeFinalizing.cpp index 083c2a4ab44..5ba3459da46 100644 --- a/src/passes/TypeFinalizing.cpp +++ b/src/passes/TypeFinalizing.cpp @@ -71,7 +71,7 @@ struct TypeFinalizing : public Pass { void modifyTypeBuilderEntry(TypeBuilder& typeBuilder, Index i, HeapType oldType) override { - if (parent.modifiableTypes.count(oldType)) { + if (parent.modifiableTypes.contains(oldType)) { typeBuilder[i].setOpen(!parent.finalize); } } diff --git a/src/passes/TypeMerging.cpp b/src/passes/TypeMerging.cpp index 03ca4fa1010..5853ead9ad6 100644 --- a/src/passes/TypeMerging.cpp +++ b/src/passes/TypeMerging.cpp @@ -384,7 +384,7 @@ bool TypeMerging::merge(MergeKind kind) { std::any_of(chain.begin(), chain.end(), [&](HeapType t) -> bool { return castTypes.contains(t); }); - if (hasCast || !privateTypes.count(type)) { + if (hasCast || !privateTypes.contains(type)) { ensurePartition(type); continue; } @@ -530,7 +530,7 @@ TypeMerging::splitSupertypePartition(const std::vector& types) { std::unordered_map partitionIndices; for (auto type : mergeableSupertypesFirst(types)) { auto super = type.getDeclaredSuperType(); - if (super && includedTypes.count(*super)) { + if (super && includedTypes.contains(*super)) { // We must already have a partition for the supertype we can add to. auto index = partitionIndices.at(*super); partitions[index].push_back(type); @@ -582,7 +582,7 @@ std::pair TypeMerging::findCastTypes() { std::vector TypeMerging::getPublicChildren(HeapType type) { std::vector publicChildren; for (auto child : type.getHeapTypeChildren()) { - if (!child.isBasic() && !privateTypes.count(child)) { + if (!child.isBasic() && !privateTypes.contains(child)) { publicChildren.push_back(child); } } @@ -602,7 +602,7 @@ DFA::State TypeMerging::makeDFAState(HeapType type) { // // For private types, full descriptor chains are included in a single DFA // represented by their base described type. - if (privateTypes.count(type)) { + if (privateTypes.contains(type)) { assert(!type.getDescribedType()); for (auto t : type.getDescriptorChain()) { for (auto child : t.getHeapTypeChildren()) { diff --git a/src/passes/TypeRefining.cpp b/src/passes/TypeRefining.cpp index 01ed9fe8d7e..201360e5aca 100644 --- a/src/passes/TypeRefining.cpp +++ b/src/passes/TypeRefining.cpp @@ -288,7 +288,7 @@ struct TypeRefining : public Pass { work.push(subType); } - if (publicTypesSet.count(type)) { + if (publicTypesSet.contains(type)) { continue; } @@ -315,7 +315,7 @@ struct TypeRefining : public Pass { // The super's new type is either what we propagated, or, if it is // public, unchanged since we cannot optimize it Type newSuperType; - if (!publicTypesSet.count(*super)) { + if (!publicTypesSet.contains(*super)) { newSuperType = finalInfos[{*super, Inexact}][i].getLUB(); } else { newSuperType = superFields[i].type; diff --git a/src/passes/TypeSSA.cpp b/src/passes/TypeSSA.cpp index 624a71b09c3..2c99f91ed76 100644 --- a/src/passes/TypeSSA.cpp +++ b/src/passes/TypeSSA.cpp @@ -296,7 +296,7 @@ struct TypeSSA : public Pass { for (auto* curr : news) { bool disallowed = false; if (curr->type.isRef()) { - disallowed = disallowedTypes.count(curr->type.getHeapType()); + disallowed = disallowedTypes.contains(curr->type.getHeapType()); } if (!disallowed && isInteresting(curr)) { newsToModify.push_back(curr); @@ -372,7 +372,7 @@ struct TypeSSA : public Pass { curr->type = Type(newType, NonNullable, Exact); // If the old type has a nice name, make a nice name for the new one. - if (typeNames.count(oldType)) { + if (typeNames.contains(oldType)) { auto intendedName = typeNames[oldType].name.toString() + '_' + std::to_string(++nameCounter); auto newName = diff --git a/src/passes/param-utils.cpp b/src/passes/param-utils.cpp index 0d46345a14a..6861756c475 100644 --- a/src/passes/param-utils.cpp +++ b/src/passes/param-utils.cpp @@ -297,7 +297,7 @@ void localizeCallsTo(const std::unordered_set& callTargets, : callTargets(callTargets), onChange(onChange) {} void visitCall(Call* curr) { - if (!callTargets.count(curr->target)) { + if (!callTargets.contains(curr->target)) { return; } @@ -354,7 +354,7 @@ void localizeCallsTo(const std::unordered_set& callTargets, } void handleCall(Expression* call, HeapType type) { - if (!callTargets.count(type)) { + if (!callTargets.contains(type)) { return; } diff --git a/src/passes/pass-utils.h b/src/passes/pass-utils.h index 12b33fb398f..97c139ada5e 100644 --- a/src/passes/pass-utils.h +++ b/src/passes/pass-utils.h @@ -47,7 +47,7 @@ struct FilteredPass : public Pass { } void runOnFunction(Module* module, Function* func) override { - if (!relevantFuncs.count(func)) { + if (!relevantFuncs.contains(func)) { return; } diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index 0e6e28267c2..bcf3242e78c 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -74,7 +74,7 @@ std::vector PassRegistry::getRegisteredNames() { } bool PassRegistry::containsPass(const std::string& name) { - return passInfos.count(name) > 0; + return passInfos.contains(name); } std::string PassRegistry::getPassDescription(std::string name) { @@ -1003,7 +1003,7 @@ void PassRunner::clear() { passes.clear(); } void PassRunner::runPass(Pass* pass) { assert(!pass->isFunctionParallel()); - if (options.passesToSkip.count(pass->name)) { + if (options.passesToSkip.contains(pass->name)) { return; } @@ -1018,7 +1018,7 @@ void PassRunner::runPass(Pass* pass) { void PassRunner::runPassOnFunction(Pass* pass, Function* func) { assert(pass->isFunctionParallel()); - if (options.passesToSkip.count(pass->name)) { + if (options.passesToSkip.contains(pass->name)) { return; } diff --git a/src/support/debug.cpp b/src/support/debug.cpp index ab5401bfc16..b0c5f1dc1e7 100644 --- a/src/support/debug.cpp +++ b/src/support/debug.cpp @@ -32,7 +32,7 @@ bool wasm::isDebugEnabled(const char* type) { if (debugTypesEnabled.empty()) { return true; } - return debugTypesEnabled.count(type) > 0; + return debugTypesEnabled.contains(type); } void wasm::setDebugEnabled(const char* types) { diff --git a/src/support/insert_ordered.h b/src/support/insert_ordered.h index 58b189859b0..3a851dba5fd 100644 --- a/src/support/insert_ordered.h +++ b/src/support/insert_ordered.h @@ -74,7 +74,7 @@ template struct InsertOrderedSet { } size_t count(const T& val) const { return Map.count(val); } - bool contains(const T& val) const { return Map.find(val) != Map.end(); } + bool contains(const T& val) const { return Map.contains(val); } InsertOrderedSet() = default; InsertOrderedSet(const InsertOrderedSet& other) { *this = other; } @@ -161,7 +161,7 @@ template struct InsertOrderedMap { size_t size() const { return Map.size(); } bool empty() const { return Map.empty(); } size_t count(const Key& k) const { return Map.count(k); } - bool contains(const Key& k) const { return Map.find(k) != Map.end(); } + bool contains(const Key& k) const { return Map.contains(k); } InsertOrderedMap() = default; InsertOrderedMap(const InsertOrderedMap& other) { diff --git a/src/support/small_set.h b/src/support/small_set.h index 3da991bf462..4da31de2ca3 100644 --- a/src/support/small_set.h +++ b/src/support/small_set.h @@ -187,7 +187,6 @@ class SmallSetBase { bool contains(const T& x) const { if (usingFixed()) { - // Do a linear search. for (size_t i = 0; i < fixed.used; i++) { if (fixed.storage[i] == x) { return true; @@ -195,7 +194,7 @@ class SmallSetBase { } return false; } else { - return flexible.find(x) != flexible.end(); + return flexible.contains(x); } } diff --git a/src/support/suffix_tree.cpp b/src/support/suffix_tree.cpp index a66bcde38be..284a41b2130 100644 --- a/src/support/suffix_tree.cpp +++ b/src/support/suffix_tree.cpp @@ -135,7 +135,7 @@ unsigned SuffixTree::extend(unsigned EndIdx, unsigned SuffixesToAdd) { unsigned FirstChar = Str[Active.Idx]; // Have we inserted anything starting with FirstChar at the current node? - if (Active.Node->Children.count(FirstChar) == 0) { + if (!Active.Node->Children.contains(FirstChar)) { // If not, then we can just insert a leaf and move to the next step. insertLeaf(*Active.Node, EndIdx, FirstChar); diff --git a/src/support/unique_deferring_queue.h b/src/support/unique_deferring_queue.h index 3b30d7f7596..cbf9d7638b5 100644 --- a/src/support/unique_deferring_queue.h +++ b/src/support/unique_deferring_queue.h @@ -74,7 +74,7 @@ struct UniqueNonrepeatingDeferredQueue : UniqueDeferredQueue { std::unordered_set processed; void push(T item) { - if (!processed.count(item)) { + if (!processed.contains(item)) { UniqueDeferredQueue::push(item); } } diff --git a/src/tools/execution-results.h b/src/tools/execution-results.h index 4e26683372e..516d9f60603 100644 --- a/src/tools/execution-results.h +++ b/src/tools/execution-results.h @@ -144,7 +144,7 @@ struct LoggingExternalInterface : public ShellExternalInterface { } Literal getImportedFunction(Function* import) override { - if (linkedInstances.count(import->module)) { + if (linkedInstances.contains(import->module)) { return getImportInstance(import)->getExportedFunction(import->base); } auto f = [import, this](const Literals& arguments) -> Flow { diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 077e6a0d9e3..8dc2b54d1a8 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -2247,7 +2247,7 @@ void TranslateToFuzzReader::fixAfterChanges(Function* func) { // Note all scope names, and fix up all uses. BranchUtils::operateOnScopeNameDefs(curr, [&](Name& name) { if (name.is()) { - if (seen.count(name)) { + if (seen.contains(name)) { replace(); } else { seen.insert(name); @@ -2848,7 +2848,7 @@ Expression* TranslateToFuzzReader::makeTry(Type type) { addTag(); } auto* tag = pick(exceptionTags); - if (usedTags.count(tag)) { + if (usedTags.contains(tag)) { continue; } usedTags.insert(tag); diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp index 4fef0da80c8..426a9b76a9c 100644 --- a/src/tools/fuzzing/heap-types.cpp +++ b/src/tools/fuzzing/heap-types.cpp @@ -1095,7 +1095,7 @@ void Inhabitator::breakNonNullableCycles() { }; for (auto root : types) { - if (visited.count(root)) { + if (visited.contains(root)) { continue; } assert(visiting.size() == 0); @@ -1106,7 +1106,7 @@ void Inhabitator::breakNonNullableCycles() { // We may have visited this type again after searching through a // descriptor backedge. If we've already finished visiting this type on // that later visit, we don't need to continue this earlier visit. - if (visited.count(curr)) { + if (visited.contains(curr)) { finishType(); continue; } @@ -1126,7 +1126,7 @@ void Inhabitator::breakNonNullableCycles() { } // Skip references that we have already marked nullable to satisfy // subtyping constraints. - if (nullables.count({curr, index})) { + if (nullables.contains({curr, index})) { ++index; continue; } @@ -1134,7 +1134,7 @@ void Inhabitator::breakNonNullableCycles() { // visited the full graph reachable from such references, so we know // they cannot cycle back to anything we are currently visiting. auto heapType = children[index].getHeapType(); - if (visited.count(heapType)) { + if (visited.contains(heapType)) { ++index; continue; } @@ -1196,7 +1196,7 @@ std::vector Inhabitator::build() { if (auto it = typeIndices.find(heapType); it != typeIndices.end()) { heapType = builder[it->second]; } - if (nullables.count(pos)) { + if (nullables.contains(pos)) { nullability = Nullable; } type = builder.getTempRefType(heapType, nullability, exactness); @@ -1352,7 +1352,7 @@ bool isUninhabitable(HeapType type, case HeapTypeKind::Array: break; } - if (visited.count(type)) { + if (visited.contains(type)) { return false; } auto [it, inserted] = visiting.insert(type); diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index b11e9e928fc..78c12a5aa41 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -764,7 +764,7 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { } if (auto* get = child->dynCast()) { - if (!readableGlobals.count(get->name)) { + if (!readableGlobals.contains(get->name)) { // This get cannot be read - it is a global that appears after // us - and so we must fix it up, using the method mentioned // before (setting it to null now, and later in the start @@ -1417,7 +1417,7 @@ void evalCtors(Module& wasm, // time and undo any side effects here. Instead, if we will need the // export, disallow things that can block serialization, if we may end up // needing to serialize. - bool keeping = keptExportsSet.count(ctor); + bool keeping = keptExportsSet.contains(ctor); if (!keeping) { instance.allowContNew = true; } else { @@ -1631,7 +1631,7 @@ int main(int argc, const char* argv[]) { } } - if (options.extra.count("output") > 0) { + if (options.extra.contains("output")) { if (options.debug) { std::cout << "writing..." << std::endl; } diff --git a/src/tools/wasm-merge.cpp b/src/tools/wasm-merge.cpp index 295b0b2d8b0..24615804da1 100644 --- a/src/tools/wasm-merge.cpp +++ b/src/tools/wasm-merge.cpp @@ -251,7 +251,7 @@ void updateNames(Module& wasm, KindNameUpdates& kindNameUpdates) { if (iter == updates.end()) { return name; } - if (visited.count(name)) { + if (visited.contains(name)) { // This is a loop of imports, which means we cannot resolve a useful // name. Report an error. Fatal() << "wasm-merge: infinite loop of imports on " << oldName; @@ -451,7 +451,7 @@ void fuseImportsAndExports(const PassOptions& options) { for (auto& ex : merged.exports) { // skip type exports if (auto* name = ex->getInternalName()) { - assert(exportModuleMap.count(ex.get())); + assert(exportModuleMap.contains(ex.get())); ExportInfo& exportInfo = exportModuleMap[ex.get()]; kindModuleExportMaps[ex->kind][exportInfo.moduleName] [exportInfo.baseName] = *name; @@ -670,7 +670,7 @@ Input source maps can be specified by adding an -ism option right after the modu [&](Options* o, const std::string& argument) { size_t pos = inputFiles.size(); if (pos == 0 || pos != inputFileNames.size() || - inputSourceMapFilenames.count(pos - 1)) { + inputSourceMapFilenames.contains(pos - 1)) { std::cerr << "Option '-ism " << argument << "' should be right after the module name\n"; exit(EXIT_FAILURE); @@ -867,7 +867,7 @@ Input source maps can be specified by adding an -ism option right after the modu } } - if (options.extra.count("output") > 0) { + if (options.extra.contains("output")) { ModuleWriter writer(options.passOptions); writer.setBinary(emitBinary); writer.setDebugInfo(debugInfo); diff --git a/src/tools/wasm-metadce.cpp b/src/tools/wasm-metadce.cpp index dab2b1f2758..96b2063df4b 100644 --- a/src/tools/wasm-metadce.cpp +++ b/src/tools/wasm-metadce.cpp @@ -658,7 +658,7 @@ int main(int argc, const char* argv[]) { // Apply to the wasm graph.apply(); - if (options.extra.count("output") > 0) { + if (options.extra.contains("output")) { ModuleWriter writer(options.passOptions); writer.setBinary(emitBinary); writer.setDebugInfo(debugInfo); diff --git a/src/tools/wasm-opt.cpp b/src/tools/wasm-opt.cpp index d3ba797a674..4dd58db122d 100644 --- a/src/tools/wasm-opt.cpp +++ b/src/tools/wasm-opt.cpp @@ -393,7 +393,7 @@ For more on how to optimize effectively, see std::string firstOutput; - if (extraFuzzCommand.size() > 0 && options.extra.count("output") > 0) { + if (extraFuzzCommand.size() > 0 && options.extra.contains("output")) { BYN_TRACE("writing binary before opts, for extra fuzz command...\n"); ModuleWriter writer(options.passOptions); writer.setBinary(emitBinary); @@ -464,7 +464,7 @@ For more on how to optimize effectively, see printStackIR(std::cout, &wasm, options.passOptions); } - if (options.extra.count("output") == 0) { + if (!options.extra.contains("output")) { if (!options.quiet) { bool printsToStdout = std::any_of( options.passes.begin(), diff --git a/src/tools/wasm-reduce/wasm-reduce.cpp b/src/tools/wasm-reduce/wasm-reduce.cpp index 03249baae0d..bc5dabfcab0 100644 --- a/src/tools/wasm-reduce/wasm-reduce.cpp +++ b/src/tools/wasm-reduce/wasm-reduce.cpp @@ -918,8 +918,7 @@ struct Reducer << numFuncs << ")\n"; for (size_t x = 0; x < functionNames.size(); x++) { size_t i = (base + x) % numFuncs; - if (!justReduced && - functionsWeTriedToRemove.count(functionNames[i]) == 1 && + if (!justReduced && functionsWeTriedToRemove.contains(functionNames[i]) && !shouldTryToReduce(std::max((factor / 5) + 1, 20000))) { continue; } @@ -1102,17 +1101,18 @@ struct Reducer } } void visitCall(Call* curr) { - if (names.count(curr->target)) { + if (names.contains(curr->target)) { replaceCurrent(Builder(*getModule()).replaceWithIdenticalType(curr)); } } void visitRefFunc(RefFunc* curr) { - if (names.count(curr->func)) { + if (names.contains(curr->func)) { replaceCurrent(Builder(*getModule()).replaceWithIdenticalType(curr)); } } void visitExport(Export* curr) { - if (auto* name = curr->getInternalName(); name && names.count(*name)) { + if (auto* name = curr->getInternalName(); + name && names.contains(*name)) { exportsToRemove.push_back(curr->name); } } diff --git a/src/tools/wasm-split/split-options.cpp b/src/tools/wasm-split/split-options.cpp index 2283685c5df..dcea3bcf227 100644 --- a/src/tools/wasm-split/split-options.cpp +++ b/src/tools/wasm-split/split-options.cpp @@ -465,7 +465,7 @@ bool WasmSplitOptions::validate() { // Validate that all used options are allowed in the current mode. for (std::string& opt : usedOptions) { - if (!validOptions[static_cast(mode)].count(opt)) { + if (!validOptions[static_cast(mode)].contains(opt)) { std::stringstream msg; msg << "Option " << opt << " cannot be used in " << mode << " mode."; fail(msg.str()); diff --git a/src/tools/wasm-split/wasm-split.cpp b/src/tools/wasm-split/wasm-split.cpp index f655d6f0104..fd53dd18b5e 100644 --- a/src/tools/wasm-split/wasm-split.cpp +++ b/src/tools/wasm-split/wasm-split.cpp @@ -296,7 +296,7 @@ void splitModule(const WasmSplitOptions& options) { } continue; } - if (!options.quiet && options.keepFuncs.count(func)) { + if (!options.quiet && options.keepFuncs.contains(func)) { std::cerr << "warning: function " << func << " was to be both kept and split. It will be split.\n"; } @@ -337,7 +337,7 @@ void splitModule(const WasmSplitOptions& options) { #ifndef NDEBUG // Check that all defined functions are in one set or the other. ModuleUtils::iterDefinedFunctions(wasm, [&](Function* func) { - assert(keepFuncs.count(func->name) || splitFuncs.count(func->name)); + assert(keepFuncs.contains(func->name) || splitFuncs.contains(func->name)); }); #endif // NDEBUG @@ -423,7 +423,7 @@ void multiSplitModule(const WasmSplitOptions& options) { Fatal() << "Module name is empty\n"; } } - if (moduleNameSet.count(name)) { + if (moduleNameSet.contains(name)) { Fatal() << "Module name " << name << " is listed more than once\n"; } currModule = name; diff --git a/src/tools/wasm2js.cpp b/src/tools/wasm2js.cpp index 03be0f7132a..3612b9194bb 100644 --- a/src/tools/wasm2js.cpp +++ b/src/tools/wasm2js.cpp @@ -454,7 +454,7 @@ static void optimizeJS(Ref ast, Wasm2JSBuilder::Flags flags) { breakCapturers.push_back(node); continueCapturers.push_back(node); } else if (node[0] == cashew::BLOCK) { - if (labelled.count(node.get())) { + if (labelled.contains(node.get())) { // Cannot break to a block without the label. breakCapturers.push_back(Ref(&INVALID)); } @@ -473,7 +473,7 @@ static void optimizeJS(Ref ast, Wasm2JSBuilder::Flags flags) { breakCapturers.pop_back(); continueCapturers.pop_back(); } else if (node[0] == cashew::BLOCK) { - if (labelled.count(node.get())) { + if (labelled.contains(node.get())) { breakCapturers.pop_back(); } } else if (node[0] == SWITCH) { @@ -481,7 +481,7 @@ static void optimizeJS(Ref ast, Wasm2JSBuilder::Flags flags) { } else if (node[0] == BREAK || node[0] == CONTINUE) { if (!node[1]->isNull()) { auto label = node[1]->getIString(); - assert(labelToValue.count(label)); + assert(labelToValue.contains(label)); auto& capturers = node[0] == BREAK ? breakCapturers : continueCapturers; assert(!capturers.empty()); @@ -508,7 +508,7 @@ static void optimizeJS(Ref ast, Wasm2JSBuilder::Flags flags) { } } else if (node[0] == LABEL) { auto label = node[1]->getIString(); - if (usedLabelNames.count(label)) { + if (usedLabelNames.contains(label)) { // It's used; just erase it from the data structure. usedLabelNames.erase(label); } else { diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index a38b76a9771..5b6990ea57b 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -4155,7 +4155,7 @@ class ModuleRunnerBase : public ExpressionRunner { Address sizeVal(uint32_t(size.getSingleValue().geti32())); if (offsetVal + sizeVal > 0 && - droppedElementSegments.count(curr->segment)) { + droppedElementSegments.contains(curr->segment)) { trap("out of bounds segment access in table.init"); } if (offsetVal + sizeVal > segment->data.size()) { @@ -4573,7 +4573,8 @@ class ModuleRunnerBase : public ExpressionRunner { Address offsetVal(offset.getSingleValue().getUnsigned()); Address sizeVal(size.getSingleValue().getUnsigned()); - if (offsetVal + sizeVal > 0 && droppedDataSegments.count(curr->segment)) { + if (offsetVal + sizeVal > 0 && + droppedDataSegments.contains(curr->segment)) { trap("out of bounds segment access in memory.init"); } if (offsetVal + sizeVal > segment->data.size()) { @@ -4690,7 +4691,7 @@ class ModuleRunnerBase : public ExpressionRunner { if (std::ckd_add(&end, offset, size * elemBytes) || end > seg.data.size()) { trap("out of bounds segment access in array.new_data"); } - if (droppedDataSegments.count(curr->segment) && end > 0) { + if (droppedDataSegments.contains(curr->segment) && end > 0) { trap("dropped segment access in array.new_data"); } contents.reserve(size); @@ -4717,7 +4718,7 @@ class ModuleRunnerBase : public ExpressionRunner { if (end > seg.data.size()) { trap("out of bounds segment access in array.new_elem"); } - if (end > 0 && droppedElementSegments.count(curr->segment)) { + if (end > 0 && droppedElementSegments.contains(curr->segment)) { trap("out of bounds segment access in array.new_elem"); } contents.reserve(size); @@ -4754,7 +4755,8 @@ class ModuleRunnerBase : public ExpressionRunner { if (offsetVal + readSize > seg->data.size()) { trap("out of bounds segment access in array.init_data"); } - if (offsetVal + sizeVal > 0 && droppedDataSegments.count(curr->segment)) { + if (offsetVal + sizeVal > 0 && + droppedDataSegments.contains(curr->segment)) { trap("out of bounds segment access in array.init_data"); } for (size_t i = 0; i < sizeVal; i++) { @@ -4788,7 +4790,7 @@ class ModuleRunnerBase : public ExpressionRunner { if (max > seg->data.size()) { trap("out of bounds segment access in array.init_elem"); } - if (max > 0 && droppedElementSegments.count(curr->segment)) { + if (max > 0 && droppedElementSegments.contains(curr->segment)) { trap("out of bounds segment access in array.init_elem"); } for (size_t i = 0; i < sizeVal; i++) { diff --git a/src/wasm-type-printing.h b/src/wasm-type-printing.h index a44e949dfc3..483c48cf0a3 100644 --- a/src/wasm-type-printing.h +++ b/src/wasm-type-printing.h @@ -48,7 +48,9 @@ template struct TypeNameGeneratorBase { private: constexpr void assertValidUsage() { -#if !defined(__GNUC__) || __GNUC__ >= 14 + // This check current causes a crash on MSVC + // TODO: Convert to C++20 requires check +#if !defined(_MSC_VER) && (!defined(__GNUC__) || __GNUC__ >= 14) // Check that the subclass provides `getNames` with the correct type. using Self = TypeNameGeneratorBase; static_assert( diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 0a8bd96ddd8..8f3d7600457 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1019,7 +1019,7 @@ void WasmBinaryWriter::writeNames() { { std::vector namedTypes; for (auto type : indexedTypes.types) { - if (wasm->typeNames.count(type) && wasm->typeNames[type].name.is()) { + if (wasm->typeNames.contains(type) && wasm->typeNames[type].name.is()) { namedTypes.push_back(type); } } @@ -1170,7 +1170,7 @@ void WasmBinaryWriter::writeNames() { if (wasm->features.hasGC()) { std::vector relevantTypes; for (auto& type : indexedTypes.types) { - if (type.isStruct() && wasm->typeNames.count(type) && + if (type.isStruct() && wasm->typeNames.contains(type) && !wasm->typeNames[type].fieldNames.empty()) { relevantTypes.push_back(type); } @@ -1613,7 +1613,7 @@ void WasmBinaryWriter::trackExpressionStart(Expression* curr, Function* func) { // track locations of instructions that have code annotations, as their binary // location goes in the custom section. if (func && (!func->expressionLocations.empty() || - func->codeAnnotations.count(curr))) { + func->codeAnnotations.contains(curr))) { binaryLocations.expressions[curr] = BinaryLocations::Span{BinaryLocation(o.size()), 0}; binaryLocationTrackedExpressionsForFunc.push_back(curr); diff --git a/src/wasm/wasm-debug.cpp b/src/wasm/wasm-debug.cpp index 0da9788eb89..c9d3e533311 100644 --- a/src/wasm/wasm-debug.cpp +++ b/src/wasm/wasm-debug.cpp @@ -434,9 +434,9 @@ struct AddrExprMap { private: void add(Expression* expr, const BinaryLocations::Span span) { - assert(startMap.count(span.start) == 0); + assert(!startMap.contains(span.start)); startMap[span.start] = expr; - assert(endMap.count(span.end) == 0); + assert(!endMap.contains(span.end)); endMap[span.end] = expr; } @@ -444,7 +444,7 @@ struct AddrExprMap { const BinaryLocations::DelimiterLocations& delimiter) { for (Index i = 0; i < delimiter.size(); i++) { if (delimiter[i] != 0) { - assert(delimiterMap.count(delimiter[i]) == 0); + assert(!delimiterMap.contains(delimiter[i])); delimiterMap[delimiter[i]] = DelimiterInfo{expr, i}; } } @@ -656,7 +656,7 @@ struct LocationUpdater { // Given an offset in .debug_loc, get the old and new compile unit bases. OldToNew getCompileUnitBasesForLoc(size_t offset) const { - if (locToUnitMap.count(offset) == 0) { + if (!locToUnitMap.contains(offset)) { // There is no compile unit for this loc. It doesn't matter what we set // here. return OldToNew{0, 0}; @@ -732,7 +732,7 @@ static void updateDebugLines(llvm::DWARFYAML::Data& data, if (newAddr && state.needToEmit()) { // LLVM sometimes emits the same address more than once. We should // probably investigate that. - if (newAddrInfo.count(newAddr)) { + if (newAddrInfo.contains(newAddr)) { continue; } newAddrs.push_back(newAddr); diff --git a/src/wasm/wasm-stack-opts.cpp b/src/wasm/wasm-stack-opts.cpp index 9f7273ba5b2..b3a4d15e26d 100644 --- a/src/wasm/wasm-stack-opts.cpp +++ b/src/wasm/wasm-stack-opts.cpp @@ -211,7 +211,7 @@ void StackIROptimizer::local2Stack() { // optimized when they are visited in the binary writer and this // optimization would intefere with that one. if (auto* get = inst->origin->dynCast(); - get && inst->type.isSingle() && !deferredGets.count(get)) { + get && inst->type.isSingle() && !deferredGets.contains(get)) { // Use another local to clarify what instIndex means in this scope. auto getIndex = instIndex; @@ -293,7 +293,7 @@ void StackIROptimizer::removeUnneededBlocks() { continue; } if (auto* block = inst->origin->dynCast()) { - if (!block->name.is() || !targets.count(block->name)) { + if (!block->name.is() || !targets.contains(block->name)) { // TODO optimize, maybe run remove-unused-names inst = nullptr; } diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 108f73edcab..496d15ca878 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -232,7 +232,7 @@ void BinaryInstWriter::visitBreak(Break* curr) { // stash the stack. std::vector typesOnStack; - auto needHandling = brIfsNeedingHandling.count(curr); + auto needHandling = brIfsNeedingHandling.contains(curr); if (needHandling) { // Tuples always need scratch locals. Uncastable types do as well, we we // can't fix them up below with a simple cast. @@ -305,7 +305,7 @@ void BinaryInstWriter::visitCallIndirect(CallIndirect* curr) { } void BinaryInstWriter::visitLocalGet(LocalGet* curr) { - if (deferredGets.count(curr)) { + if (deferredGets.contains(curr)) { // This local.get will be emitted as part of the instruction that consumes // it. return; @@ -2456,7 +2456,7 @@ void BinaryInstWriter::visitTupleMake(TupleMake* curr) { } void BinaryInstWriter::visitTupleExtract(TupleExtract* curr) { - if (extractedGets.count(curr->tuple)) { + if (extractedGets.contains(curr->tuple)) { // We already have just the extracted value on the stack. return; } @@ -3010,7 +3010,7 @@ void BinaryInstWriter::visitStringWTF16Get(StringWTF16Get* curr) { bool posDeferred = false; Index posIndex; if (auto* get = curr->pos->dynCast()) { - assert(deferredGets.count(get)); + assert(deferredGets.contains(get)); posDeferred = true; posIndex = mappedLocals[{get->index, 0}]; } else { @@ -3037,8 +3037,8 @@ void BinaryInstWriter::visitStringSliceWTF(StringSliceWTF* curr) { auto* startGet = curr->start->dynCast(); auto* endGet = curr->end->dynCast(); if (startGet && endGet) { - assert(deferredGets.count(startGet)); - assert(deferredGets.count(endGet)); + assert(deferredGets.contains(startGet)); + assert(deferredGets.contains(endGet)); deferred = true; startIndex = mappedLocals[{startGet->index, 0}]; endIndex = mappedLocals[{endGet->index, 0}]; diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 4faffb8017d..b7c2c8d2bd0 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -2494,7 +2494,7 @@ validateTypeInfo(HeapTypeInfo& info, if (auto* super = info.supertype) { // The supertype must be canonical (i.e. defined in a previous rec group) // or have already been defined in this rec group. - if (super->isTemp && !seenTypes.count(HeapType(uintptr_t(super)))) { + if (super->isTemp && !seenTypes.contains(HeapType(uintptr_t(super)))) { return TypeBuilder::ErrorReasonKind::ForwardSupertypeReference; } // The supertype must have a valid structure. @@ -2510,7 +2510,7 @@ validateTypeInfo(HeapTypeInfo& info, return TypeBuilder::ErrorReasonKind::NonStructDescribes; } assert(desc->isTemp && "unexpected canonical described type"); - if (!seenTypes.count(HeapType(uintptr_t(desc)))) { + if (!seenTypes.contains(HeapType(uintptr_t(desc)))) { return TypeBuilder::ErrorReasonKind::ForwardDescribesReference; } if (desc->descriptor != &info) { @@ -2649,7 +2649,7 @@ buildRecGroup(std::unique_ptr&& groupInfo, for (size_t i = 0; i < typeInfos.size(); ++i) { auto type = asHeapType(typeInfos[i]); for (auto child : type.getHeapTypeChildren()) { - if (isTemp(child) && !seenTypes.count(child)) { + if (isTemp(child) && !seenTypes.contains(child)) { return {TypeBuilder::Error{ i, TypeBuilder::ErrorReasonKind::ForwardChildReference}}; } diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index e1a13f9da15..3f472a6108d 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2768,14 +2768,14 @@ void FunctionValidator::visitElemDrop(ElemDrop* curr) { void FunctionValidator::noteDelegate(Name name, Expression* curr) { if (name != DELEGATE_CALLER_TARGET) { - shouldBeTrue(delegateTargetNames.count(name) != 0, + shouldBeTrue(delegateTargetNames.contains(name), curr, "all delegate targets must be valid"); } } void FunctionValidator::noteRethrow(Name name, Expression* curr) { - shouldBeTrue(rethrowTargetNames.count(name) != 0, + shouldBeTrue(rethrowTargetNames.contains(name), curr, "all rethrow targets must be valid"); } @@ -4447,7 +4447,7 @@ void FunctionValidator::validateResumeHandlers( // But we cannot check this here because we do not know what type the // block named $label expects. Save the tag to check when we visit the // block later. - if (!shouldBeTrue(breakTypes.count(labels[i]) != 0, + if (!shouldBeTrue(breakTypes.contains(labels[i]), curr, "all resume targets must be valid")) { return; @@ -4989,7 +4989,7 @@ void validateExports(Module& module, ValidationInfo& info) { WASM_UNREACHABLE("invalid ExternalKind"); } Name exportName = exp->name; - info.shouldBeFalse(exportNames.count(exportName) > 0, + info.shouldBeFalse(exportNames.contains(exportName), exportName, "module exports must be unique"); exportNames.insert(exportName); @@ -5023,7 +5023,7 @@ void validateGlobals(Module& module, ValidationInfo& info) { for (auto* get : FindAll(curr->init).list) { auto* global = module.getGlobalOrNull(get->name); info.shouldBeTrue( - global && (seen.count(global) || global->imported()), + global && (seen.contains(global) || global->imported()), curr->init, "global initializer should only refer to previous globals"); } diff --git a/src/wasm2js.h b/src/wasm2js.h index e95fd53f968..2de6e2287cc 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -273,7 +273,7 @@ class Wasm2JSBuilder { } auto mangled = asmangle(out.str()); ret = stringToIString(mangled); - if (scopeMangledNames.count(ret)) { + if (scopeMangledNames.contains(ret)) { // When export names collide things may be confusing, as this is // observable externally by the person using the JS. Report a warning. if (scope == NameScope::Export) { @@ -289,7 +289,7 @@ class Wasm2JSBuilder { // var bar = 0; // } // function bar() { .. - if (scope == NameScope::Local && topMangledNames.count(ret)) { + if (scope == NameScope::Local && topMangledNames.contains(ret)) { continue; } // We found a good name, use it. @@ -604,7 +604,7 @@ static bool needsQuoting(Name name) { } void Wasm2JSBuilder::ensureModuleVar(Ref ast, const Importable& imp) { - if (seenModuleImports.count(imp.module) > 0) { + if (seenModuleImports.contains(imp.module)) { return; } Ref theVar = ValueBuilder::makeVar(); @@ -889,7 +889,7 @@ Ref Wasm2JSBuilder::processFunction(Module* m, Ref ret = ValueBuilder::makeFunction(fromName(func->name, NameScope::Top)); // arguments bool needCoercions = options.optimizeLevel == 0 || standaloneFunction || - functionsCallableFromOutside.count(func->name); + functionsCallableFromOutside.contains(func->name); for (Index i = 0; i < func->getNumParams(); i++) { IString name = fromName(func->getLocalNameOrGeneric(i), NameScope::Local); ValueBuilder::appendArgumentToFunction(ret, name); @@ -996,7 +996,7 @@ Ref Wasm2JSBuilder::processExpression(Expression* curr, break; } // If we have already seen this block, stop here. - if (unneededExpressions.count(block)) { + if (unneededExpressions.contains(block)) { // XXX FIXME we should probably abort the entire optimization break; } @@ -1025,7 +1025,7 @@ Ref Wasm2JSBuilder::processExpression(Expression* curr, } namesBranchedTo.insert(newBranches.begin(), newBranches.end()); } - if (namesBranchedTo.count(block->name)) { + if (namesBranchedTo.contains(block->name)) { break; } // We can move code after the child (reached by branching on the @@ -1151,7 +1151,7 @@ Ref Wasm2JSBuilder::processExpression(Expression* curr, // Visitors Ref visitBlock(Block* curr) { - if (switchProcessor.unneededExpressions.count(curr)) { + if (switchProcessor.unneededExpressions.contains(curr)) { // We have had our tail hoisted into a switch that is nested in our // first position, so we don't need to emit that code again, or // ourselves in fact. @@ -1201,7 +1201,7 @@ Ref Wasm2JSBuilder::processExpression(Expression* curr, } Ref makeBreakOrContinue(Name name) { - if (continueLabels.count(name)) { + if (continueLabels.contains(name)) { return ValueBuilder::makeContinue(fromName(name, NameScope::Label)); } else { return ValueBuilder::makeBreak(fromName(name, NameScope::Label)); @@ -1275,7 +1275,7 @@ Ref Wasm2JSBuilder::processExpression(Expression* curr, // Emit any remaining groups by just emitting branches to their code, // which will appear outside the switch. for (auto& [target, indexes] : targetIndexes) { - if (emittedTargets.count(target)) { + if (emittedTargets.contains(target)) { continue; } stopFurtherFallthrough(); @@ -1294,7 +1294,7 @@ Ref Wasm2JSBuilder::processExpression(Expression* curr, // TODO: if the group the default is in is not the largest, we can turn // the largest into // the default by using a local and a check on the range - if (!emittedTargets.count(curr->default_)) { + if (!emittedTargets.contains(curr->default_)) { stopFurtherFallthrough(); ValueBuilder::appendDefaultToSwitch(theSwitch); ValueBuilder::appendCodeToSwitch( @@ -2007,7 +2007,7 @@ Ref Wasm2JSBuilder::processExpression(Expression* curr, Ref val = visit(curr->value, EXPRESSION_RESULT); bool needCoercion = parent->options.optimizeLevel == 0 || standaloneFunction || - parent->functionsCallableFromOutside.count(func->name); + parent->functionsCallableFromOutside.contains(func->name); if (needCoercion) { val = makeJsCoercion(val, wasmToJsType(curr->value->type)); } @@ -2718,12 +2718,12 @@ void Wasm2JSGlue::emitPreES6() { // Right now codegen requires a flat namespace going into the module, // meaning we don't support importing the same name from multiple namespaces // yet. - if (baseModuleMap.count(base) && baseModuleMap[base] != module) { + if (baseModuleMap.contains(base) && baseModuleMap[base] != module) { Fatal() << "the name " << base << " cannot be imported from " << "two different modules yet"; } baseModuleMap[base] = module; - if (seenModules.count(module) == 0) { + if (!seenModules.contains(module)) { out << "import * as " << asmangle(module.toString()) << " from '" << module << "';\n"; seenModules.insert(module); @@ -2785,7 +2785,7 @@ void Wasm2JSGlue::emitPostES6() { if (ABI::wasm2js::isHelper(import->base)) { return; } - if (seenModules.count(import->module) > 0) { + if (seenModules.contains(import->module)) { return; } out << " \"" << import->module @@ -2811,7 +2811,7 @@ void Wasm2JSGlue::emitPostES6() { if (ABI::wasm2js::isHelper(import->base)) { return; } - if (seenModules.count(import->module) > 0) { + if (seenModules.contains(import->module)) { return; } out << " \"" << import->module