diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/asm2wasm.h | 13 | ||||
-rw-r--r-- | src/ast/trapping.h | 4 | ||||
-rw-r--r-- | src/wasm-module-building.h | 23 |
3 files changed, 32 insertions, 8 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 7d4ce5fbe..fc21b945b 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -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); @@ -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 */); } diff --git a/src/ast/trapping.h b/src/ast/trapping.h index 184e6059b..7b170ccb4 100644 --- a/src/ast/trapping.h +++ b/src/ast/trapping.h @@ -85,6 +85,10 @@ public: return wasm; } + std::map<Name, Function*>& getFunctions() { + return functions; + } + private: std::map<Name, Function*> functions; std::map<Name, Import*> imports; diff --git a/src/wasm-module-building.h b/src/wasm-module-building.h index c52cea9f9..61e98ba71 100644 --- a/src/wasm-module-building.h +++ b/src/wasm-module-building.h @@ -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 @@ -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) { @@ -165,14 +171,13 @@ public: } 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 } @@ -225,9 +230,11 @@ private: } void optimizeGlobally() { + beforeGlobalOptimizations(); PassRunner passRunner(wasm, passOptions); passRunner.addDefaultGlobalOptimizationPostPasses(); passRunner.run(); + } // worker code |