Skip to content

Commit 5268486

Browse files
committed
optimize helper funcs (like i32-div) if created in asm2wasm, so they are consistently handled regardless of whether we optimize in parallel or not
1 parent 9f9e9ae commit 5268486

10 files changed

+142
-9
lines changed

src/asm2wasm.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
862862
if (body[i][0] == DEFUN) numFunctions++;
863863
}
864864
optimizingBuilder = make_unique<OptimizingIncrementalModuleBuilder>(&wasm, numFunctions, passOptions, [&](PassRunner& passRunner) {
865+
// addPrePasses
865866
if (debug) {
866867
passRunner.setDebug(true);
867868
passRunner.setValidateGlobally(false);
@@ -874,6 +875,18 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
874875
}
875876
// optimize relooper label variable usage at the wasm level, where it is easy
876877
passRunner.add("relooper-jump-threading");
878+
}, [&]() {
879+
// beforeGlobalOptimizations
880+
// if we added any helper functions (like non-trapping i32-div, etc.), then those
881+
// have not been optimized (the optimizing builder has just been fed the asm.js
882+
// functions). Optimize those now. Typically there are very few, just do it
883+
// sequentially.
884+
PassRunner passRunner(&wasm, passOptions);
885+
passRunner.addDefaultFunctionOptimizationPasses();
886+
for (auto& pair : trappingFunctions.getFunctions()) {
887+
auto* func = pair.second;
888+
passRunner.runFunction(func);
889+
}
877890
}, debug, false /* do not validate globally yet */);
878891
}
879892

src/ast/trapping.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ class TrappingFunctionContainer {
8585
return wasm;
8686
}
8787

88+
std::map<Name, Function*>& getFunctions() {
89+
return functions;
90+
}
91+
8892
private:
8993
std::map<Name, Function*> functions;
9094
std::map<Name, Import*> imports;

src/wasm-module-building.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class OptimizingIncrementalModuleBuilder {
7575
uint32_t numFunctions;
7676
PassOptions passOptions;
7777
std::function<void (PassRunner&)> addPrePasses;
78+
std::function<void ()> beforeGlobalOptimizations;
7879
Function* endMarker;
7980
std::atomic<Function*>* list;
8081
uint32_t nextFunction; // only used on main thread
@@ -90,8 +91,13 @@ class OptimizingIncrementalModuleBuilder {
9091
public:
9192
// numFunctions must be equal to the number of functions allocated, or higher. Knowing
9293
// this bounds helps avoid locking.
93-
OptimizingIncrementalModuleBuilder(Module* wasm, Index numFunctions, PassOptions passOptions, std::function<void (PassRunner&)> addPrePasses, bool debug, bool validateGlobally)
94-
: wasm(wasm), numFunctions(numFunctions), passOptions(passOptions), addPrePasses(addPrePasses), endMarker(nullptr), list(nullptr), nextFunction(0),
94+
OptimizingIncrementalModuleBuilder(Module* wasm, Index numFunctions, PassOptions passOptions,
95+
std::function<void (PassRunner&)> addPrePasses,
96+
std::function<void ()> beforeGlobalOptimizations,
97+
bool debug, bool validateGlobally)
98+
: wasm(wasm), numFunctions(numFunctions), passOptions(passOptions),
99+
addPrePasses(addPrePasses), beforeGlobalOptimizations(beforeGlobalOptimizations),
100+
endMarker(nullptr), list(nullptr), nextFunction(0),
95101
numWorkers(0), liveWorkers(0), activeWorkers(0), availableFuncs(0), finishedFuncs(0),
96102
finishing(false), debug(debug), validateGlobally(validateGlobally) {
97103

@@ -165,14 +171,13 @@ class OptimizingIncrementalModuleBuilder {
165171
}
166172
addPrePasses(passRunner);
167173
passRunner.addDefaultFunctionOptimizationPasses();
168-
passRunner.addDefaultGlobalOptimizationPostPasses();
169174
passRunner.run();
170-
return;
175+
} else {
176+
DEBUG_THREAD("finish()ing");
177+
assert(nextFunction == numFunctions);
178+
wakeAllWorkers();
179+
waitUntilAllFinished();
171180
}
172-
DEBUG_THREAD("finish()ing");
173-
assert(nextFunction == numFunctions);
174-
wakeAllWorkers();
175-
waitUntilAllFinished();
176181
optimizeGlobally();
177182
// TODO: clear side thread allocators from module allocator, as these threads were transient
178183
}
@@ -225,9 +230,11 @@ class OptimizingIncrementalModuleBuilder {
225230
}
226231

227232
void optimizeGlobally() {
233+
beforeGlobalOptimizations();
228234
PassRunner passRunner(wasm, passOptions);
229235
passRunner.addDefaultGlobalOptimizationPostPasses();
230236
passRunner.run();
237+
231238
}
232239

233240
// worker code

test/unit.asm.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,11 @@ function asm(global, env, buffer) {
150150
x = (4294967295 / 2)&-1;
151151
return x | 0;
152152
}
153+
function trapping_sint_div_s() {
154+
var x = 0;
155+
x = (-2147483648 / -1);
156+
return x | 0;
157+
}
153158
function fr(x) {
154159
x = Math_fround(x);
155160
var y = Math_fround(0), z = 0.0;
@@ -790,6 +795,6 @@ function asm(global, env, buffer) {
790795
var FUNCTION_TABLE_vi = [ vi, vi, vi, vi, vi, vi, vi, vi ];
791796
var FUNCTION_TABLE_ii = [ ii ];
792797

793-
return { big_negative: big_negative, pick: forgetMe, pick: exportMe, doubleCompares: doubleCompares, intOps: intOps, conversions: conversions, switcher: switcher, frem: frem, frem_float: frem_float, big_uint_div_u: big_uint_div_u, fr: fr, negZero: negZero, neg: neg, smallCompare: smallCompare, cneg_nosemicolon: cneg_nosemicolon, forLoop: forLoop, ceiling_32_64: ceiling_32_64, aborts: aborts, continues: continues, bitcasts: bitcasts, recursiveBlockMerging: recursiveBlockMerging, lb: lb, zeroInit: zeroInit, phi: phi, smallIf: smallIf, dropCall: dropCall, useSetGlobal: useSetGlobal, usesSetGlobal2: usesSetGlobal2, breakThroughMany: breakThroughMany, ifChainEmpty: ifChainEmpty, heap8NoShift: heap8NoShift, conditionalTypeFun: conditionalTypeFun, loadSigned: loadSigned, globalOpts: globalOpts, dropCallImport: dropCallImport, loophi: loophi, loophi2: loophi2, loophi2b: loophi2b, relooperJumpThreading: relooperJumpThreading, relooperJumpThreading__ZN4game14preloadweaponsEv: relooperJumpThreading__ZN4game14preloadweaponsEv, __Z12multi_varargiz: __Z12multi_varargiz, jumpThreadDrop: jumpThreadDrop, dropIgnoredImportInIf: dropIgnoredImportInIf, dropIgnoredImportsInIf: dropIgnoredImportsInIf, relooperJumpThreading_irreducible: relooperJumpThreading_irreducible, store_fround: store_fround, exportedNumber: 42, relocatableAndModules: relocatableAndModules, exported_f32_user: exported_f32_user, keepAlive: keepAlive };
798+
return { big_negative: big_negative, pick: forgetMe, pick: exportMe, doubleCompares: doubleCompares, intOps: intOps, conversions: conversions, switcher: switcher, frem: frem, frem_float: frem_float, big_uint_div_u: big_uint_div_u, trapping_sint_div_s: trapping_sint_div_s, fr: fr, negZero: negZero, neg: neg, smallCompare: smallCompare, cneg_nosemicolon: cneg_nosemicolon, forLoop: forLoop, ceiling_32_64: ceiling_32_64, aborts: aborts, continues: continues, bitcasts: bitcasts, recursiveBlockMerging: recursiveBlockMerging, lb: lb, zeroInit: zeroInit, phi: phi, smallIf: smallIf, dropCall: dropCall, useSetGlobal: useSetGlobal, usesSetGlobal2: usesSetGlobal2, breakThroughMany: breakThroughMany, ifChainEmpty: ifChainEmpty, heap8NoShift: heap8NoShift, conditionalTypeFun: conditionalTypeFun, loadSigned: loadSigned, globalOpts: globalOpts, dropCallImport: dropCallImport, loophi: loophi, loophi2: loophi2, loophi2b: loophi2b, relooperJumpThreading: relooperJumpThreading, relooperJumpThreading__ZN4game14preloadweaponsEv: relooperJumpThreading__ZN4game14preloadweaponsEv, __Z12multi_varargiz: __Z12multi_varargiz, jumpThreadDrop: jumpThreadDrop, dropIgnoredImportInIf: dropIgnoredImportInIf, dropIgnoredImportsInIf: dropIgnoredImportsInIf, relooperJumpThreading_irreducible: relooperJumpThreading_irreducible, store_fround: store_fround, exportedNumber: 42, relocatableAndModules: relocatableAndModules, exported_f32_user: exported_f32_user, keepAlive: keepAlive };
794799
}
795800

test/unit.fromasm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
(export "frem" (func $frem))
3737
(export "frem_float" (func $legalstub$frem_float))
3838
(export "big_uint_div_u" (func $big_uint_div_u))
39+
(export "trapping_sint_div_s" (func $trapping_sint_div_s))
3940
(export "fr" (func $legalstub$fr))
4041
(export "negZero" (func $negZero))
4142
(export "neg" (func $neg))
@@ -254,6 +255,9 @@
254255
(func $big_uint_div_u (result i32)
255256
(i32.const 2147483647)
256257
)
258+
(func $trapping_sint_div_s (result i32)
259+
(i32.const 0)
260+
)
257261
(func $fr (param $0 f32)
258262
(nop)
259263
)

test/unit.fromasm.clamp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
(export "frem" (func $frem))
3535
(export "frem_float" (func $legalstub$frem_float))
3636
(export "big_uint_div_u" (func $big_uint_div_u))
37+
(export "trapping_sint_div_s" (func $trapping_sint_div_s))
3738
(export "fr" (func $legalstub$fr))
3839
(export "negZero" (func $negZero))
3940
(export "neg" (func $neg))
@@ -302,6 +303,9 @@
302303
(func $big_uint_div_u (result i32)
303304
(i32.const 2147483647)
304305
)
306+
(func $trapping_sint_div_s (result i32)
307+
(i32.const 0)
308+
)
305309
(func $fr (param $0 f32)
306310
(nop)
307311
)

test/unit.fromasm.clamp.no-opts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
(export "frem" (func $frem))
4242
(export "frem_float" (func $legalstub$frem_float))
4343
(export "big_uint_div_u" (func $big_uint_div_u))
44+
(export "trapping_sint_div_s" (func $trapping_sint_div_s))
4445
(export "fr" (func $legalstub$fr))
4546
(export "negZero" (func $negZero))
4647
(export "neg" (func $neg))
@@ -477,6 +478,43 @@
477478
(get_local $x)
478479
)
479480
)
481+
(func $i32s-div (param $0 i32) (param $1 i32) (result i32)
482+
(if (result i32)
483+
(i32.eqz
484+
(get_local $1)
485+
)
486+
(i32.const 0)
487+
(if (result i32)
488+
(i32.and
489+
(i32.eq
490+
(get_local $0)
491+
(i32.const -2147483648)
492+
)
493+
(i32.eq
494+
(get_local $1)
495+
(i32.const -1)
496+
)
497+
)
498+
(i32.const 0)
499+
(i32.div_s
500+
(get_local $0)
501+
(get_local $1)
502+
)
503+
)
504+
)
505+
)
506+
(func $trapping_sint_div_s (result i32)
507+
(local $x i32)
508+
(set_local $x
509+
(call $i32s-div
510+
(i32.const -2147483648)
511+
(i32.const -1)
512+
)
513+
)
514+
(return
515+
(get_local $x)
516+
)
517+
)
480518
(func $fr (param $x f32)
481519
(local $y f32)
482520
(local $z f64)

test/unit.fromasm.imprecise

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
(export "frem" (func $frem))
3434
(export "frem_float" (func $legalstub$frem_float))
3535
(export "big_uint_div_u" (func $big_uint_div_u))
36+
(export "trapping_sint_div_s" (func $trapping_sint_div_s))
3637
(export "fr" (func $legalstub$fr))
3738
(export "negZero" (func $negZero))
3839
(export "neg" (func $neg))
@@ -240,6 +241,12 @@
240241
(func $big_uint_div_u (result i32)
241242
(i32.const 2147483647)
242243
)
244+
(func $trapping_sint_div_s (result i32)
245+
(i32.div_s
246+
(i32.const -2147483648)
247+
(i32.const -1)
248+
)
249+
)
243250
(func $fr (param $0 f32)
244251
(nop)
245252
)

test/unit.fromasm.imprecise.no-opts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
(export "frem" (func $frem))
4242
(export "frem_float" (func $legalstub$frem_float))
4343
(export "big_uint_div_u" (func $big_uint_div_u))
44+
(export "trapping_sint_div_s" (func $trapping_sint_div_s))
4445
(export "fr" (func $legalstub$fr))
4546
(export "negZero" (func $negZero))
4647
(export "neg" (func $neg))
@@ -413,6 +414,18 @@
413414
(get_local $x)
414415
)
415416
)
417+
(func $trapping_sint_div_s (result i32)
418+
(local $x i32)
419+
(set_local $x
420+
(i32.div_s
421+
(i32.const -2147483648)
422+
(i32.const -1)
423+
)
424+
)
425+
(return
426+
(get_local $x)
427+
)
428+
)
416429
(func $fr (param $x f32)
417430
(local $y f32)
418431
(local $z f64)

test/unit.fromasm.no-opts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
(export "frem" (func $frem))
4444
(export "frem_float" (func $legalstub$frem_float))
4545
(export "big_uint_div_u" (func $big_uint_div_u))
46+
(export "trapping_sint_div_s" (func $trapping_sint_div_s))
4647
(export "fr" (func $legalstub$fr))
4748
(export "negZero" (func $negZero))
4849
(export "neg" (func $neg))
@@ -429,6 +430,43 @@
429430
(get_local $x)
430431
)
431432
)
433+
(func $i32s-div (param $0 i32) (param $1 i32) (result i32)
434+
(if (result i32)
435+
(i32.eqz
436+
(get_local $1)
437+
)
438+
(i32.const 0)
439+
(if (result i32)
440+
(i32.and
441+
(i32.eq
442+
(get_local $0)
443+
(i32.const -2147483648)
444+
)
445+
(i32.eq
446+
(get_local $1)
447+
(i32.const -1)
448+
)
449+
)
450+
(i32.const 0)
451+
(i32.div_s
452+
(get_local $0)
453+
(get_local $1)
454+
)
455+
)
456+
)
457+
)
458+
(func $trapping_sint_div_s (result i32)
459+
(local $x i32)
460+
(set_local $x
461+
(call $i32s-div
462+
(i32.const -2147483648)
463+
(i32.const -1)
464+
)
465+
)
466+
(return
467+
(get_local $x)
468+
)
469+
)
432470
(func $fr (param $x f32)
433471
(local $y f32)
434472
(local $z f64)

0 commit comments

Comments
 (0)