summaryrefslogtreecommitdiff
path: root/src/ir/intrinsics.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-09-10 15:35:29 -0700
committerGitHub <noreply@github.com>2021-09-10 22:35:29 +0000
commitfc310a6dd6145d5d1470d8bf4cbb57c93f8785f1 (patch)
treebd611524aea65aab2652eb4e122438166d871ce9 /src/ir/intrinsics.cpp
parentea74b4f8649dfa6c8775fcef829d115083e5acc9 (diff)
downloadbinaryen-fc310a6dd6145d5d1470d8bf4cbb57c93f8785f1.tar.gz
binaryen-fc310a6dd6145d5d1470d8bf4cbb57c93f8785f1.tar.bz2
binaryen-fc310a6dd6145d5d1470d8bf4cbb57c93f8785f1.zip
Add an Intrinsics mechanism, and a call.without.effects intrinsic (#4126)
An "intrinsic" is modeled as a call to an import. We could also add new IR things for them, but that would take more work and lead to less clear errors in other tools if they try to read a binary using such a nonstandard extension. A first intrinsic is added here, call.without.effects This is basically the same as call_ref except that the optimizer is free to assume the call has no side effects. Consequently, if the result is not used then it can be optimized out (as even if it is not used then side effects could have kept it around). Likewise, the lack of side effects allows more reordering and other things. A lowering pass for intrinsics is provided. Rather than automatically lower them to normal wasm at the end of optimizations, the user must call that pass explicitly. A typical workflow might be -O --intrinsic-lowering -O That optimizes with the intrinsic present - perhaps removing calls thanks to it - then lowers it into normal wasm - it turns into a call_ref - and then optimizes further, which would turns the call_ref into a direct call, potentially inline, etc.
Diffstat (limited to 'src/ir/intrinsics.cpp')
-rw-r--r--src/ir/intrinsics.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/ir/intrinsics.cpp b/src/ir/intrinsics.cpp
new file mode 100644
index 000000000..c2318cabf
--- /dev/null
+++ b/src/ir/intrinsics.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+
+#include "ir/intrinsics.h"
+#include "wasm-builder.h"
+
+namespace wasm {
+
+static Name BinaryenIntrinsics("binaryen-intrinsics"),
+ CallWithoutEffects("call.without.effects");
+
+bool Intrinsics::isCallWithoutEffects(Function* func) {
+ return func->module == BinaryenIntrinsics && func->base == CallWithoutEffects;
+}
+
+Call* Intrinsics::isCallWithoutEffects(Expression* curr) {
+ if (auto* call = curr->dynCast<Call>()) {
+ // The target function may not exist if the module is still being
+ // constructed.
+ if (auto* func = module.getFunctionOrNull(call->target)) {
+ if (isCallWithoutEffects(func)) {
+ return call;
+ }
+ }
+ }
+ return nullptr;
+}
+
+} // namespace wasm