diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-09-07 10:38:49 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-09-07 12:04:01 -0700 |
commit | c24b9f9f6af61abd9ef124837bee41cbba35a8f2 (patch) | |
tree | e0f64742eac547534e4e9b82f12a7c02202fb3ea | |
parent | 5d3fbce683a80a2dcbe17d9e100d6a0a287412ff (diff) | |
download | binaryen-c24b9f9f6af61abd9ef124837bee41cbba35a8f2.tar.gz binaryen-c24b9f9f6af61abd9ef124837bee41cbba35a8f2.tar.bz2 binaryen-c24b9f9f6af61abd9ef124837bee41cbba35a8f2.zip |
ensure we create the OptimizeInstructions database on demand, avoiding global ctors
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 20 | ||||
-rw-r--r-- | src/support/threads.h | 18 | ||||
-rw-r--r-- | src/wasm-module-building.h | 8 |
3 files changed, 43 insertions, 3 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 9fa059327..2a5e7b8c4 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -23,6 +23,7 @@ #include <wasm.h> #include <pass.h> #include <wasm-s-parser.h> +#include <support/threads.h> namespace wasm { @@ -71,7 +72,16 @@ struct PatternDatabase { }; }; -static PatternDatabase database; +static PatternDatabase* database = nullptr; + +static void ensureDatabase() { + if (!database) { + // we must only ever create one database + static OnlyOnce onlyOnce; + onlyOnce.verify(); + database = new PatternDatabase; + } +} // Check for matches and apply them struct Match { @@ -151,11 +161,15 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions, Pass* create() override { return new OptimizeInstructions; } + OptimizeInstructions() { + ensureDatabase(); + } + void visitExpression(Expression* curr) { // we may be able to apply multiple patterns, one may open opportunities that look deeper NB: patterns must not have cycles while (1) { - auto iter = database.patternMap.find(curr->_id); - if (iter == database.patternMap.end()) return; + auto iter = database->patternMap.find(curr->_id); + if (iter == database->patternMap.end()) return; auto& patterns = iter->second; bool more = false; for (auto& pattern : patterns) { diff --git a/src/support/threads.h b/src/support/threads.h index ea9e53c13..45c09e602 100644 --- a/src/support/threads.h +++ b/src/support/threads.h @@ -105,6 +105,24 @@ private: bool areThreadsReady(); }; +// Verify a code segment is only entered once. Usage: +// static OnlyOnce onlyOnce; +// onlyOnce.verify(); + +class OnlyOnce { + std::atomic<int> created; + +public: + OnlyOnce() { + created.store(0); + } + + void verify() { + auto before = created.fetch_add(1); + assert(before == 0); + } +}; + } // namespace wasm #endif // wasm_support_threads_h diff --git a/src/wasm-module-building.h b/src/wasm-module-building.h index 43cc493d1..52a4e7536 100644 --- a/src/wasm-module-building.h +++ b/src/wasm-module-building.h @@ -96,6 +96,14 @@ public: return; } + // Before parallelism, create all passes on the main thread here, to ensure + // constructors run at least once on the main thread, for one-time init things. + { + PassRunner passRunner(wasm); + addPrePasses(passRunner); + passRunner.addDefaultFunctionOptimizationPasses(); + } + // prepare work list endMarker = new Function(); list = new std::atomic<Function*>[numFunctions]; |