Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,5 @@ CMakeUserPresets.json

# files related to clangd cache
.cache/*

.venv/
9 changes: 5 additions & 4 deletions src/ir/effects.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define wasm_ir_effects_h

#include <cassert>
#include <unordered_set>

#include "ir/intrinsics.h"
#include "pass.h"
Expand Down Expand Up @@ -141,8 +142,8 @@ class EffectAnalyzer {

std::set<Index> localsRead;
std::set<Index> localsWritten;
std::set<Name> mutableGlobalsRead;
std::set<Name> globalsWritten;
std::unordered_set<Name> mutableGlobalsRead;
std::unordered_set<Name> 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
Expand Down Expand Up @@ -513,8 +514,8 @@ class EffectAnalyzer {
return hasAnything();
}

std::set<Name> breakTargets;
std::set<Name> delegateTargets;
std::unordered_set<Name> breakTargets;
std::unordered_set<Name> delegateTargets;

private:
struct InternalAnalyzer
Expand Down
42 changes: 24 additions & 18 deletions src/passes/CodeFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
// to the same thing, and after merging it can still reach it).
//

#include <iterator>
#include <unordered_map>
#include <unordered_set>

#include "ir/branch-utils.h"
#include "ir/effects.h"
Expand All @@ -74,9 +75,9 @@ static const Index WORTH_ADDING_BLOCK_TO_REMOVE_THIS_MUCH = 3;
struct ExpressionMarker
: public PostWalker<ExpressionMarker,
UnifiedExpressionVisitor<ExpressionMarker>> {
std::set<Expression*>& marked;
std::unordered_set<Expression*>& marked;

ExpressionMarker(std::set<Expression*>& marked, Expression* expr)
ExpressionMarker(std::unordered_set<Expression*>& marked, Expression* expr)
: marked(marked) {
walk(expr);
}
Expand Down Expand Up @@ -122,13 +123,16 @@ struct CodeFolding

// pass state

std::map<Name, std::vector<Tail>> breakTails; // break target name => tails
// that reach it
std::unordered_map<Name, std::vector<Tail>>
breakTails; // break target name => tails
// that reach it
std::vector<Tail> unreachableTails; // tails leading to (unreachable)
std::vector<Tail> returnTails; // tails leading to (return)
std::set<Name> unoptimizables; // break target names that we can't handle
std::set<Expression*> modifieds; // modified code should not be processed
// again, wait for next pass
std::unordered_set<Name>
unoptimizables; // break target names that we can't handle
std::unordered_set<Expression*>
modifieds; // modified code should not be processed
// again, wait for next pass

// walking

Expand Down Expand Up @@ -308,13 +312,14 @@ struct CodeFolding
auto allTargets = BranchUtils::getBranchTargets(outOf);
for (auto* item : items) {
auto exiting = BranchUtils::getExitingBranches(item);
std::vector<Name> 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;
}
Expand Down Expand Up @@ -644,17 +649,18 @@ struct CodeFolding
if (next.size() >= 2) {
// now we want to find a mergeable item - any item that is equal among a
// subset
std::map<Expression*, size_t> hashes; // expression => hash value
std::unordered_map<Expression*, size_t>
hashes; // expression => hash value
// hash value => expressions with that hash
std::map<size_t, std::vector<Expression*>> hashed;
std::unordered_map<size_t, std::vector<Expression*>> hashed;
for (auto& tail : next) {
auto* item = getItem(tail, num);
auto hash = hashes[item] = ExpressionAnalyzer::hash(item);
hashed[hash].push_back(item);
}
// look at each hash value exactly once. we do this in a deterministic
// order by iterating over a vector retaining insertion order.
std::set<size_t> seen;
std::unordered_set<size_t> seen;
for (auto& tail : next) {
auto* item = getItem(tail, num);
auto digest = hashes[item];
Expand Down
Loading