summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/module-utils.h34
-rw-r--r--src/passes/Metrics.cpp45
-rw-r--r--test/passes/func-metrics.txt123
-rw-r--r--test/passes/func-metrics.wast69
-rw-r--r--test/passes/metrics.txt5
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
)