summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/asmjs/shared-constants.cpp1
-rw-r--r--src/asmjs/shared-constants.h1
-rw-r--r--src/ast/localize.h47
-rw-r--r--src/passes/PostEmscripten.cpp23
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() {