diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/asmjs/shared-constants.cpp | 1 | ||||
-rw-r--r-- | src/asmjs/shared-constants.h | 1 | ||||
-rw-r--r-- | src/ast/localize.h | 47 | ||||
-rw-r--r-- | src/passes/PostEmscripten.cpp | 23 |
4 files changed, 72 insertions, 0 deletions
diff --git a/src/asmjs/shared-constants.cpp b/src/asmjs/shared-constants.cpp index e30fd939c..d704c8009 100644 --- a/src/asmjs/shared-constants.cpp +++ b/src/asmjs/shared-constants.cpp @@ -49,6 +49,7 @@ cashew::IString GLOBAL("global"), FLOOR("floor"), CEIL("ceil"), SQRT("sqrt"), + POW("pow"), I32_TEMP("asm2wasm_i32_temp"), DEBUGGER("debugger"), USE_ASM("use asm"), diff --git a/src/asmjs/shared-constants.h b/src/asmjs/shared-constants.h index e0c627511..7b48c3df5 100644 --- a/src/asmjs/shared-constants.h +++ b/src/asmjs/shared-constants.h @@ -52,6 +52,7 @@ extern cashew::IString GLOBAL, FLOOR, CEIL, SQRT, + POW, I32_TEMP, DEBUGGER, USE_ASM, diff --git a/src/ast/localize.h b/src/ast/localize.h new file mode 100644 index 000000000..9e7dd6653 --- /dev/null +++ b/src/ast/localize.h @@ -0,0 +1,47 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef wasm_ast_localizer_h +#define wasm_ast_localizer_h + +#include <wasm-builder.h> + +namespace wasm { + +// Make an expression available in a local. If already in one, just +// use that local, otherwise use a new local + +struct Localizer { + Index index; + Expression* expr; + + Localizer(Expression* input, Function* func, Module* wasm) { + expr = input; + if (auto* get = expr->dynCast<GetLocal>()) { + index = get->index; + } else if (auto* set = expr->dynCast<SetLocal>()) { + index = set->index; + } else { + index = Builder::addVar(func, expr->type); + expr = Builder(*wasm).makeTeeLocal(index, expr); + } + } +}; + +} // namespace wasm + +#endif // wasm_ast_localizer_h + diff --git a/src/passes/PostEmscripten.cpp b/src/passes/PostEmscripten.cpp index 51b8c2ec1..937a70e36 100644 --- a/src/passes/PostEmscripten.cpp +++ b/src/passes/PostEmscripten.cpp @@ -21,6 +21,9 @@ #include <wasm.h> #include <pass.h> +#include <wasm-builder.h> +#include <ast/localize.h> +#include <asmjs/shared-constants.h> namespace wasm { @@ -88,6 +91,26 @@ struct PostEmscripten : public WalkerPass<PostWalker<PostEmscripten>> { void visitStore(Store* curr) { optimizeMemoryAccess(curr->ptr, curr->offset); } + + void visitCallImport(CallImport* curr) { + // special asm.js imports can be optimized + auto* import = getModule()->getImport(curr->target); + if (import->module == GLOBAL_MATH) { + if (import->base == POW) { + if (auto* exponent = curr->operands[1]->dynCast<Const>()) { + if (exponent->value == Literal(double(2.0))) { + // This is just a square operation, do a multiply + Localizer localizer(curr->operands[0], getFunction(), getModule()); + Builder builder(*getModule()); + replaceCurrent(builder.makeBinary(MulFloat64, localizer.expr, builder.makeGetLocal(localizer.index, localizer.expr->type))); + } else if (exponent->value == Literal(double(0.5))) { + // This is just a square root operation + replaceCurrent(Builder(*getModule()).makeUnary(SqrtFloat64, curr->operands[0])); + } + } + } + } + } }; Pass *createPostEmscriptenPass() { |