diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 20 | ||||
-rw-r--r-- | src/support/threads.h | 18 | ||||
-rw-r--r-- | src/wasm-binary.h | 9 | ||||
-rw-r--r-- | src/wasm-module-building.h | 8 |
4 files changed, 49 insertions, 6 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-binary.h b/src/wasm-binary.h index 40671b082..561a310b0 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1328,19 +1328,22 @@ public: } uint16_t getInt16() { if (debug) std::cerr << "<==" << std::endl; - auto ret = uint16_t(getInt8()) | (uint16_t(getInt8()) << 8); + auto ret = uint16_t(getInt8()); + ret |= uint16_t(getInt8()) << 8; if (debug) std::cerr << "getInt16: " << ret << " ==>" << std::endl; return ret; } uint32_t getInt32() { if (debug) std::cerr << "<==" << std::endl; - auto ret = uint32_t(getInt16()) | (uint32_t(getInt16()) << 16); + auto ret = uint32_t(getInt16()); + ret |= uint32_t(getInt16()) << 16; if (debug) std::cerr << "getInt32: " << ret << " ==>" << std::endl; return ret; } uint64_t getInt64() { if (debug) std::cerr << "<==" << std::endl; - auto ret = uint64_t(getInt32()) | (uint64_t(getInt32()) << 32); + auto ret = uint64_t(getInt32()); + ret |= uint64_t(getInt32()) << 32; if (debug) std::cerr << "getInt64: " << ret << " ==>" << std::endl; return ret; } 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]; |