summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--src/pass.h3
-rw-r--r--src/passes/Metrics.cpp69
-rw-r--r--src/wasm.h26
4 files changed, 99 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 19d250865..7efcbeeba 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -42,6 +42,7 @@ SET(binaryen-shell_SOURCES
src/passes/RemoveUnusedBrs.cpp
src/passes/RemoveUnusedNames.cpp
src/passes/SimplifyLocals.cpp
+ src/passes/Metrics.cpp
)
ADD_EXECUTABLE(binaryen-shell
${binaryen-shell_SOURCES})
diff --git a/src/pass.h b/src/pass.h
index f8b56aff6..a95be9850 100644
--- a/src/pass.h
+++ b/src/pass.h
@@ -94,6 +94,8 @@ public:
// Override this to perform preparation work before the pass runs.
virtual void prepare(PassRunner* runner, Module* module) {}
virtual void run(PassRunner* runner, Module* module) = 0;
+ // Override this to perform finalization work after the pass runs.
+ virtual void finalize(PassRunner* runner, Module* module) {}
protected:
Pass() {}
Pass(Pass &) {}
@@ -110,6 +112,7 @@ public:
void run(PassRunner* runner, Module* module) override {
prepare(runner, module);
WalkerType::startWalk(module);
+ finalize(runner, module);
}
};
diff --git a/src/passes/Metrics.cpp b/src/passes/Metrics.cpp
new file mode 100644
index 000000000..3624786a4
--- /dev/null
+++ b/src/passes/Metrics.cpp
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+#include <iomanip>
+#include <pass.h>
+#include <wasm.h>
+
+namespace wasm {
+
+using namespace std;
+
+// Prints metrics between optimization passes.
+struct Metrics : public WalkerPass<WasmWalker<Metrics>> {
+ static Metrics *lastMetricsPass;
+
+ map<const char *, int> counts;
+ void walk(Expression *&curr) override {
+ WalkerPass::walk(curr);
+ if (!curr)
+ return;
+ auto name = getExpressionName(curr);
+ counts[name]++;
+ }
+ void finalize(PassRunner *runner, Module *module) override {
+ ostream &o = cout;
+ o << "Counts"
+ << "\n";
+ for (auto i = counts.cbegin(); i != counts.cend(); i++) {
+ o << " " << left << setw(15) << i->first << ": " << setw(8)
+ << i->second;
+ if (lastMetricsPass) {
+ if (lastMetricsPass->counts.count(i->first)) {
+ int before = lastMetricsPass->counts[i->first];
+ int after = i->second;
+ if (after - before) {
+ if (after > before) {
+ Colors::red(o);
+ } else {
+ Colors::green(o);
+ }
+ o << right << setw(8);
+ o << showpos << after - before << noshowpos;
+ Colors::normal(o);
+ }
+ }
+ }
+ o << "\n";
+ }
+ lastMetricsPass = this;
+ }
+};
+
+Metrics *Metrics::lastMetricsPass;
+static RegisterPass<Metrics> registerPass("metrics", "reports metrics");
+
+} // namespace wasm
diff --git a/src/wasm.h b/src/wasm.h
index 987a8da6b..856c0ebeb 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -350,6 +350,32 @@ public:
}
};
+inline const char *getExpressionName(Expression *curr) {
+ switch (curr->_id) {
+ case Expression::Id::InvalidId: abort();
+ case Expression::Id::BlockId: return "block";
+ case Expression::Id::IfId: return "if";
+ case Expression::Id::LoopId: return "loop";
+ case Expression::Id::BreakId: return "break";
+ case Expression::Id::SwitchId: return "switch";
+ case Expression::Id::CallId: return "call";
+ case Expression::Id::CallImportId: return "call_import";
+ case Expression::Id::CallIndirectId: return "call_indirect";
+ case Expression::Id::GetLocalId: return "get_local";
+ case Expression::Id::SetLocalId: return "set_local";
+ case Expression::Id::LoadId: return "load";
+ case Expression::Id::StoreId: return "store";
+ case Expression::Id::ConstId: return "const";
+ case Expression::Id::UnaryId: return "unary";
+ case Expression::Id::BinaryId: return "binary";
+ case Expression::Id::SelectId: return "select";
+ case Expression::Id::HostId: return "host";
+ case Expression::Id::NopId: return "nop";
+ case Expression::Id::UnreachableId: return "unreachable";
+ default: WASM_UNREACHABLE();
+ }
+}
+
typedef std::vector<Expression*> ExpressionList; // TODO: optimize?
class Nop : public Expression {