summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2024-04-09 12:39:11 -0700
committerGitHub <noreply@github.com>2024-04-09 12:39:11 -0700
commit0ee46de2e3073609c062af98e5f8c13b9f5f5284 (patch)
treeb1550aacc132074a778bd882d1957a3269eb0fc7 /src
parent102c3633d2378457dae1f5e239fd63ad80eefb92 (diff)
downloadbinaryen-0ee46de2e3073609c062af98e5f8c13b9f5f5284.tar.gz
binaryen-0ee46de2e3073609c062af98e5f8c13b9f5f5284.tar.bz2
binaryen-0ee46de2e3073609c062af98e5f8c13b9f5f5284.zip
Asyncify: Fix nondeterminism in verbose logging (#6479)
#6457 added a test that exposed existing nondeterminism.
Diffstat (limited to 'src')
-rw-r--r--src/ir/module-utils.h7
-rw-r--r--src/passes/Asyncify.cpp21
2 files changed, 24 insertions, 4 deletions
diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h
index 190191cd7..0a101e5da 100644
--- a/src/ir/module-utils.h
+++ b/src/ir/module-utils.h
@@ -393,6 +393,13 @@ template<typename T> struct CallGraphPropertyAnalysis {
// addProperty() - Adds the property.
// logVisit() - Log each visit of the propagation. This is called before
// we check if the function already has the property.
+ //
+ // Note that the order of propagation here is *not* deterministic, for
+ // efficiency reasons (specifically, |calledBy| is unordered and also is
+ // generated by |callsTo| which is likewise unordered). If the order matters
+ // we could add an ordered variant of this. For now, users that care about
+ // ordering in the middle need to handle this (e.g. Asyncify - if we add such
+ // an ordered variant, we could use it there).
void propagateBack(std::function<bool(const T&)> hasProperty,
std::function<bool(const T&)> canHaveProperty,
std::function<void(T&)> addProperty,
diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp
index b74c1d7ae..1ba764387 100644
--- a/src/passes/Asyncify.cpp
+++ b/src/passes/Asyncify.cpp
@@ -711,21 +711,34 @@ public:
handleAddList(scanner.map);
}
+ // The order of propagation in |propagateBack| is non-deterministic, so sort
+ // the loggings we intend to do.
+ std::vector<std::string> loggings;
+
scanner.propagateBack([](const Info& info) { return info.canChangeState; },
[](const Info& info) {
return !info.isBottomMostRuntime &&
!info.inRemoveList;
},
[](Info& info) { info.canChangeState = true; },
- [verbose](const Info& info, Function* reason) {
+ [&](const Info& info, Function* reason) {
if (verbose) {
- std::cout << "[asyncify] " << info.name
- << " can change the state due to "
- << reason->name << "\n";
+ std::stringstream str;
+ str << "[asyncify] " << info.name
+ << " can change the state due to "
+ << reason->name << "\n";
+ loggings.push_back(str.str());
}
},
scanner.IgnoreNonDirectCalls);
+ if (!loggings.empty()) {
+ std::sort(loggings.begin(), loggings.end());
+ for (auto& logging : loggings) {
+ std::cout << logging;
+ }
+ }
+
map.swap(scanner.map);
if (!onlyListInput.empty()) {