summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2017-03-16 14:12:44 -0700
committerGitHub <noreply@github.com>2017-03-16 14:12:44 -0700
commitee501dfb427e675adee7790a6dbc7e90f9f5a4ca (patch)
tree0889eb6cd2bff3cebebe019e8132eb816bd52d27 /src
parent5079b89949d4c5c5c7b6d29658d058db459be9e6 (diff)
downloadbinaryen-ee501dfb427e675adee7790a6dbc7e90f9f5a4ca.tar.gz
binaryen-ee501dfb427e675adee7790a6dbc7e90f9f5a4ca.tar.bz2
binaryen-ee501dfb427e675adee7790a6dbc7e90f9f5a4ca.zip
add a pass to log execution traces via instrumenting the code (#950)
Diffstat (limited to 'src')
-rw-r--r--src/passes/CMakeLists.txt1
-rw-r--r--src/passes/LogExecution.cpp77
-rw-r--r--src/passes/pass.cpp1
-rw-r--r--src/passes/passes.h2
4 files changed, 80 insertions, 1 deletions
diff --git a/src/passes/CMakeLists.txt b/src/passes/CMakeLists.txt
index 876a71d74..75e634c16 100644
--- a/src/passes/CMakeLists.txt
+++ b/src/passes/CMakeLists.txt
@@ -8,6 +8,7 @@ SET(passes_SOURCES
Inlining.cpp
LegalizeJSInterface.cpp
LocalCSE.cpp
+ LogExecution.cpp
MemoryPacking.cpp
MergeBlocks.cpp
Metrics.cpp
diff --git a/src/passes/LogExecution.cpp b/src/passes/LogExecution.cpp
new file mode 100644
index 000000000..8d555fefe
--- /dev/null
+++ b/src/passes/LogExecution.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2017 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.
+ */
+
+//
+// Instruments the build with code to log execution at each function
+// entry and loop header. This can be useful in debugging, to log out
+// a trace, and diff it to another (running in another browser, to
+// check for bugs, for example).
+//
+// The logging is performed by calling an ffi with an id for each
+// call site. You need to provide that import on the JS side.
+//
+
+#include <wasm.h>
+#include <wasm-builder.h>
+#include <pass.h>
+#include "shared-constants.h"
+#include "asmjs/shared-constants.h"
+#include "asm_v_wasm.h"
+
+namespace wasm {
+
+Name LOGGER("log_execution");
+
+struct LogExecution : public WalkerPass<PostWalker<LogExecution>> {
+ void visitLoop(Loop* curr) {
+ curr->body = makeLogCall(curr->body);
+ }
+
+ void visitFunction(Function* curr) {
+ curr->body = makeLogCall(curr->body);
+ }
+
+ void visitModule(Module *curr) {
+ // Add the import
+ auto import = new Import;
+ import->name = LOGGER;
+ import->module = ENV;
+ import->base = LOGGER;
+ import->functionType = ensureFunctionType("vi", curr)->name;
+ import->kind = ExternalKind::Function;
+ curr->addImport(import);
+ }
+
+private:
+ Expression* makeLogCall(Expression* curr) {
+ static Index id = 0;
+ Builder builder(*getModule());
+ return builder.makeSequence(
+ builder.makeCallImport(
+ LOGGER,
+ { builder.makeConst(Literal(int32_t(id++))) },
+ none
+ ),
+ curr
+ );
+ }
+};
+
+Pass *createLogExecutionPass() {
+ return new LogExecution();
+}
+
+} // namespace wasm
diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp
index a82b2fa58..577a460cb 100644
--- a/src/passes/pass.cpp
+++ b/src/passes/pass.cpp
@@ -72,6 +72,7 @@ void PassRegistry::registerPasses() {
registerPass("inlining", "inlines functions (currently only ones with a single use)", createInliningPass);
registerPass("legalize-js-interface", "legalizes i64 types on the import/export boundary", createLegalizeJSInterfacePass);
registerPass("local-cse", "common subexpression elimination inside basic blocks", createLocalCSEPass);
+ registerPass("log-execution", "instrument the build with logging of where execution goes", createLogExecutionPass);
registerPass("memory-packing", "packs memory into separate segments, skipping zeros", createMemoryPackingPass);
registerPass("merge-blocks", "merges blocks to their parents", createMergeBlocksPass);
registerPass("metrics", "reports metrics", createMetricsPass);
diff --git a/src/passes/passes.h b/src/passes/passes.h
index c3660b048..f8156d4fe 100644
--- a/src/passes/passes.h
+++ b/src/passes/passes.h
@@ -32,7 +32,7 @@ Pass *createFullPrinterPass();
Pass *createInliningPass();
Pass *createLegalizeJSInterfacePass();
Pass *createLocalCSEPass();
-Pass *createLowerIfElsePass();
+Pass *createLogExecutionPass();
Pass *createMemoryPackingPass();
Pass *createMergeBlocksPass();
Pass *createMinifiedPrinterPass();