summaryrefslogtreecommitdiff
path: root/src/passes/RemoveUnusedBrs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/RemoveUnusedBrs.cpp')
-rw-r--r--src/passes/RemoveUnusedBrs.cpp39
1 files changed, 24 insertions, 15 deletions
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index 786fcaf67..2d944d212 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -35,7 +35,8 @@ namespace wasm {
// not have side effects (as they would run unconditionally)
static bool canTurnIfIntoBrIf(Expression* ifCondition,
Expression* brValue,
- PassOptions& options) {
+ PassOptions& options,
+ FeatureSet features) {
// if the if isn't even reached, this is all dead code anyhow
if (ifCondition->type == Type::unreachable) {
return false;
@@ -43,11 +44,11 @@ static bool canTurnIfIntoBrIf(Expression* ifCondition,
if (!brValue) {
return true;
}
- EffectAnalyzer value(options, brValue);
+ EffectAnalyzer value(options, features, brValue);
if (value.hasSideEffects()) {
return false;
}
- return !EffectAnalyzer(options, ifCondition).invalidates(value);
+ return !EffectAnalyzer(options, features, ifCondition).invalidates(value);
}
// Check if it is not worth it to run code unconditionally. This
@@ -302,11 +303,13 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
}
void visitIf(If* curr) {
+ FeatureSet features = getModule()->features;
if (!curr->ifFalse) {
// if without an else. try to reduce
// if (condition) br => br_if (condition)
if (Break* br = curr->ifTrue->dynCast<Break>()) {
- if (canTurnIfIntoBrIf(curr->condition, br->value, getPassOptions())) {
+ if (canTurnIfIntoBrIf(
+ curr->condition, br->value, getPassOptions(), features)) {
if (!br->condition) {
br->condition = curr->condition;
} else {
@@ -327,7 +330,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
}
// Of course we can't do this if the br's condition has side
// effects, as we would then execute those unconditionally.
- if (EffectAnalyzer(getPassOptions(), br->condition)
+ if (EffectAnalyzer(getPassOptions(), features, br->condition)
.hasSideEffects()) {
return;
}
@@ -521,7 +524,8 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
return false;
}
// if there is control flow, we must stop looking
- if (EffectAnalyzer(getPassOptions(), curr).branches) {
+ if (EffectAnalyzer(getPassOptions(), getModule()->features, curr)
+ .transfersControlFlow()) {
return false;
}
if (i == 0) {
@@ -744,6 +748,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
// the if is dead
// * note that we do this at the end, because un-conditionalizing can
// interfere with optimizeLoop()ing.
+ FeatureSet features = getModule()->features;
auto& list = curr->list;
for (Index i = 0; i < list.size(); i++) {
auto* iff = list[i]->dynCast<If>();
@@ -755,7 +760,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
auto* ifTrueBreak = iff->ifTrue->dynCast<Break>();
if (ifTrueBreak && !ifTrueBreak->condition &&
canTurnIfIntoBrIf(
- iff->condition, ifTrueBreak->value, passOptions)) {
+ iff->condition, ifTrueBreak->value, passOptions, features)) {
// we are an if-else where the ifTrue is a break without a
// condition, so we can do this
ifTrueBreak->condition = iff->condition;
@@ -768,7 +773,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
auto* ifFalseBreak = iff->ifFalse->dynCast<Break>();
if (ifFalseBreak && !ifFalseBreak->condition &&
canTurnIfIntoBrIf(
- iff->condition, ifFalseBreak->value, passOptions)) {
+ iff->condition, ifFalseBreak->value, passOptions, features)) {
ifFalseBreak->condition =
Builder(*getModule()).makeUnary(EqZInt32, iff->condition);
ifFalseBreak->finalize();
@@ -797,7 +802,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
if (shrink && br2->type != Type::unreachable) {
// Join adjacent br_ifs to the same target, making one br_if
// with a "selectified" condition that executes both.
- if (!EffectAnalyzer(passOptions, br2->condition)
+ if (!EffectAnalyzer(passOptions, features, br2->condition)
.hasSideEffects()) {
// it's ok to execute them both, do it
Builder builder(*getModule());
@@ -888,8 +893,10 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
// If the items we move around have side effects, we can't do
// this.
// TODO: we could use a select, in some cases..?
- if (!EffectAnalyzer(passOptions, br->value).hasSideEffects() &&
- !EffectAnalyzer(passOptions, br->condition)
+ FeatureSet features = getModule()->features;
+ if (!EffectAnalyzer(passOptions, features, br->value)
+ .hasSideEffects() &&
+ !EffectAnalyzer(passOptions, features, br->condition)
.hasSideEffects()) {
ExpressionManipulator::nop(list[0]);
Builder builder(*getModule());
@@ -923,11 +930,12 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
return nullptr;
}
// Check if side effects allow this.
- EffectAnalyzer condition(passOptions, iff->condition);
+ FeatureSet features = getModule()->features;
+ EffectAnalyzer condition(passOptions, features, iff->condition);
if (!condition.hasSideEffects()) {
- EffectAnalyzer ifTrue(passOptions, iff->ifTrue);
+ EffectAnalyzer ifTrue(passOptions, features, iff->ifTrue);
if (!ifTrue.hasSideEffects()) {
- EffectAnalyzer ifFalse(passOptions, iff->ifFalse);
+ EffectAnalyzer ifFalse(passOptions, features, iff->ifFalse);
if (!ifFalse.hasSideEffects()) {
return Builder(*getModule())
.makeSelect(iff->condition, iff->ifTrue, iff->ifFalse);
@@ -1184,7 +1192,8 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
}
// if the condition has side effects, we can't replace many
// appearances of it with a single one
- if (EffectAnalyzer(passOptions, conditionValue).hasSideEffects()) {
+ if (EffectAnalyzer(passOptions, getModule()->features, conditionValue)
+ .hasSideEffects()) {
start++;
continue;
}