summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast/branch-utils.h22
-rw-r--r--src/ast_utils.h2
-rw-r--r--src/passes/RemoveUnusedBrs.cpp4
-rw-r--r--src/passes/SimplifyLocals.cpp2
-rw-r--r--src/wasm-validator.h1
-rw-r--r--src/wasm/wasm-binary.cpp11
-rw-r--r--src/wasm/wasm-validator.cpp7
7 files changed, 21 insertions, 28 deletions
diff --git a/src/ast/branch-utils.h b/src/ast/branch-utils.h
index 05ead8571..d574945ef 100644
--- a/src/ast/branch-utils.h
+++ b/src/ast/branch-utils.h
@@ -24,24 +24,23 @@ namespace wasm {
namespace BranchUtils {
-// branches not actually taken (e.g. (br $out (unreachable)))
-// are trivially ignored in our type system
+// Some branches are obviously not actually reachable (e.g. (br $out (unreachable)))
-inline bool isBranchTaken(Break* br) {
+inline bool isBranchReachable(Break* br) {
return !(br->value && br->value->type == unreachable) &&
!(br->condition && br->condition->type == unreachable);
}
-inline bool isBranchTaken(Switch* sw) {
+inline bool isBranchReachable(Switch* sw) {
return !(sw->value && sw->value->type == unreachable) &&
sw->condition->type != unreachable;
}
-inline bool isBranchTaken(Expression* expr) {
+inline bool isBranchReachable(Expression* expr) {
if (auto* br = expr->dynCast<Break>()) {
- return isBranchTaken(br);
+ return isBranchReachable(br);
} else if (auto* sw = expr->dynCast<Switch>()) {
- return isBranchTaken(sw);
+ return isBranchReachable(sw);
}
WASM_UNREACHABLE();
}
@@ -103,8 +102,9 @@ inline std::set<Name> getBranchTargets(Expression* ast) {
// Finds if there are branches targeting a name. Note that since names are
// unique in our IR, we just need to look for the name, and do not need
// to analyze scoping.
-// By default we consider untaken branches (so any named use). You can unset named to
-// avoid that (and only note branches that are not obviously unreachable)
+// By default we consider all branches, so any place there is a branch that
+// names the target. You can unset 'named' to only note branches that appear
+// reachable (i.e., are not obviously unreachable).
struct BranchSeeker : public PostWalker<BranchSeeker> {
Name target;
bool named = true;
@@ -144,7 +144,7 @@ struct BranchSeeker : public PostWalker<BranchSeeker> {
if (curr->default_ == target) noteFound(curr->value);
}
- static bool hasTaken(Expression* tree, Name target) {
+ static bool hasReachable(Expression* tree, Name target) {
if (!target.is()) return false;
BranchSeeker seeker(target);
seeker.named = false;
@@ -152,7 +152,7 @@ struct BranchSeeker : public PostWalker<BranchSeeker> {
return seeker.found > 0;
}
- static Index countTaken(Expression* tree, Name target) {
+ static Index countReachable(Expression* tree, Name target) {
if (!target.is()) return 0;
BranchSeeker seeker(target);
seeker.named = false;
diff --git a/src/ast_utils.h b/src/ast_utils.h
index 852cf89a3..95f725636 100644
--- a/src/ast_utils.h
+++ b/src/ast_utils.h
@@ -62,7 +62,7 @@ struct ExpressionAnalyzer {
if (auto* br = curr->dynCast<Break>()) {
if (!br->condition) return true;
} else if (auto* block = curr->dynCast<Block>()) {
- if (block->list.size() > 0 && obviouslyDoesNotFlowOut(block->list.back()) && !BranchUtils::BranchSeeker::hasTaken(block, block->name)) return true;
+ if (block->list.size() > 0 && obviouslyDoesNotFlowOut(block->list.back()) && !BranchUtils::BranchSeeker::hasReachable(block, block->name)) return true;
}
return false;
}
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index ec7809f48..7e122b806 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -31,7 +31,7 @@ namespace wasm {
// condition and possible value, and the possible value must
// not have side effects (as they would run unconditionally)
static bool canTurnIfIntoBrIf(Expression* ifCondition, Expression* brValue, PassOptions& options) {
- // if the if isn't even taken, this is all dead code anyhow
+ // if the if isn't even reached, this is all dead code anyhow
if (ifCondition->type == unreachable) return false;
if (!brValue) return true;
EffectAnalyzer value(options, brValue);
@@ -512,7 +512,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
if (curr->name.is()) {
auto* br = list[0]->dynCast<Break>();
// we seek a regular br_if; if the type is unreachable that means it is not
- // actually taken, so ignore
+ // actually reached, so ignore
if (br && br->condition && br->name == curr->name && br->type != unreachable) {
assert(!br->value); // can't, it would be dropped or last in the block
if (BranchUtils::BranchSeeker::countNamed(curr, curr->name) == 1) {
diff --git a/src/passes/SimplifyLocals.cpp b/src/passes/SimplifyLocals.cpp
index 919784cdf..618f8dead 100644
--- a/src/passes/SimplifyLocals.cpp
+++ b/src/passes/SimplifyLocals.cpp
@@ -348,7 +348,7 @@ struct SimplifyLocals : public WalkerPass<LinearExecutionWalker<SimplifyLocals>>
auto* brp = breaks[j].brp;
auto* br = (*brp)->cast<Break>();
assert(!br->value);
- // if the break is conditional, then we must set the value here - if the break is not taken, we must still have the new value in the local
+ // if the break is conditional, then we must set the value here - if the break is not reached, we must still have the new value in the local
auto* set = (*breakSetLocalPointer)->cast<SetLocal>();
if (br->condition) {
br->value = set;
diff --git a/src/wasm-validator.h b/src/wasm-validator.h
index 35304d1c9..0851d33e8 100644
--- a/src/wasm-validator.h
+++ b/src/wasm-validator.h
@@ -78,7 +78,6 @@ struct WasmValidator : public PostWalker<WasmValidator> {
std::map<Name, Expression*> breakTargets;
std::map<Expression*, BreakInfo> breakInfos;
- std::set<Name> namedBreakTargets; // even breaks not taken must not be named if they go to a place that does not exist
WasmType returnType = unreachable; // type used in returns
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index f0787600e..9c0e5cd37 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -670,7 +670,7 @@ void WasmBinaryWriter::visitBreak(Break *curr) {
// then either the condition or the value is unreachable, which is
// extremely rare, and may require us to make the stack polymorphic
// (if the block we branch to has a value, we may lack one as we
- // are not a taken branch; the wasm spec on the other hand does
+ // are not a reachable branch; the wasm spec on the other hand does
// presume the br_if emits a value of the right type, even if it
// popped unreachable)
o << int8_t(BinaryConsts::Unreachable);
@@ -683,11 +683,10 @@ void WasmBinaryWriter::visitSwitch(Switch *curr) {
recurse(curr->value);
}
recurse(curr->condition);
- if (!BranchUtils::isBranchTaken(curr)) {
- // if the branch is not taken, then it's dangerous to emit it, as
- // wasm type checking rules are stricter than ours - we tolerate
- // an untaken branch to a target with a different value, but not
- // wasm. so just don't emit it
+ if (!BranchUtils::isBranchReachable(curr)) {
+ // if the branch is not reachable, then it's dangerous to emit it, as
+ // wasm type checking rules are different, especially in unreachable
+ // code. so just don't emit that unreachable code.
o << int8_t(BinaryConsts::Unreachable);
return;
}
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 877232521..8e93b1c38 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -58,7 +58,6 @@ void WasmValidator::visitBlock(Block *curr) {
}
}
breakTargets.erase(curr->name);
- namedBreakTargets.erase(curr->name);
}
if (curr->list.size() > 1) {
for (Index i = 0; i < curr->list.size() - 1; i++) {
@@ -88,7 +87,6 @@ void WasmValidator::visitLoop(Loop *curr) {
if (curr->name.is()) {
noteLabelName(curr->name);
breakTargets.erase(curr->name);
- namedBreakTargets.erase(curr->name);
if (breakInfos.count(curr) > 0) {
auto& info = breakInfos[curr];
shouldBeEqual(info.arity, Index(0), curr, "breaks to a loop cannot pass a value");
@@ -128,7 +126,6 @@ void WasmValidator::visitIf(If *curr) {
}
void WasmValidator::noteBreak(Name name, Expression* value, Expression* curr) {
- namedBreakTargets.insert(name);
WasmType valueType = none;
Index arity = 0;
if (value) {
@@ -550,9 +547,7 @@ void WasmValidator::visitFunction(Function *curr) {
if (returnType != unreachable) {
shouldBeEqual(curr->result, returnType, curr->body, "function result must match, if function has returns");
}
- if (!shouldBeTrue(namedBreakTargets.empty(), curr->body, "all named break targets must exist") && !quiet) {
- std::cerr << "(on label " << *namedBreakTargets.begin() << ")\n";
- }
+ shouldBeTrue(breakTargets.empty(), curr->body, "all named break targets must exist");
returnType = unreachable;
labelNames.clear();
}