diff options
author | Alon Zakai <azakai@google.com> | 2019-04-26 16:59:41 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-26 16:59:41 -0700 |
commit | db9124f1de0478dcac525009b6f1589b44a7edd8 (patch) | |
tree | fa26395a0f6cca53cf5cb6e10189f989c5bfa847 /src/tools/wasm-metadce.cpp | |
parent | 87636dccd404a340d75acb1d96301581343f29ca (diff) | |
download | binaryen-db9124f1de0478dcac525009b6f1589b44a7edd8.tar.gz binaryen-db9124f1de0478dcac525009b6f1589b44a7edd8.tar.bz2 binaryen-db9124f1de0478dcac525009b6f1589b44a7edd8.zip |
Apply format changes from #2048 (#2059)
Mass change to apply clang-format to everything. We are applying this in a PR by me so the (git) blame is all mine ;) but @aheejin did all the work to get clang-format set up and all the manual work to tidy up some things to make the output nicer in #2048
Diffstat (limited to 'src/tools/wasm-metadce.cpp')
-rw-r--r-- | src/tools/wasm-metadce.cpp | 268 |
1 files changed, 146 insertions, 122 deletions
diff --git a/src/tools/wasm-metadce.cpp b/src/tools/wasm-metadce.cpp index adb623ea0..a6f5bb012 100644 --- a/src/tools/wasm-metadce.cpp +++ b/src/tools/wasm-metadce.cpp @@ -26,14 +26,14 @@ #include <memory> +#include "ir/module-utils.h" #include "pass.h" +#include "support/colors.h" #include "support/command-line.h" #include "support/file.h" #include "support/json.h" -#include "support/colors.h" -#include "wasm-io.h" #include "wasm-builder.h" -#include "ir/module-utils.h" +#include "wasm-io.h" using namespace wasm; @@ -51,9 +51,10 @@ struct MetaDCEGraph { std::unordered_map<Name, DCENode> nodes; std::unordered_set<Name> roots; - std::unordered_map<Name, Name> exportToDCENode; // export exported name => DCE name + // export exported name => DCE name + std::unordered_map<Name, Name> exportToDCENode; std::unordered_map<Name, Name> functionToDCENode; // function name => DCE name - std::unordered_map<Name, Name> globalToDCENode; // global name => DCE name + std::unordered_map<Name, Name> globalToDCENode; // global name => DCE name std::unordered_map<Name, Name> DCENodeToExport; // reverse maps std::unordered_map<Name, Name> DCENodeToFunction; @@ -79,18 +80,20 @@ struct MetaDCEGraph { return getImportId(imp->module, imp->base); } - std::unordered_map<Name, Name> importIdToDCENode; // import module.base => DCE name + // import module.base => DCE name + std::unordered_map<Name, Name> importIdToDCENode; Module& wasm; MetaDCEGraph(Module& wasm) : wasm(wasm) {} - // populate the graph with info from the wasm, integrating with potentially-existing - // nodes for imports and exports that the graph may already contain. + // populate the graph with info from the wasm, integrating with + // potentially-existing nodes for imports and exports that the graph may + // already contain. void scanWebAssembly() { // Add an entry for everything we might need ahead of time, so parallel work - // does not alter parent state, just adds to things pointed by it, independently - // (each thread will add for one function, etc.) + // does not alter parent state, just adds to things pointed by it, + // independently (each thread will add for one function, etc.) ModuleUtils::iterDefinedFunctions(wasm, [&](Function* func) { auto dceName = getName("func", func->name.str); DCENodeToFunction[dceName] = func->name; @@ -103,7 +106,8 @@ struct MetaDCEGraph { globalToDCENode[global->name] = dceName; nodes[dceName] = DCENode(dceName); }); - // only process function and global imports - the table and memory are always there + // only process function and global imports - the table and memory are + // always there ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) { auto id = getImportId(import->module, import->base); if (importIdToDCENode.find(id) == importIdToDCENode.end()) { @@ -131,13 +135,15 @@ struct MetaDCEGraph { if (!wasm.getFunction(exp->value)->imported()) { node.reaches.push_back(functionToDCENode[exp->value]); } else { - node.reaches.push_back(importIdToDCENode[getFunctionImportId(exp->value)]); + node.reaches.push_back( + importIdToDCENode[getFunctionImportId(exp->value)]); } } else if (exp->kind == ExternalKind::Global) { if (!wasm.getGlobal(exp->value)->imported()) { node.reaches.push_back(globalToDCENode[exp->value]); } else { - node.reaches.push_back(importIdToDCENode[getGlobalImportId(exp->value)]); + node.reaches.push_back( + importIdToDCENode[getGlobalImportId(exp->value)]); } } } @@ -145,14 +151,11 @@ struct MetaDCEGraph { // if we provide a parent DCE name, that is who can reach what we see // if none is provided, then it is something we must root struct InitScanner : public PostWalker<InitScanner> { - InitScanner(MetaDCEGraph* parent, Name parentDceName) : parent(parent), parentDceName(parentDceName) {} + InitScanner(MetaDCEGraph* parent, Name parentDceName) + : parent(parent), parentDceName(parentDceName) {} - void visitGetGlobal(GetGlobal* curr) { - handleGlobal(curr->name); - } - void visitSetGlobal(SetGlobal* curr) { - handleGlobal(curr->name); - } + void visitGetGlobal(GetGlobal* curr) { handleGlobal(curr->name); } + void visitSetGlobal(SetGlobal* curr) { handleGlobal(curr->name); } private: MetaDCEGraph* parent; @@ -206,34 +209,29 @@ struct MetaDCEGraph { Scanner(MetaDCEGraph* parent) : parent(parent) {} - Scanner* create() override { - return new Scanner(parent); - } + Scanner* create() override { return new Scanner(parent); } void visitCall(Call* curr) { if (!getModule()->getFunction(curr->target)->imported()) { - parent->nodes[parent->functionToDCENode[getFunction()->name]].reaches.push_back( - parent->functionToDCENode[curr->target] - ); + parent->nodes[parent->functionToDCENode[getFunction()->name]] + .reaches.push_back(parent->functionToDCENode[curr->target]); } else { assert(parent->functionToDCENode.count(getFunction()->name) > 0); - parent->nodes[parent->functionToDCENode[getFunction()->name]].reaches.push_back( - parent->importIdToDCENode[parent->getFunctionImportId(curr->target)] - ); + parent->nodes[parent->functionToDCENode[getFunction()->name]] + .reaches.push_back( + parent + ->importIdToDCENode[parent->getFunctionImportId(curr->target)]); } } - void visitGetGlobal(GetGlobal* curr) { - handleGlobal(curr->name); - } - void visitSetGlobal(SetGlobal* curr) { - handleGlobal(curr->name); - } + void visitGetGlobal(GetGlobal* curr) { handleGlobal(curr->name); } + void visitSetGlobal(SetGlobal* curr) { handleGlobal(curr->name); } private: MetaDCEGraph* parent; void handleGlobal(Name name) { - if (!getFunction()) return; // non-function stuff (initializers) are handled separately + if (!getFunction()) + return; // non-function stuff (initializers) are handled separately Name dceName; if (!getModule()->getGlobal(name)->imported()) { // its a global @@ -242,7 +240,8 @@ struct MetaDCEGraph { // it's an import. dceName = parent->importIdToDCENode[parent->getGlobalImportId(name)]; } - parent->nodes[parent->functionToDCENode[getFunction()->name]].reaches.push_back(dceName); + parent->nodes[parent->functionToDCENode[getFunction()->name]] + .reaches.push_back(dceName); } }; @@ -256,7 +255,8 @@ private: // gets a unique name for the graph Name getName(std::string prefix1, std::string prefix2) { while (1) { - auto curr = Name(prefix1 + '$' + prefix2 + '$' + std::to_string(nameIndex++)); + auto curr = + Name(prefix1 + '$' + prefix2 + '$' + std::to_string(nameIndex++)); if (nodes.find(curr) == nodes.end()) { return curr; } @@ -305,7 +305,8 @@ public: // Now they are gone, standard optimization passes can do the rest! PassRunner passRunner(&wasm); passRunner.add("remove-unused-module-elements"); - passRunner.add("reorder-functions"); // removing functions may alter the optimum order, as # of calls can change + // removing functions may alter the optimum order, as # of calls can change + passRunner.add("reorder-functions"); passRunner.run(); } @@ -344,7 +345,8 @@ public: std::cout << " is import " << importMap[name] << '\n'; } if (DCENodeToExport.find(name) != DCENodeToExport.end()) { - std::cout << " is export " << DCENodeToExport[name].str << ", " << wasm.getExport(DCENodeToExport[name])->value << '\n'; + std::cout << " is export " << DCENodeToExport[name].str << ", " + << wasm.getExport(DCENodeToExport[name])->value << '\n'; } if (DCENodeToFunction.find(name) != DCENodeToFunction.end()) { std::cout << " is function " << DCENodeToFunction[name] << '\n'; @@ -372,86 +374,99 @@ int main(int argc, const char* argv[]) { std::string graphFile; bool dump = false; - Options options("wasm-metadce", "This tool performs dead code elimination (DCE) on a larger space " - "that the wasm module is just a part of. For example, if you have " - "JS and wasm that are connected, this can DCE the combined graph. " - "By doing so, it is able to eliminate wasm module exports, which " - "otherwise regular optimizations cannot.\n\n" - "This tool receives a representation of the reachability graph " - "that the wasm module resides in, which contains abstract nodes " - "and connections showing what they reach. Some of those nodes " - "can represent the wasm module's imports and exports. The tool " - "then completes the graph by adding the internal parts of the " - "module, and does DCE on the entire thing.\n\n" - "This tool will output a wasm module with dead code eliminated, " - "and metadata describing the things in the rest of the graph " - "that can be eliminated as well.\n\n" - "The graph description file should represent the graph in the following " - "JSON-like notation (note, this is not true JSON, things like " - "comments, escaping, single-quotes, etc. are not supported):\n\n" - " [\n" - " {\n" - " \"name\": \"entity1\",\n" - " \"reaches\": [\"entity2, \"entity3\"],\n" - " \"root\": true\n" - " },\n" - " {\n" - " \"name\": \"entity2\",\n" - " \"reaches\": [\"entity1, \"entity4\"]\n" - " },\n" - " {\n" - " \"name\": \"entity3\",\n" - " \"reaches\": [\"entity1\"],\n" - " \"export\": \"export1\"\n" - " },\n" - " {\n" - " \"name\": \"entity4\",\n" - " \"import\": [\"module\", \"import1\"]\n" - " },\n" - " ]\n\n" - "Each entity has a name and an optional list of the other " - "entities it reaches. It can also be marked as a root, " - "export (with the export string), or import (with the " - "module and import strings). DCE then computes what is " - "reachable from the roots."); + Options options( + "wasm-metadce", + "This tool performs dead code elimination (DCE) on a larger space " + "that the wasm module is just a part of. For example, if you have " + "JS and wasm that are connected, this can DCE the combined graph. " + "By doing so, it is able to eliminate wasm module exports, which " + "otherwise regular optimizations cannot.\n\n" + "This tool receives a representation of the reachability graph " + "that the wasm module resides in, which contains abstract nodes " + "and connections showing what they reach. Some of those nodes " + "can represent the wasm module's imports and exports. The tool " + "then completes the graph by adding the internal parts of the " + "module, and does DCE on the entire thing.\n\n" + "This tool will output a wasm module with dead code eliminated, " + "and metadata describing the things in the rest of the graph " + "that can be eliminated as well.\n\n" + "The graph description file should represent the graph in the following " + "JSON-like notation (note, this is not true JSON, things like " + "comments, escaping, single-quotes, etc. are not supported):\n\n" + " [\n" + " {\n" + " \"name\": \"entity1\",\n" + " \"reaches\": [\"entity2, \"entity3\"],\n" + " \"root\": true\n" + " },\n" + " {\n" + " \"name\": \"entity2\",\n" + " \"reaches\": [\"entity1, \"entity4\"]\n" + " },\n" + " {\n" + " \"name\": \"entity3\",\n" + " \"reaches\": [\"entity1\"],\n" + " \"export\": \"export1\"\n" + " },\n" + " {\n" + " \"name\": \"entity4\",\n" + " \"import\": [\"module\", \"import1\"]\n" + " },\n" + " ]\n\n" + "Each entity has a name and an optional list of the other " + "entities it reaches. It can also be marked as a root, " + "export (with the export string), or import (with the " + "module and import strings). DCE then computes what is " + "reachable from the roots."); options - .add("--output", "-o", "Output file (stdout if not specified)", - Options::Arguments::One, - [](Options* o, const std::string& argument) { - o->extra["output"] = argument; - Colors::disable(); - }) - .add("--emit-text", "-S", "Emit text instead of binary for the output file", - Options::Arguments::Zero, - [&](Options *o, const std::string& argument) { emitBinary = false; }) - .add("--debuginfo", "-g", "Emit names section and debug info", - Options::Arguments::Zero, - [&](Options *o, const std::string& arguments) { debugInfo = true; }) - .add("--graph-file", "-f", "Filename of the graph description file", - Options::Arguments::One, - [&](Options* o, const std::string& argument) { - graphFile = argument; - }) - .add("--dump", "-d", "Dump the combined graph file (useful for debugging)", - Options::Arguments::Zero, - [&](Options *o, const std::string& arguments) { dump = true; }) - .add_positional("INFILE", Options::Arguments::One, - [](Options* o, const std::string& argument) { - o->extra["infile"] = argument; - }); + .add("--output", + "-o", + "Output file (stdout if not specified)", + Options::Arguments::One, + [](Options* o, const std::string& argument) { + o->extra["output"] = argument; + Colors::disable(); + }) + .add("--emit-text", + "-S", + "Emit text instead of binary for the output file", + Options::Arguments::Zero, + [&](Options* o, const std::string& argument) { emitBinary = false; }) + .add("--debuginfo", + "-g", + "Emit names section and debug info", + Options::Arguments::Zero, + [&](Options* o, const std::string& arguments) { debugInfo = true; }) + .add("--graph-file", + "-f", + "Filename of the graph description file", + Options::Arguments::One, + [&](Options* o, const std::string& argument) { graphFile = argument; }) + .add("--dump", + "-d", + "Dump the combined graph file (useful for debugging)", + Options::Arguments::Zero, + [&](Options* o, const std::string& arguments) { dump = true; }) + .add_positional("INFILE", + Options::Arguments::One, + [](Options* o, const std::string& argument) { + o->extra["infile"] = argument; + }); options.parse(argc, argv); if (graphFile.size() == 0) { Fatal() << "no graph file provided."; } - auto input(read_file<std::string>(options.extra["infile"], Flags::Text, Flags::Release)); + auto input(read_file<std::string>( + options.extra["infile"], Flags::Text, Flags::Release)); Module wasm; { - if (options.debug) std::cerr << "reading...\n"; + if (options.debug) + std::cerr << "reading...\n"; ModuleReader reader; reader.setDebug(options.debug); @@ -463,32 +478,36 @@ int main(int argc, const char* argv[]) { } } - auto graphInput(read_file<std::string>(graphFile, Flags::Text, Flags::Release)); + auto graphInput( + read_file<std::string>(graphFile, Flags::Text, Flags::Release)); auto* copy = strdup(graphInput.c_str()); json::Value outside; outside.parse(copy); // parse the JSON into our graph, doing all the JSON parsing here, leaving // the abstract computation for the class itself - const json::IString NAME("name"), - REACHES("reaches"), - ROOT("root"), - EXPORT("export"), - IMPORT("import"); + const json::IString NAME("name"); + const json::IString REACHES("reaches"); + const json::IString ROOT("root"); + const json::IString EXPORT("export"); + const json::IString IMPORT("import"); MetaDCEGraph graph(wasm); if (!outside.isArray()) { - Fatal() << "input graph must be a JSON array of nodes. see --help for the form"; + Fatal() + << "input graph must be a JSON array of nodes. see --help for the form"; } auto size = outside.size(); for (size_t i = 0; i < size; i++) { json::Ref ref = outside[i]; if (!ref->isObject()) { - Fatal() << "nodes in input graph must be JSON objects. see --help for the form"; + Fatal() + << "nodes in input graph must be JSON objects. see --help for the form"; } if (!ref->has(NAME)) { - Fatal() << "nodes in input graph must have a name. see --help for the form"; + Fatal() + << "nodes in input graph must have a name. see --help for the form"; } DCENode node(ref[NAME]->getIString()); if (ref->has(REACHES)) { @@ -500,7 +519,8 @@ int main(int argc, const char* argv[]) { for (size_t j = 0; j < size; j++) { json::Ref name = reaches[j]; if (!name->isString()) { - Fatal() << "node.reaches items must be strings. see --help for the form"; + Fatal() + << "node.reaches items must be strings. see --help for the form"; } node.reaches.push_back(name->getIString()); } @@ -508,22 +528,26 @@ int main(int argc, const char* argv[]) { if (ref->has(ROOT)) { json::Ref root = ref[ROOT]; if (!root->isBool() || !root->getBool()) { - Fatal() << "node.root, if it exists, must be true. see --help for the form"; + Fatal() + << "node.root, if it exists, must be true. see --help for the form"; } graph.roots.insert(node.name); } if (ref->has(EXPORT)) { json::Ref exp = ref[EXPORT]; if (!exp->isString()) { - Fatal() << "node.export, if it exists, must be a string. see --help for the form"; + Fatal() << "node.export, if it exists, must be a string. see --help " + "for the form"; } graph.exportToDCENode[exp->getIString()] = node.name; graph.DCENodeToExport[node.name] = exp->getIString(); } if (ref->has(IMPORT)) { json::Ref imp = ref[IMPORT]; - if (!imp->isArray() || imp->size() != 2 || !imp[0]->isString() || !imp[1]->isString()) { - Fatal() << "node.import, if it exists, must be an array of two strings. see --help for the form"; + if (!imp->isArray() || imp->size() != 2 || !imp[0]->isString() || + !imp[1]->isString()) { + Fatal() << "node.import, if it exists, must be an array of two " + "strings. see --help for the form"; } auto id = graph.getImportId(imp[0]->getIString(), imp[1]->getIString()); graph.importIdToDCENode[id] = node.name; |