diff options
-rw-r--r-- | src/ir/module-utils.h | 34 | ||||
-rw-r--r-- | src/passes/Metrics.cpp | 45 | ||||
-rw-r--r-- | test/passes/func-metrics.txt | 123 | ||||
-rw-r--r-- | test/passes/func-metrics.wast | 69 | ||||
-rw-r--r-- | test/passes/metrics.txt | 5 |
5 files changed, 262 insertions, 14 deletions
diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h index 0c828f83a..5bcf2ea99 100644 --- a/src/ir/module-utils.h +++ b/src/ir/module-utils.h @@ -18,6 +18,7 @@ #define wasm_ir_module_h #include "wasm.h" +#include "ir/manipulation.h" namespace wasm { @@ -51,6 +52,39 @@ struct BinaryIndexes { } }; +inline void copyModule(Module& in, Module& out) { + // we use names throughout, not raw points, so simple copying is fine + // for everything *but* expressions + for (auto& curr : in.functionTypes) { + out.addFunctionType(new FunctionType(*curr)); + } + for (auto& curr : in.imports) { + out.addImport(new Import(*curr)); + } + for (auto& curr : in.exports) { + out.addExport(new Export(*curr)); + } + for (auto& curr : in.functions) { + auto* func = new Function(*curr); + func->body = ExpressionManipulator::copy(func->body, out); + out.addFunction(func); + } + for (auto& curr : in.globals) { + out.addGlobal(new Global(*curr)); + } + out.table = in.table; + for (auto& segment : out.table.segments) { + segment.offset = ExpressionManipulator::copy(segment.offset, out); + } + out.memory = in.memory; + for (auto& segment : out.memory.segments) { + segment.offset = ExpressionManipulator::copy(segment.offset, out); + } + out.start = in.start; + out.userSections = in.userSections; + out.debugInfoFileNames = in.debugInfoFileNames; +} + } // namespace ModuleUtils } // namespace wasm diff --git a/src/passes/Metrics.cpp b/src/passes/Metrics.cpp index 822596cb3..5b5e1c8ab 100644 --- a/src/passes/Metrics.cpp +++ b/src/passes/Metrics.cpp @@ -20,6 +20,7 @@ #include <support/colors.h> #include <wasm.h> #include <wasm-binary.h> +#include <ir/module-utils.h> namespace wasm { @@ -92,7 +93,43 @@ struct Metrics : public WalkerPass<PostWalker<Metrics, UnifiedExpressionVisitor< counts["[binary-bytes]"] = writer.tableOfContents.functionBodies[i].size; printCounts(std::string("func: ") + func->name.str); } - // can't comapre detailed info between passes yet + // print for each export how much code size is due to it, i.e., + // how much the module could shrink without it. + auto sizeAfterGlobalCleanup = [](Module* module) { + PassRunner runner(module, PassOptions::getWithDefaultOptimizationOptions()); + runner.setIsNested(true); + runner.addDefaultGlobalOptimizationPostPasses(); // remove stuff + runner.run(); + BufferWithRandomAccess buffer; + WasmBinaryWriter writer(module, buffer); + writer.write(); + return buffer.size(); + }; + size_t baseline; + { + Module test; + ModuleUtils::copyModule(*module, test); + baseline = sizeAfterGlobalCleanup(&test); + } + for (auto& exp : module->exports) { + // create a test module where we remove the export and then see how much can be removed thanks to that + Module test; + ModuleUtils::copyModule(*module, test); + test.removeExport(exp->name); + counts.clear(); + counts["[removable-bytes-without-it]"] = baseline - sizeAfterGlobalCleanup(&test); + printCounts(std::string("export: ") + exp->name.str + " (" + exp->value.str + ')'); + } + // check how much size depends on the start method + if (!module->start.isNull()) { + Module test; + ModuleUtils::copyModule(*module, test); + test.start = Name(); + counts.clear(); + counts["[removable-bytes-without-it]"] = baseline - sizeAfterGlobalCleanup(&test); + printCounts(std::string("start: ") + module->start.str); + } + // can't compare detailed info between passes yet lastMetricsPass = nullptr; } else { // add function info @@ -116,7 +153,10 @@ struct Metrics : public WalkerPass<PostWalker<Metrics, UnifiedExpressionVisitor< int total = 0; for (auto i : counts) { keys.push_back(i.first); - total += i.second; + // total is of all the normal stuff, not the special [things] + if (i.first[0] != '[') { + total += i.second; + } } keys.push_back("[total]"); counts["[total]"] = total; @@ -127,6 +167,7 @@ struct Metrics : public WalkerPass<PostWalker<Metrics, UnifiedExpressionVisitor< o << title << "\n"; for (auto* key : keys) { auto value = counts[key]; + if (value == 0) continue; o << " " << left << setw(15) << key << ": " << setw(8) << value; if (lastMetricsPass) { diff --git a/test/passes/func-metrics.txt b/test/passes/func-metrics.txt index f21b6c1a3..b778962a1 100644 --- a/test/passes/func-metrics.txt +++ b/test/passes/func-metrics.txt @@ -2,17 +2,15 @@ global [funcs] : 3 [memory-data] : 9 [table-data] : 3 - [total] : 18 + [total] : 3 const : 3 func: empty [binary-bytes] : 3 - [total] : 4 - [vars] : 0 + [total] : 1 nop : 1 func: small [binary-bytes] : 9 - [total] : 14 - [vars] : 0 + [total] : 5 block : 1 const : 1 drop : 1 @@ -20,7 +18,7 @@ func: small return : 1 func: ifs [binary-bytes] : 51 - [total] : 76 + [total] : 24 [vars] : 1 binary : 1 block : 1 @@ -86,7 +84,116 @@ func: ifs ) ) global - [funcs] : 0 - [total] : 0 (module ) +global + [funcs] : 3 +func: func_a + [binary-bytes] : 16 + [total] : 8 + block : 1 + call : 2 + call_import : 5 +func: func_b + [binary-bytes] : 22 + [total] : 11 + block : 1 + call_import : 10 +func: func_c + [binary-bytes] : 32 + [total] : 16 + block : 1 + call_import : 15 +export: a (func_a) + [removable-bytes-without-it]: 72 +export: b (func_b) + [removable-bytes-without-it]: 18 +(module + (type $FUNCSIG$v (func)) + (import "env" "waka" (func $waka)) + (export "a" (func $func_a)) + (export "b" (func $func_b)) + (func $func_a (; 1 ;) (type $FUNCSIG$v) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $func_b) + (call $func_c) + ) + (func $func_b (; 2 ;) (type $FUNCSIG$v) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + ) + (func $func_c (; 3 ;) (type $FUNCSIG$v) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + ) +) +global + [funcs] : 1 +func: func_a + [binary-bytes] : 12 + [total] : 6 + block : 1 + call_import : 5 +export: a (func_a) + [removable-bytes-without-it]: 7 +start: func_a + [removable-bytes-without-it]: 3 +(module + (type $FUNCSIG$v (func)) + (import "env" "waka" (func $waka)) + (export "a" (func $func_a)) + (start $func_a) + (func $func_a (; 1 ;) (type $FUNCSIG$v) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + ) +) +global + [funcs] : 1 +func: func_a + [binary-bytes] : 12 + [total] : 6 + block : 1 + call_import : 5 +start: func_a + [removable-bytes-without-it]: 67 +(module + (type $FUNCSIG$v (func)) + (import "env" "waka" (func $waka)) + (start $func_a) + (func $func_a (; 1 ;) (type $FUNCSIG$v) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + ) +) diff --git a/test/passes/func-metrics.wast b/test/passes/func-metrics.wast index 9c2f35a81..2bdbc6b29 100644 --- a/test/passes/func-metrics.wast +++ b/test/passes/func-metrics.wast @@ -54,3 +54,72 @@ ;; module with no table or memory or anything for that matter (module ) +;; export size checking +(module + (import "env" "waka" (func $waka)) + (export "a" (func $func_a)) + (export "b" (func $func_b)) + (func $func_a + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $func_b) + (call $func_c) + ) + (func $func_b + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + ) + (func $func_c + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + ) +) +;; start size checking +(module + (import "env" "waka" (func $waka)) + (export "a" (func $func_a)) + (start $func_a) + (func $func_a + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + ) +) +(module + (import "env" "waka" (func $waka)) + (start $func_a) + (func $func_a + (call $waka) + (call $waka) + (call $waka) + (call $waka) + (call $waka) + ) +) + diff --git a/test/passes/metrics.txt b/test/passes/metrics.txt index f2670c550..9cc5d03ec 100644 --- a/test/passes/metrics.txt +++ b/test/passes/metrics.txt @@ -2,7 +2,7 @@ total [funcs] : 1 [memory-data] : 9 [table-data] : 3 - [total] : 41 + [total] : 27 [vars] : 1 binary : 1 block : 1 @@ -57,8 +57,5 @@ total ) ) total - [funcs] : 0 - [total] : 0 - [vars] : 0 (module ) |