summaryrefslogtreecommitdiff
path: root/src/ir/memory-utils.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2023-04-10 09:48:23 -0700
committerGitHub <noreply@github.com>2023-04-10 09:48:23 -0700
commit35a237db1b96b37cfa7638d2f8d22aa46a626683 (patch)
treeb308f9aa498f185f124a8d845faf8c99a728b233 /src/ir/memory-utils.cpp
parentbd91d8df9abc2194e648e257b9994d3d325c7a34 (diff)
downloadbinaryen-35a237db1b96b37cfa7638d2f8d22aa46a626683.tar.gz
binaryen-35a237db1b96b37cfa7638d2f8d22aa46a626683.tar.bz2
binaryen-35a237db1b96b37cfa7638d2f8d22aa46a626683.zip
Do not flatten memory when array.new_data is present (#5650)
Like data.drop etc., it notices data segment identity.
Diffstat (limited to 'src/ir/memory-utils.cpp')
-rw-r--r--src/ir/memory-utils.cpp37
1 files changed, 25 insertions, 12 deletions
diff --git a/src/ir/memory-utils.cpp b/src/ir/memory-utils.cpp
index b21d8f0ad..9ab0e33fc 100644
--- a/src/ir/memory-utils.cpp
+++ b/src/ir/memory-utils.cpp
@@ -27,20 +27,33 @@ bool flatten(Module& wasm) {
// The presence of any instruction that cares about segment identity is a
// problem because flattening gets rid of that (when it merges them all into
// one big segment).
- ModuleUtils::ParallelFunctionAnalysis<bool> analysis(
- wasm, [&](Function* func, bool& noticesSegmentIdentity) {
- if (func->imported()) {
- return;
- }
- noticesSegmentIdentity =
- FindAll<MemoryInit>(func->body).list.size() > 0 ||
- FindAll<DataDrop>(func->body).list.size() > 0;
- });
+ struct Scanner : public WalkerPass<PostWalker<Scanner>> {
+ std::atomic<bool>& noticesSegmentIdentity;
- for (auto& [func, noticesSegmentIdentity] : analysis.map) {
- if (noticesSegmentIdentity) {
- return false;
+ Scanner(std::atomic<bool>& noticesSegmentIdentity)
+ : noticesSegmentIdentity(noticesSegmentIdentity) {}
+
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<Scanner>(noticesSegmentIdentity);
+ }
+
+ void visitMemoryInit(MemoryInit* curr) { noticesSegmentIdentity = true; }
+ void visitDataDrop(DataDrop* curr) { noticesSegmentIdentity = true; }
+ void visitArrayNewSeg(ArrayNewSeg* curr) {
+ if (curr->op == NewData) {
+ noticesSegmentIdentity = true;
+ }
}
+ };
+
+ std::atomic<bool> noticesSegmentIdentity = false;
+ PassRunner runner(&wasm);
+ Scanner scanner(noticesSegmentIdentity);
+ scanner.setPassRunner(&runner);
+ scanner.run(&wasm);
+ scanner.runOnModuleCode(&runner, &wasm);
+ if (noticesSegmentIdentity) {
+ return false;
}
auto& dataSegments = wasm.dataSegments;