summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binaryen-c.cpp7
-rw-r--r--src/binaryen-c.h2
-rw-r--r--src/ir/effects.h20
-rw-r--r--src/ir/local-utils.h16
-rw-r--r--src/ir/ordering.h2
-rw-r--r--src/ir/properties.h8
-rw-r--r--src/js/binaryen.js-post.js4
-rw-r--r--src/passes/AvoidReinterprets.cpp17
-rw-r--r--src/passes/CodePushing.cpp15
-rw-r--r--src/passes/ConstantFieldPropagation.cpp3
-rw-r--r--src/passes/Heap2Local.cpp4
-rw-r--r--src/passes/OptimizeAddedConstants.cpp3
-rw-r--r--src/passes/OptimizeInstructions.cpp32
-rw-r--r--src/passes/Precompute.cpp2
-rw-r--r--src/passes/SimplifyLocals.cpp2
15 files changed, 54 insertions, 83 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index 35e39142b..15c4cb90e 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -4329,10 +4329,9 @@ BinaryenSideEffects BinaryenSideEffectAny(void) {
return static_cast<BinaryenSideEffects>(EffectAnalyzer::SideEffects::Any);
}
-BinaryenSideEffects
-BinaryenExpressionGetSideEffects(BinaryenExpressionRef expr,
- BinaryenFeatures features) {
- return EffectAnalyzer(globalPassOptions, features, (Expression*)expr)
+BinaryenSideEffects BinaryenExpressionGetSideEffects(BinaryenExpressionRef expr,
+ BinaryenModuleRef module) {
+ return EffectAnalyzer(globalPassOptions, *(Module*)module, (Expression*)expr)
.getSideEffects();
}
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index d46e971b5..dc8bb890f 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -2628,7 +2628,7 @@ BINARYEN_API BinaryenSideEffects BinaryenSideEffectDanglingPop(void);
BINARYEN_API BinaryenSideEffects BinaryenSideEffectAny(void);
BINARYEN_API BinaryenSideEffects BinaryenExpressionGetSideEffects(
- BinaryenExpressionRef expr, BinaryenFeatures features);
+ BinaryenExpressionRef expr, BinaryenModuleRef module);
//
// ========== CFG / Relooper ==========
diff --git a/src/ir/effects.h b/src/ir/effects.h
index d34f8e5b2..3f0f78e6f 100644
--- a/src/ir/effects.h
+++ b/src/ir/effects.h
@@ -27,17 +27,6 @@ namespace wasm {
class EffectAnalyzer {
public:
EffectAnalyzer(const PassOptions& passOptions,
- FeatureSet features,
- Expression* ast = nullptr)
- : ignoreImplicitTraps(passOptions.ignoreImplicitTraps),
- trapsNeverHappen(passOptions.trapsNeverHappen),
- debugInfo(passOptions.debugInfo), module(nullptr), features(features) {
- if (ast) {
- walk(ast);
- }
- }
-
- EffectAnalyzer(const PassOptions& passOptions,
Module& module,
Expression* ast = nullptr)
: ignoreImplicitTraps(passOptions.ignoreImplicitTraps),
@@ -685,15 +674,6 @@ public:
// Helpers
static bool canReorder(const PassOptions& passOptions,
- FeatureSet features,
- Expression* a,
- Expression* b) {
- EffectAnalyzer aEffects(passOptions, features, a);
- EffectAnalyzer bEffects(passOptions, features, b);
- return !aEffects.invalidates(bEffects);
- }
-
- static bool canReorder(const PassOptions& passOptions,
Module& module,
Expression* a,
Expression* b) {
diff --git a/src/ir/local-utils.h b/src/ir/local-utils.h
index 0eba31889..73d065e73 100644
--- a/src/ir/local-utils.h
+++ b/src/ir/local-utils.h
@@ -45,23 +45,21 @@ struct UnneededSetRemover : public PostWalker<UnneededSetRemover> {
PassOptions& passOptions;
LocalGetCounter* localGetCounter = nullptr;
- FeatureSet features;
+ Module& module;
- UnneededSetRemover(Function* func,
- PassOptions& passOptions,
- FeatureSet features)
- : passOptions(passOptions), features(features) {
+ UnneededSetRemover(Function* func, PassOptions& passOptions, Module& module)
+ : passOptions(passOptions), module(module) {
LocalGetCounter counter(func);
- UnneededSetRemover inner(counter, func, passOptions, features);
+ UnneededSetRemover inner(counter, func, passOptions, module);
removed = inner.removed;
}
UnneededSetRemover(LocalGetCounter& localGetCounter,
Function* func,
PassOptions& passOptions,
- FeatureSet features)
+ Module& module)
: passOptions(passOptions), localGetCounter(&localGetCounter),
- features(features) {
+ module(module) {
walk(func->body);
}
@@ -96,7 +94,7 @@ struct UnneededSetRemover : public PostWalker<UnneededSetRemover> {
auto* value = set->value;
if (set->isTee()) {
replaceCurrent(value);
- } else if (EffectAnalyzer(passOptions, features, set->value)
+ } else if (EffectAnalyzer(passOptions, module, set->value)
.hasSideEffects()) {
Drop* drop = ExpressionManipulator::convert<LocalSet, Drop>(set);
drop->value = value;
diff --git a/src/ir/ordering.h b/src/ir/ordering.h
index 8e178dd35..55163759c 100644
--- a/src/ir/ordering.h
+++ b/src/ir/ordering.h
@@ -43,7 +43,7 @@ Expression* getResultOfFirst(Expression* first,
Builder builder(*wasm);
- if (EffectAnalyzer::canReorder(passOptions, wasm->features, first, second)) {
+ if (EffectAnalyzer::canReorder(passOptions, *wasm, first, second)) {
return builder.makeSequence(second, first);
}
diff --git a/src/ir/properties.h b/src/ir/properties.h
index 2e3f94a06..1640ca814 100644
--- a/src/ir/properties.h
+++ b/src/ir/properties.h
@@ -254,7 +254,7 @@ inline Index getZeroExtBits(Expression* curr) {
// TODO: Receive a Module instead of FeatureSet, to pass to EffectAnalyzer?
inline Expression* getImmediateFallthrough(Expression* curr,
const PassOptions& passOptions,
- FeatureSet features) {
+ Module& module) {
// If the current node is unreachable, there is no value
// falling through.
if (curr->type == Type::unreachable) {
@@ -285,7 +285,7 @@ inline Expression* getImmediateFallthrough(Expression* curr,
return br->value;
}
} else if (auto* tryy = curr->dynCast<Try>()) {
- if (!EffectAnalyzer(passOptions, features, tryy->body).throws) {
+ if (!EffectAnalyzer(passOptions, module, tryy->body).throws) {
return tryy->body;
}
} else if (auto* as = curr->dynCast<RefCast>()) {
@@ -302,9 +302,9 @@ inline Expression* getImmediateFallthrough(Expression* curr,
// find the final value that falls through.
inline Expression* getFallthrough(Expression* curr,
const PassOptions& passOptions,
- FeatureSet features) {
+ Module& module) {
while (1) {
- auto* next = getImmediateFallthrough(curr, passOptions, features);
+ auto* next = getImmediateFallthrough(curr, passOptions, module);
if (next == curr) {
return curr;
}
diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js
index 645290478..a91d5af31 100644
--- a/src/js/binaryen.js-post.js
+++ b/src/js/binaryen.js-post.js
@@ -3128,8 +3128,8 @@ Module['getExpressionInfo'] = function(expr) {
};
// Gets the side effects of the specified expression
-Module['getSideEffects'] = function(expr, features) {
- return Module['_BinaryenExpressionGetSideEffects'](expr, features);
+Module['getSideEffects'] = function(expr, module) {
+ return Module['_BinaryenExpressionGetSideEffects'](expr, module);
};
Module['createType'] = function(types) {
diff --git a/src/passes/AvoidReinterprets.cpp b/src/passes/AvoidReinterprets.cpp
index cc5871a2a..d1030f89e 100644
--- a/src/passes/AvoidReinterprets.cpp
+++ b/src/passes/AvoidReinterprets.cpp
@@ -40,7 +40,7 @@ static bool canReplaceWithReinterpret(Load* load) {
static Load* getSingleLoad(LocalGraph* localGraph,
LocalGet* get,
const PassOptions& passOptions,
- FeatureSet features) {
+ Module& module) {
std::set<LocalGet*> seen;
seen.insert(get);
while (1) {
@@ -52,7 +52,7 @@ static Load* getSingleLoad(LocalGraph* localGraph,
if (!set) {
return nullptr;
}
- auto* value = Properties::getFallthrough(set->value, passOptions, features);
+ auto* value = Properties::getFallthrough(set->value, passOptions, module);
if (auto* parentGet = value->dynCast<LocalGet>()) {
if (seen.count(parentGet)) {
// We are in a cycle of gets, in unreachable code.
@@ -102,12 +102,11 @@ struct AvoidReinterprets : public WalkerPass<PostWalker<AvoidReinterprets>> {
void visitUnary(Unary* curr) {
if (isReinterpret(curr)) {
- FeatureSet features = getModule()->features;
- if (auto* get =
- Properties::getFallthrough(curr->value, getPassOptions(), features)
- ->dynCast<LocalGet>()) {
+ if (auto* get = Properties::getFallthrough(
+ curr->value, getPassOptions(), *getModule())
+ ->dynCast<LocalGet>()) {
if (auto* load =
- getSingleLoad(localGraph, get, getPassOptions(), features)) {
+ getSingleLoad(localGraph, get, getPassOptions(), *getModule())) {
auto& info = infos[load];
info.reinterpreted = true;
}
@@ -156,8 +155,8 @@ struct AvoidReinterprets : public WalkerPass<PostWalker<AvoidReinterprets>> {
replaceCurrent(makeReinterpretedLoad(load, load->ptr));
}
} else if (auto* get = value->dynCast<LocalGet>()) {
- if (auto* load = getSingleLoad(
- localGraph, get, passOptions, module->features)) {
+ if (auto* load =
+ getSingleLoad(localGraph, get, passOptions, *module)) {
auto iter = infos.find(load);
if (iter != infos.end()) {
auto& info = iter->second;
diff --git a/src/passes/CodePushing.cpp b/src/passes/CodePushing.cpp
index c43028399..3ac11eebd 100644
--- a/src/passes/CodePushing.cpp
+++ b/src/passes/CodePushing.cpp
@@ -82,16 +82,16 @@ class Pusher {
LocalAnalyzer& analyzer;
std::vector<Index>& numGetsSoFar;
PassOptions& passOptions;
- FeatureSet features;
+ Module& module;
public:
Pusher(Block* block,
LocalAnalyzer& analyzer,
std::vector<Index>& numGetsSoFar,
PassOptions& passOptions,
- FeatureSet features)
+ Module& module)
: list(block->list), analyzer(analyzer), numGetsSoFar(numGetsSoFar),
- passOptions(passOptions), features(features) {
+ passOptions(passOptions), module(module) {
// Find an optimization segment: from the first pushable thing, to the first
// point past which we want to push. We then push in that range before
// continuing forward.
@@ -128,7 +128,7 @@ private:
// but also have no side effects, as it may not execute if pushed.
if (analyzer.isSFA(index) &&
numGetsSoFar[index] == analyzer.getNumGets(index) &&
- !EffectAnalyzer(passOptions, features, set->value).hasSideEffects()) {
+ !EffectAnalyzer(passOptions, module, set->value).hasSideEffects()) {
return set;
}
return nullptr;
@@ -159,7 +159,7 @@ private:
assert(firstPushable != Index(-1) && pushPoint != Index(-1) &&
firstPushable < pushPoint);
// everything that matters if you want to be pushed past the pushPoint
- EffectAnalyzer cumulativeEffects(passOptions, features);
+ EffectAnalyzer cumulativeEffects(passOptions, module);
cumulativeEffects.walk(list[pushPoint]);
// it is ok to ignore the branching here, that is the crucial point of this
// opt
@@ -177,7 +177,7 @@ private:
pushableEffects
.emplace(std::piecewise_construct,
std::forward_as_tuple(pushable),
- std::forward_as_tuple(passOptions, features, pushable))
+ std::forward_as_tuple(passOptions, module, pushable))
.first;
}
auto& effects = iter->second;
@@ -268,8 +268,7 @@ struct CodePushing : public WalkerPass<PostWalker<CodePushing>> {
// don't hit a non-control-flow ordering invalidation issue, since if this
// isn't a loop, it's fine (we're not used outside), and if it is, we hit
// the assign before any use (as we can't push it past a use).
- Pusher pusher(
- curr, analyzer, numGetsSoFar, getPassOptions(), getModule()->features);
+ Pusher pusher(curr, analyzer, numGetsSoFar, getPassOptions(), *getModule());
}
};
diff --git a/src/passes/ConstantFieldPropagation.cpp b/src/passes/ConstantFieldPropagation.cpp
index 8ec868a2f..d00e61ca5 100644
--- a/src/passes/ConstantFieldPropagation.cpp
+++ b/src/passes/ConstantFieldPropagation.cpp
@@ -266,8 +266,7 @@ private:
HeapType type,
Index index,
FunctionStructValuesMap& valuesMap) {
- expr =
- Properties::getFallthrough(expr, getPassOptions(), getModule()->features);
+ expr = Properties::getFallthrough(expr, getPassOptions(), *getModule());
// Ignore copies: when we set a value to a field from that same field, no
// new values are actually introduced.
diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp
index ac60c5cac..f2846671c 100644
--- a/src/passes/Heap2Local.cpp
+++ b/src/passes/Heap2Local.cpp
@@ -658,8 +658,8 @@ struct Heap2LocalOptimizer {
// Finally, check for mixing. If the child is the immediate fallthrough
// of the parent then no other values can be mixed in.
- if (Properties::getImmediateFallthrough(
- parent, passOptions, module->features) == child) {
+ if (Properties::getImmediateFallthrough(parent, passOptions, *module) ==
+ child) {
return ParentChildInteraction::Flows;
}
diff --git a/src/passes/OptimizeAddedConstants.cpp b/src/passes/OptimizeAddedConstants.cpp
index 107b06ffb..625a1bdcd 100644
--- a/src/passes/OptimizeAddedConstants.cpp
+++ b/src/passes/OptimizeAddedConstants.cpp
@@ -360,8 +360,7 @@ private:
void cleanUpAfterPropagation() {
// Remove sets that no longer have uses. This allows further propagation by
// letting us see the accurate amount of uses of each set.
- UnneededSetRemover remover(
- getFunction(), getPassOptions(), getModule()->features);
+ UnneededSetRemover remover(getFunction(), getPassOptions(), *getModule());
}
std::map<LocalSet*, Index> helperIndexes;
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 22d53b151..8752c76cb 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -101,8 +101,8 @@ struct LocalScanner : PostWalker<LocalScanner> {
return;
}
// an integer var, worth processing
- auto* value = Properties::getFallthrough(
- curr->value, passOptions, getModule()->features);
+ auto* value =
+ Properties::getFallthrough(curr->value, passOptions, *getModule());
auto& info = localInfo[curr->index];
info.maxBits = std::max(info.maxBits, Bits::getMaxBits(value, this));
auto signExtBits = LocalInfo::kUnknown;
@@ -469,9 +469,9 @@ struct OptimizeInstructions
Index extraLeftShifts;
auto bits = Properties::getAlmostSignExtBits(curr, extraLeftShifts);
if (extraLeftShifts == 0) {
- if (auto* load = Properties::getFallthrough(
- ext, getPassOptions(), getModule()->features)
- ->dynCast<Load>()) {
+ if (auto* load =
+ Properties::getFallthrough(ext, getPassOptions(), *getModule())
+ ->dynCast<Load>()) {
// pattern match a load of 8 bits and a sign extend using a shl of
// 24 then shr_s of 24 as well, etc.
if (LoadUtils::canBeSigned(load) &&
@@ -1152,9 +1152,9 @@ struct OptimizeInstructions
// the fallthrough value there. It takes more work to optimize this case,
// but it is pretty important to allow a call_ref to become a fast direct
// call, so make the effort.
- if (auto* ref =
- Properties::getFallthrough(curr->target, getPassOptions(), features)
- ->dynCast<RefFunc>()) {
+ if (auto* ref = Properties::getFallthrough(
+ curr->target, getPassOptions(), *getModule())
+ ->dynCast<RefFunc>()) {
// Check if the fallthrough make sense. We may have cast it to a different
// type, which would be a problem - we'd be replacing a call_ref to one
// type with a direct call to a function of another type. That would trap
@@ -1290,8 +1290,8 @@ struct OptimizeInstructions
Builder builder(*getModule());
auto passOptions = getPassOptions();
- auto fallthrough = Properties::getFallthrough(
- curr->ref, getPassOptions(), getModule()->features);
+ auto fallthrough =
+ Properties::getFallthrough(curr->ref, getPassOptions(), *getModule());
// If the value is a null, it will just flow through, and we do not need the
// cast. However, if that would change the type, then things are less
@@ -1358,8 +1358,6 @@ struct OptimizeInstructions
}
}
- auto features = getModule()->features;
-
// Repeated identical ref.cast operations are unnecessary, if using the
// exact same rtt - the result will be the same. Find the immediate child
// cast, if there is one, and see if it is identical.
@@ -1370,7 +1368,7 @@ struct OptimizeInstructions
// RefCast falls through the value, so instead of calling getFallthrough()
// to look through all fallthroughs, we must iterate manually. Keep going
// until we reach either the end of things falling-through, or a cast.
- ref = Properties::getImmediateFallthrough(ref, passOptions, features);
+ ref = Properties::getImmediateFallthrough(ref, passOptions, *getModule());
if (ref == last) {
break;
}
@@ -1544,7 +1542,6 @@ private:
// also ok to have side effects here, if we can remove them, as we are also
// checking if we can remove the two inputs anyhow.)
auto passOptions = getPassOptions();
- auto features = getModule()->features;
if (EffectAnalyzer(passOptions, *getModule(), left)
.hasUnremovableSideEffects() ||
EffectAnalyzer(passOptions, *getModule(), right)
@@ -1553,14 +1550,15 @@ private:
}
// Ignore extraneous things and compare them structurally.
- left = Properties::getFallthrough(left, passOptions, features);
- right = Properties::getFallthrough(right, passOptions, features);
+ left = Properties::getFallthrough(left, passOptions, *getModule());
+ right = Properties::getFallthrough(right, passOptions, *getModule());
if (!ExpressionAnalyzer::equal(left, right)) {
return false;
}
// To be equal, they must also be known to return the same result
// deterministically.
- if (Properties::isIntrinsicallyNondeterministic(left, features)) {
+ if (Properties::isIntrinsicallyNondeterministic(left,
+ getModule()->features)) {
return false;
}
return true;
diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp
index 82504bff5..89941a1ae 100644
--- a/src/passes/Precompute.cpp
+++ b/src/passes/Precompute.cpp
@@ -316,7 +316,7 @@ private:
// propagate that 42 along to the users, regardless of whatever the call
// did globally.)
auto values = precomputeValue(Properties::getFallthrough(
- set->value, getPassOptions(), getModule()->features));
+ set->value, getPassOptions(), *getModule()));
// Fix up the value. The computation we just did was to look at the
// fallthrough, then precompute that; that looks through expressions
// that pass through the value. Normally that does not matter here,
diff --git a/src/passes/SimplifyLocals.cpp b/src/passes/SimplifyLocals.cpp
index ee0459d7d..7c768d4d4 100644
--- a/src/passes/SimplifyLocals.cpp
+++ b/src/passes/SimplifyLocals.cpp
@@ -1031,7 +1031,7 @@ struct SimplifyLocals
// gotten there thanks to the EquivalentOptimizer. If there are such
// locals, remove all their sets.
UnneededSetRemover setRemover(
- getCounter, func, this->getPassOptions(), this->getModule()->features);
+ getCounter, func, this->getPassOptions(), *this->getModule());
setRemover.setModule(this->getModule());
return eqOpter.anotherCycle || setRemover.removed;