summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-09-07 10:38:49 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-09-07 12:04:01 -0700
commitc24b9f9f6af61abd9ef124837bee41cbba35a8f2 (patch)
treee0f64742eac547534e4e9b82f12a7c02202fb3ea
parent5d3fbce683a80a2dcbe17d9e100d6a0a287412ff (diff)
downloadbinaryen-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.cpp20
-rw-r--r--src/support/threads.h18
-rw-r--r--src/wasm-module-building.h8
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];