summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-09-07 16:50:03 -0700
committerGitHub <noreply@github.com>2016-09-07 16:50:03 -0700
commit87f65f1623983bfc516ff4b222a3bb2537971837 (patch)
treee0f64742eac547534e4e9b82f12a7c02202fb3ea /src
parent135a20cd110d356d5d098a08a7b447205adaed7a (diff)
parentc24b9f9f6af61abd9ef124837bee41cbba35a8f2 (diff)
downloadbinaryen-87f65f1623983bfc516ff4b222a3bb2537971837.tar.gz
binaryen-87f65f1623983bfc516ff4b222a3bb2537971837.tar.bz2
binaryen-87f65f1623983bfc516ff4b222a3bb2537971837.zip
Merge pull request #694 from WebAssembly/binary-order-fix
Ordering bug fixes for windows
Diffstat (limited to 'src')
-rw-r--r--src/passes/OptimizeInstructions.cpp20
-rw-r--r--src/support/threads.h18
-rw-r--r--src/wasm-binary.h9
-rw-r--r--src/wasm-module-building.h8
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];