Skip to content

optimize asm2wasm helper functions like i32-div #1208

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/asm2wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
if (body[i][0] == DEFUN) numFunctions++;
}
optimizingBuilder = make_unique<OptimizingIncrementalModuleBuilder>(&wasm, numFunctions, passOptions, [&](PassRunner& passRunner) {
// addPrePasses
if (debug) {
passRunner.setDebug(true);
passRunner.setValidateGlobally(false);
Expand All @@ -874,6 +875,18 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
}
// optimize relooper label variable usage at the wasm level, where it is easy
passRunner.add("relooper-jump-threading");
}, [&]() {
// beforeGlobalOptimizations
// if we added any helper functions (like non-trapping i32-div, etc.), then those
// have not been optimized (the optimizing builder has just been fed the asm.js
// functions). Optimize those now. Typically there are very few, just do it
// sequentially.
PassRunner passRunner(&wasm, passOptions);
passRunner.addDefaultFunctionOptimizationPasses();
for (auto& pair : trappingFunctions.getFunctions()) {
auto* func = pair.second;
passRunner.runFunction(func);
}
}, debug, false /* do not validate globally yet */);
}

Expand Down
4 changes: 4 additions & 0 deletions src/ast/trapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ class TrappingFunctionContainer {
return wasm;
}

std::map<Name, Function*>& getFunctions() {
return functions;
}

private:
std::map<Name, Function*> functions;
std::map<Name, Import*> imports;
Expand Down
23 changes: 15 additions & 8 deletions src/wasm-module-building.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class OptimizingIncrementalModuleBuilder {
uint32_t numFunctions;
PassOptions passOptions;
std::function<void (PassRunner&)> addPrePasses;
std::function<void ()> beforeGlobalOptimizations;
Function* endMarker;
std::atomic<Function*>* list;
uint32_t nextFunction; // only used on main thread
Expand All @@ -90,8 +91,13 @@ class OptimizingIncrementalModuleBuilder {
public:
// numFunctions must be equal to the number of functions allocated, or higher. Knowing
// this bounds helps avoid locking.
OptimizingIncrementalModuleBuilder(Module* wasm, Index numFunctions, PassOptions passOptions, std::function<void (PassRunner&)> addPrePasses, bool debug, bool validateGlobally)
: wasm(wasm), numFunctions(numFunctions), passOptions(passOptions), addPrePasses(addPrePasses), endMarker(nullptr), list(nullptr), nextFunction(0),
OptimizingIncrementalModuleBuilder(Module* wasm, Index numFunctions, PassOptions passOptions,
std::function<void (PassRunner&)> addPrePasses,
std::function<void ()> beforeGlobalOptimizations,
bool debug, bool validateGlobally)
: wasm(wasm), numFunctions(numFunctions), passOptions(passOptions),
addPrePasses(addPrePasses), beforeGlobalOptimizations(beforeGlobalOptimizations),
endMarker(nullptr), list(nullptr), nextFunction(0),
numWorkers(0), liveWorkers(0), activeWorkers(0), availableFuncs(0), finishedFuncs(0),
finishing(false), debug(debug), validateGlobally(validateGlobally) {

Expand Down Expand Up @@ -165,14 +171,13 @@ class OptimizingIncrementalModuleBuilder {
}
addPrePasses(passRunner);
passRunner.addDefaultFunctionOptimizationPasses();
passRunner.addDefaultGlobalOptimizationPostPasses();
passRunner.run();
return;
} else {
DEBUG_THREAD("finish()ing");
assert(nextFunction == numFunctions);
wakeAllWorkers();
waitUntilAllFinished();
}
DEBUG_THREAD("finish()ing");
assert(nextFunction == numFunctions);
wakeAllWorkers();
waitUntilAllFinished();
optimizeGlobally();
// TODO: clear side thread allocators from module allocator, as these threads were transient
}
Expand Down Expand Up @@ -225,9 +230,11 @@ class OptimizingIncrementalModuleBuilder {
}

void optimizeGlobally() {
beforeGlobalOptimizations();
PassRunner passRunner(wasm, passOptions);
passRunner.addDefaultGlobalOptimizationPostPasses();
passRunner.run();

}

// worker code
Expand Down
7 changes: 6 additions & 1 deletion test/unit.asm.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@ function asm(global, env, buffer) {
x = (4294967295 / 2)&-1;
return x | 0;
}
function trapping_sint_div_s() {
var x = 0;
x = (-2147483648 / -1);
return x | 0;
}
function fr(x) {
x = Math_fround(x);
var y = Math_fround(0), z = 0.0;
Expand Down Expand Up @@ -790,6 +795,6 @@ function asm(global, env, buffer) {
var FUNCTION_TABLE_vi = [ vi, vi, vi, vi, vi, vi, vi, vi ];
var FUNCTION_TABLE_ii = [ ii ];

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 };
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 };
}

4 changes: 4 additions & 0 deletions test/unit.fromasm
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
(export "frem" (func $frem))
(export "frem_float" (func $legalstub$frem_float))
(export "big_uint_div_u" (func $big_uint_div_u))
(export "trapping_sint_div_s" (func $trapping_sint_div_s))
(export "fr" (func $legalstub$fr))
(export "negZero" (func $negZero))
(export "neg" (func $neg))
Expand Down Expand Up @@ -254,6 +255,9 @@
(func $big_uint_div_u (result i32)
(i32.const 2147483647)
)
(func $trapping_sint_div_s (result i32)
(i32.const 0)
)
(func $fr (param $0 f32)
(nop)
)
Expand Down
4 changes: 4 additions & 0 deletions test/unit.fromasm.clamp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
(export "frem" (func $frem))
(export "frem_float" (func $legalstub$frem_float))
(export "big_uint_div_u" (func $big_uint_div_u))
(export "trapping_sint_div_s" (func $trapping_sint_div_s))
(export "fr" (func $legalstub$fr))
(export "negZero" (func $negZero))
(export "neg" (func $neg))
Expand Down Expand Up @@ -302,6 +303,9 @@
(func $big_uint_div_u (result i32)
(i32.const 2147483647)
)
(func $trapping_sint_div_s (result i32)
(i32.const 0)
)
(func $fr (param $0 f32)
(nop)
)
Expand Down
38 changes: 38 additions & 0 deletions test/unit.fromasm.clamp.no-opts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
(export "frem" (func $frem))
(export "frem_float" (func $legalstub$frem_float))
(export "big_uint_div_u" (func $big_uint_div_u))
(export "trapping_sint_div_s" (func $trapping_sint_div_s))
(export "fr" (func $legalstub$fr))
(export "negZero" (func $negZero))
(export "neg" (func $neg))
Expand Down Expand Up @@ -477,6 +478,43 @@
(get_local $x)
)
)
(func $i32s-div (param $0 i32) (param $1 i32) (result i32)
(if (result i32)
(i32.eqz
(get_local $1)
)
(i32.const 0)
(if (result i32)
(i32.and
(i32.eq
(get_local $0)
(i32.const -2147483648)
)
(i32.eq
(get_local $1)
(i32.const -1)
)
)
(i32.const 0)
(i32.div_s
(get_local $0)
(get_local $1)
)
)
)
)
(func $trapping_sint_div_s (result i32)
(local $x i32)
(set_local $x
(call $i32s-div
(i32.const -2147483648)
(i32.const -1)
)
)
(return
(get_local $x)
)
)
(func $fr (param $x f32)
(local $y f32)
(local $z f64)
Expand Down
7 changes: 7 additions & 0 deletions test/unit.fromasm.imprecise
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
(export "frem" (func $frem))
(export "frem_float" (func $legalstub$frem_float))
(export "big_uint_div_u" (func $big_uint_div_u))
(export "trapping_sint_div_s" (func $trapping_sint_div_s))
(export "fr" (func $legalstub$fr))
(export "negZero" (func $negZero))
(export "neg" (func $neg))
Expand Down Expand Up @@ -240,6 +241,12 @@
(func $big_uint_div_u (result i32)
(i32.const 2147483647)
)
(func $trapping_sint_div_s (result i32)
(i32.div_s
(i32.const -2147483648)
(i32.const -1)
)
)
(func $fr (param $0 f32)
(nop)
)
Expand Down
13 changes: 13 additions & 0 deletions test/unit.fromasm.imprecise.no-opts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
(export "frem" (func $frem))
(export "frem_float" (func $legalstub$frem_float))
(export "big_uint_div_u" (func $big_uint_div_u))
(export "trapping_sint_div_s" (func $trapping_sint_div_s))
(export "fr" (func $legalstub$fr))
(export "negZero" (func $negZero))
(export "neg" (func $neg))
Expand Down Expand Up @@ -413,6 +414,18 @@
(get_local $x)
)
)
(func $trapping_sint_div_s (result i32)
(local $x i32)
(set_local $x
(i32.div_s
(i32.const -2147483648)
(i32.const -1)
)
)
(return
(get_local $x)
)
)
(func $fr (param $x f32)
(local $y f32)
(local $z f64)
Expand Down
38 changes: 38 additions & 0 deletions test/unit.fromasm.no-opts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
(export "frem" (func $frem))
(export "frem_float" (func $legalstub$frem_float))
(export "big_uint_div_u" (func $big_uint_div_u))
(export "trapping_sint_div_s" (func $trapping_sint_div_s))
(export "fr" (func $legalstub$fr))
(export "negZero" (func $negZero))
(export "neg" (func $neg))
Expand Down Expand Up @@ -429,6 +430,43 @@
(get_local $x)
)
)
(func $i32s-div (param $0 i32) (param $1 i32) (result i32)
(if (result i32)
(i32.eqz
(get_local $1)
)
(i32.const 0)
(if (result i32)
(i32.and
(i32.eq
(get_local $0)
(i32.const -2147483648)
)
(i32.eq
(get_local $1)
(i32.const -1)
)
)
(i32.const 0)
(i32.div_s
(get_local $0)
(get_local $1)
)
)
)
)
(func $trapping_sint_div_s (result i32)
(local $x i32)
(set_local $x
(call $i32s-div
(i32.const -2147483648)
(i32.const -1)
)
)
(return
(get_local $x)
)
)
(func $fr (param $x f32)
(local $y f32)
(local $z f64)
Expand Down