diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/asm2wasm.h | 7 | ||||
-rw-r--r-- | src/passes/MergeBlocks.cpp | 21 |
2 files changed, 21 insertions, 7 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 2245bd2b5..e2b1802b5 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -1397,7 +1397,12 @@ void Asm2WasmBuilder::processAsm(Ref ast) { void visitCallIndirect(CallIndirect* curr) { // we already call into target = something + offset, where offset is a callImport with the name of the table. replace that with the table offset // note that for an ftCall or mftCall, we have no asm.js mask, so have nothing to do here - auto* add = curr->target->dynCast<Binary>(); + auto* target = curr->target; + // might be a block with a fallthrough + if (auto* block = target->dynCast<Block>()) { + target = block->list.back(); + } + auto* add = target->dynCast<Binary>(); if (!add) return; if (add->right->is<CallImport>()) { auto* offset = add->right->cast<CallImport>(); diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp index bce5798a5..bc5fea6fb 100644 --- a/src/passes/MergeBlocks.cpp +++ b/src/passes/MergeBlocks.cpp @@ -288,11 +288,14 @@ struct MergeBlocks : public WalkerPass<PostWalker<MergeBlocks>> { } void visitSelect(Select* curr) { + // TODO: for now, just stop when we see any side effect. instead, we could + // check effects carefully for reordering Block* outer = nullptr; - outer = optimize(curr, curr->ifTrue, outer); if (EffectAnalyzer(getPassOptions(), curr->ifTrue).hasSideEffects()) return; - outer = optimize(curr, curr->ifFalse, outer); + outer = optimize(curr, curr->ifTrue, outer); if (EffectAnalyzer(getPassOptions(), curr->ifFalse).hasSideEffects()) return; + outer = optimize(curr, curr->ifFalse, outer); + if (EffectAnalyzer(getPassOptions(), curr->condition).hasSideEffects()) return; optimize(curr, curr->condition, outer); } @@ -308,11 +311,13 @@ struct MergeBlocks : public WalkerPass<PostWalker<MergeBlocks>> { } template<typename T> - void handleCall(T* curr, Block* outer = nullptr) { + void handleCall(T* curr) { + Block* outer = nullptr; for (Index i = 0; i < curr->operands.size(); i++) { - outer = optimize(curr, curr->operands[i], outer); if (EffectAnalyzer(getPassOptions(), curr->operands[i]).hasSideEffects()) return; + outer = optimize(curr, curr->operands[i], outer); } + return; } void visitCall(Call* curr) { @@ -324,9 +329,13 @@ struct MergeBlocks : public WalkerPass<PostWalker<MergeBlocks>> { } void visitCallIndirect(CallIndirect* curr) { - auto* outer = optimize(curr, curr->target); + Block* outer = nullptr; + for (Index i = 0; i < curr->operands.size(); i++) { + if (EffectAnalyzer(getPassOptions(), curr->operands[i]).hasSideEffects()) return; + outer = optimize(curr, curr->operands[i], outer); + } if (EffectAnalyzer(getPassOptions(), curr->target).hasSideEffects()) return; - handleCall(curr, outer); + optimize(curr, curr->target, outer); } }; |