summaryrefslogtreecommitdiff
path: root/src/passes/pass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/pass.cpp')
-rw-r--r--src/passes/pass.cpp126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp
new file mode 100644
index 000000000..e4cc35554
--- /dev/null
+++ b/src/passes/pass.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2015 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 <chrono>
+
+#include <pass.h>
+
+namespace wasm {
+
+// PassRegistry
+
+PassRegistry* PassRegistry::get() {
+ static PassRegistry* manager = nullptr;
+ if (!manager) {
+ manager = new PassRegistry();
+ }
+ return manager;
+}
+
+void PassRegistry::registerPass(const char* name, const char *description, Creator create) {
+ assert(passInfos.find(name) == passInfos.end());
+ passInfos[name] = PassInfo(description, create);
+}
+
+Pass* PassRegistry::createPass(std::string name) {
+ if (passInfos.find(name) == passInfos.end()) return nullptr;
+ auto ret = passInfos[name].create();
+ ret->name = name;
+ return ret;
+}
+
+std::vector<std::string> PassRegistry::getRegisteredNames() {
+ std::vector<std::string> ret;
+ for (auto pair : passInfos) {
+ ret.push_back(pair.first);
+ }
+ return ret;
+}
+
+std::string PassRegistry::getPassDescription(std::string name) {
+ assert(passInfos.find(name) != passInfos.end());
+ return passInfos[name].description;
+}
+
+// PassRunner
+
+void PassRunner::addDefaultOptimizationPasses() {
+ add("remove-unused-brs");
+ add("remove-unused-names");
+ add("optimize-instructions");
+ add("simplify-locals");
+ add("merge-blocks");
+ add("reorder-locals");
+ add("vacuum");
+ add("optimize-instructions");
+}
+
+void PassRunner::run() {
+ std::chrono::high_resolution_clock::time_point beforeEverything;
+ size_t padding = 0;
+ if (debug) {
+ std::cerr << "[PassRunner] running passes..." << std::endl;
+ beforeEverything = std::chrono::high_resolution_clock::now();
+ for (auto pass : passes) {
+ padding = std::max(padding, pass->name.size());
+ }
+ }
+ for (auto pass : passes) {
+ currPass = pass;
+ std::chrono::high_resolution_clock::time_point before;
+ if (debug) {
+ std::cerr << "[PassRunner] running pass: " << pass->name << "... ";
+ for (size_t i = 0; i < padding - pass->name.size(); i++) {
+ std::cerr << ' ';
+ }
+ before = std::chrono::high_resolution_clock::now();
+ }
+ pass->run(this, wasm);
+ if (debug) {
+ auto after = std::chrono::high_resolution_clock::now();
+ std::chrono::duration<double> diff = after - before;
+ std::cerr << diff.count() << " seconds." << std::endl;
+ }
+ }
+ if (debug) {
+ auto after = std::chrono::high_resolution_clock::now();
+ std::chrono::duration<double> diff = after - beforeEverything;
+ std::cerr << "[PassRunner] passes took " << diff.count() << " seconds." << std::endl;
+ }
+}
+
+template<class P>
+P* PassRunner::getLast() {
+ bool found = false;
+ P* ret;
+ for (int i = passes.size() - 1; i >= 0; i--) {
+ if (found && (ret = dynamic_cast<P*>(passes[i]))) {
+ return ret;
+ }
+ if (passes[i] == currPass) {
+ found = true;
+ }
+ }
+ return nullptr;
+}
+
+PassRunner::~PassRunner() {
+ for (auto pass : passes) {
+ delete pass;
+ }
+}
+
+} // namespace wasm