2020#include < support/colors.h>
2121#include < wasm.h>
2222#include < wasm-binary.h>
23+ #include < ir/module-utils.h>
2324
2425namespace wasm {
2526
@@ -92,7 +93,43 @@ struct Metrics : public WalkerPass<PostWalker<Metrics, UnifiedExpressionVisitor<
9293 counts[" [binary-bytes]" ] = writer.tableOfContents .functionBodies [i].size ;
9394 printCounts (std::string (" func: " ) + func->name .str );
9495 }
95- // can't comapre detailed info between passes yet
96+ // print for each export how much code size is due to it, i.e.,
97+ // how much the module could shrink without it.
98+ auto sizeAfterGlobalCleanup = [](Module* module ) {
99+ PassRunner runner (module , PassOptions::getWithDefaultOptimizationOptions ());
100+ runner.setIsNested (true );
101+ runner.addDefaultGlobalOptimizationPostPasses (); // remove stuff
102+ runner.run ();
103+ BufferWithRandomAccess buffer;
104+ WasmBinaryWriter writer (module , buffer);
105+ writer.write ();
106+ return buffer.size ();
107+ };
108+ size_t baseline;
109+ {
110+ Module test;
111+ ModuleUtils::copyModule (*module , test);
112+ baseline = sizeAfterGlobalCleanup (&test);
113+ }
114+ for (auto & exp : module ->exports ) {
115+ // create a test module where we remove the export and then see how much can be removed thanks to that
116+ Module test;
117+ ModuleUtils::copyModule (*module , test);
118+ test.removeExport (exp->name );
119+ counts.clear ();
120+ counts[" [removable-bytes-without-it]" ] = baseline - sizeAfterGlobalCleanup (&test);
121+ printCounts (std::string (" export: " ) + exp->name .str + " (" + exp->value .str + ' )' );
122+ }
123+ // check how much size depends on the start method
124+ if (!module ->start .isNull ()) {
125+ Module test;
126+ ModuleUtils::copyModule (*module , test);
127+ test.start = Name ();
128+ counts.clear ();
129+ counts[" [removable-bytes-without-it]" ] = baseline - sizeAfterGlobalCleanup (&test);
130+ printCounts (std::string (" start: " ) + module ->start .str );
131+ }
132+ // can't compare detailed info between passes yet
96133 lastMetricsPass = nullptr ;
97134 } else {
98135 // add function info
@@ -116,7 +153,10 @@ struct Metrics : public WalkerPass<PostWalker<Metrics, UnifiedExpressionVisitor<
116153 int total = 0 ;
117154 for (auto i : counts) {
118155 keys.push_back (i.first );
119- total += i.second ;
156+ // total is of all the normal stuff, not the special [things]
157+ if (i.first [0 ] != ' [' ) {
158+ total += i.second ;
159+ }
120160 }
121161 keys.push_back (" [total]" );
122162 counts[" [total]" ] = total;
@@ -127,6 +167,7 @@ struct Metrics : public WalkerPass<PostWalker<Metrics, UnifiedExpressionVisitor<
127167 o << title << " \n " ;
128168 for (auto * key : keys) {
129169 auto value = counts[key];
170+ if (value == 0 ) continue ;
130171 o << " " << left << setw (15 ) << key << " : " << setw (8 )
131172 << value;
132173 if (lastMetricsPass) {
0 commit comments