diff --git a/.gitignore b/.gitignore index 95af1a39719..b88109b38e0 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,5 @@ CMakeUserPresets.json # files related to clangd cache .cache/* + +.venv/ diff --git a/src/ir/effects.h b/src/ir/effects.h index e8ab4c8ef69..af866b9e536 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -18,6 +18,7 @@ #define wasm_ir_effects_h #include +#include #include "ir/intrinsics.h" #include "pass.h" @@ -141,8 +142,8 @@ class EffectAnalyzer { std::set localsRead; std::set localsWritten; - std::set mutableGlobalsRead; - std::set globalsWritten; + std::unordered_set mutableGlobalsRead; + std::unordered_set globalsWritten; // The nested depth of try-catch_all. If an instruction that may throw is // inside an inner try-catch_all, we don't mark it as 'throws_', because it @@ -513,8 +514,8 @@ class EffectAnalyzer { return hasAnything(); } - std::set breakTargets; - std::set delegateTargets; + std::unordered_set breakTargets; + std::unordered_set delegateTargets; private: struct InternalAnalyzer diff --git a/src/passes/CodeFolding.cpp b/src/passes/CodeFolding.cpp index c4a7804695c..429cdf5e391 100644 --- a/src/passes/CodeFolding.cpp +++ b/src/passes/CodeFolding.cpp @@ -55,7 +55,8 @@ // to the same thing, and after merging it can still reach it). // -#include +#include +#include #include "ir/branch-utils.h" #include "ir/effects.h" @@ -74,9 +75,9 @@ static const Index WORTH_ADDING_BLOCK_TO_REMOVE_THIS_MUCH = 3; struct ExpressionMarker : public PostWalker> { - std::set& marked; + std::unordered_set& marked; - ExpressionMarker(std::set& marked, Expression* expr) + ExpressionMarker(std::unordered_set& marked, Expression* expr) : marked(marked) { walk(expr); } @@ -122,13 +123,16 @@ struct CodeFolding // pass state - std::map> breakTails; // break target name => tails - // that reach it + std::unordered_map> + breakTails; // break target name => tails + // that reach it std::vector unreachableTails; // tails leading to (unreachable) std::vector returnTails; // tails leading to (return) - std::set unoptimizables; // break target names that we can't handle - std::set modifieds; // modified code should not be processed - // again, wait for next pass + std::unordered_set + unoptimizables; // break target names that we can't handle + std::unordered_set + modifieds; // modified code should not be processed + // again, wait for next pass // walking @@ -308,13 +312,14 @@ struct CodeFolding auto allTargets = BranchUtils::getBranchTargets(outOf); for (auto* item : items) { auto exiting = BranchUtils::getExitingBranches(item); - std::vector intersection; - std::set_intersection(allTargets.begin(), - allTargets.end(), - exiting.begin(), - exiting.end(), - std::back_inserter(intersection)); - if (intersection.size() > 0) { + bool hasIntersection = false; + for (auto& name : exiting) { + if (allTargets.count(name)) { + hasIntersection = true; + break; + } + } + if (hasIntersection) { // anything exiting that is in all targets is something bad return false; } @@ -644,9 +649,10 @@ struct CodeFolding if (next.size() >= 2) { // now we want to find a mergeable item - any item that is equal among a // subset - std::map hashes; // expression => hash value + std::unordered_map + hashes; // expression => hash value // hash value => expressions with that hash - std::map> hashed; + std::unordered_map> hashed; for (auto& tail : next) { auto* item = getItem(tail, num); auto hash = hashes[item] = ExpressionAnalyzer::hash(item); @@ -654,7 +660,7 @@ struct CodeFolding } // look at each hash value exactly once. we do this in a deterministic // order by iterating over a vector retaining insertion order. - std::set seen; + std::unordered_set seen; for (auto& tail : next) { auto* item = getItem(tail, num); auto digest = hashes[item];