diff options
Diffstat (limited to 'src/passes')
-rw-r--r-- | src/passes/FlattenControlFlow.cpp | 7 | ||||
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 8 | ||||
-rw-r--r-- | src/passes/RemoveUnusedBrs.cpp | 4 | ||||
-rw-r--r-- | src/passes/SimplifyLocals.cpp | 5 |
4 files changed, 20 insertions, 4 deletions
diff --git a/src/passes/FlattenControlFlow.cpp b/src/passes/FlattenControlFlow.cpp index 3da5809c3..dce8e6345 100644 --- a/src/passes/FlattenControlFlow.cpp +++ b/src/passes/FlattenControlFlow.cpp @@ -61,7 +61,7 @@ #include <wasm.h> #include <pass.h> #include <wasm-builder.h> - +#include <ast_utils.h> namespace wasm { @@ -461,6 +461,11 @@ struct FlattenControlFlow : public WalkerPass<PostWalker<FlattenControlFlow>> { splitter.note(operand); } } + + void visitFunction(Function* curr) { + // removing breaks can alter types + ReFinalize().walkFunctionInModule(curr, getModule()); + } }; Pass *createFlattenControlFlowPass() { diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index f458a58b2..acbf39447 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -397,6 +397,14 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions, // Optimizations that don't yet fit in the pattern DSL, but could be eventually maybe Expression* handOptimize(Expression* curr) { + // if this contains dead code, don't bother trying to optimize it, the type + // might change (if might not be unreachable if just one arm is, for example). + // this optimization pass focuses on actually executing code. the only + // exceptions are control flow changes + if (curr->type == unreachable && + !curr->is<Break>() && !curr->is<Switch>() && !curr->is<If>()) { + return nullptr; + } if (auto* binary = curr->dynCast<Binary>()) { if (Properties::isSymmetric(binary)) { // canonicalize a const to the second position diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp index e307ec414..ec7809f48 100644 --- a/src/passes/RemoveUnusedBrs.cpp +++ b/src/passes/RemoveUnusedBrs.cpp @@ -394,7 +394,9 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> { if (list.size() == 1 && curr->name.is()) { // if this block has just one child, a sub-block, then jumps to the former are jumps to us, really if (auto* child = list[0]->dynCast<Block>()) { - if (child->name.is() && child->name != curr->name) { + // the two blocks must have the same type for us to update the branch, as otherwise + // one block may be unreachable and the other concrete, so one might lack a value + if (child->name.is() && child->name != curr->name && child->type == curr->type) { auto& breaks = breaksToBlock[child]; for (auto* br : breaks) { newNames[br] = curr->name; diff --git a/src/passes/SimplifyLocals.cpp b/src/passes/SimplifyLocals.cpp index 2d4a02337..919784cdf 100644 --- a/src/passes/SimplifyLocals.cpp +++ b/src/passes/SimplifyLocals.cpp @@ -372,8 +372,9 @@ struct SimplifyLocals : public WalkerPass<LinearExecutionWalker<SimplifyLocals>> // optimize set_locals from both sides of an if into a return value void optimizeIfReturn(If* iff, Expression** currp, Sinkables& ifTrue) { assert(iff->ifFalse); - // if this if already has a result, we can't do anything - if (isConcreteWasmType(iff->type)) return; + // if this if already has a result, or is unreachable code, we have + // nothing to do + if (iff->type != none) return; // We now have the sinkables from both sides of the if. Sinkables& ifFalse = sinkables; Index sharedIndex = -1; |