summaryrefslogtreecommitdiff
path: root/src/ir
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir')
-rw-r--r--src/ir/ReFinalize.cpp3
-rw-r--r--src/ir/memory-utils.cpp26
-rw-r--r--src/ir/memory-utils.h75
-rw-r--r--src/ir/module-utils.h30
-rw-r--r--src/ir/utils.h2
5 files changed, 82 insertions, 54 deletions
diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp
index 79a4c9386..ef09ddbae 100644
--- a/src/ir/ReFinalize.cpp
+++ b/src/ir/ReFinalize.cpp
@@ -189,6 +189,9 @@ void ReFinalize::visitElementSegment(ElementSegment* curr) {
WASM_UNREACHABLE("unimp");
}
void ReFinalize::visitMemory(Memory* curr) { WASM_UNREACHABLE("unimp"); }
+void ReFinalize::visitDataSegment(DataSegment* curr) {
+ WASM_UNREACHABLE("unimp");
+}
void ReFinalize::visitTag(Tag* curr) { WASM_UNREACHABLE("unimp"); }
void ReFinalize::visitModule(Module* curr) { WASM_UNREACHABLE("unimp"); }
diff --git a/src/ir/memory-utils.cpp b/src/ir/memory-utils.cpp
index b7c92fe9e..8dc3baeb9 100644
--- a/src/ir/memory-utils.cpp
+++ b/src/ir/memory-utils.cpp
@@ -37,34 +37,36 @@ bool flatten(Module& wasm) {
}
}
- auto& memory = wasm.memory;
+ auto& dataSegments = wasm.dataSegments;
- if (memory.segments.size() == 0) {
+ if (dataSegments.size() == 0) {
return true;
}
std::vector<char> data;
- for (auto& segment : memory.segments) {
- if (segment.isPassive) {
+ for (auto& segment : dataSegments) {
+ if (segment->isPassive) {
return false;
}
- auto* offset = segment.offset->dynCast<Const>();
+ auto* offset = segment->offset->dynCast<Const>();
if (!offset) {
return false;
}
}
- for (auto& segment : memory.segments) {
- auto* offset = segment.offset->dynCast<Const>();
+ for (auto& segment : dataSegments) {
+ auto* offset = segment->offset->dynCast<Const>();
Index start = offset->value.getInteger();
- Index end = start + segment.data.size();
+ Index end = start + segment->data.size();
if (end > data.size()) {
data.resize(end);
}
- std::copy(segment.data.begin(), segment.data.end(), data.begin() + start);
+ std::copy(segment->data.begin(), segment->data.end(), data.begin() + start);
}
- memory.segments.resize(1);
- memory.segments[0].offset->cast<Const>()->value = Literal(int32_t(0));
- memory.segments[0].data.swap(data);
+ dataSegments.resize(1);
+ dataSegments[0]->offset->cast<Const>()->value = Literal(int32_t(0));
+ dataSegments[0]->data.swap(data);
+ wasm.removeDataSegments(
+ [&](DataSegment* curr) { return curr->name != dataSegments[0]->name; });
return true;
}
diff --git a/src/ir/memory-utils.h b/src/ir/memory-utils.h
index 9b3325329..5e9086ca4 100644
--- a/src/ir/memory-utils.h
+++ b/src/ir/memory-utils.h
@@ -43,8 +43,8 @@ inline void ensureExists(Memory& memory) {
// Try to merge segments until they fit into web limitations.
// Return true if successful.
inline bool ensureLimitedSegments(Module& module) {
- Memory& memory = module.memory;
- if (memory.segments.size() <= WebLimitations::MaxDataSegments) {
+ auto& dataSegments = module.dataSegments;
+ if (dataSegments.size() <= WebLimitations::MaxDataSegments) {
return true;
}
@@ -54,25 +54,23 @@ inline bool ensureLimitedSegments(Module& module) {
return false;
}
- auto isEmpty = [](Memory::Segment& segment) {
- return segment.data.size() == 0;
- };
+ auto isEmpty = [](DataSegment& segment) { return segment.data.size() == 0; };
- auto isConstantOffset = [](Memory::Segment& segment) {
+ auto isConstantOffset = [](DataSegment& segment) {
return segment.offset && segment.offset->is<Const>();
};
Index numConstant = 0, numDynamic = 0;
bool hasPassiveSegments = false;
- for (auto& segment : memory.segments) {
- if (!isEmpty(segment)) {
- if (isConstantOffset(segment)) {
+ for (auto& segment : dataSegments) {
+ if (!isEmpty(*segment)) {
+ if (isConstantOffset(*segment)) {
numConstant++;
} else {
numDynamic++;
}
}
- hasPassiveSegments |= segment.isPassive;
+ hasPassiveSegments |= segment->isPassive;
}
if (hasPassiveSegments) {
@@ -93,43 +91,43 @@ inline bool ensureLimitedSegments(Module& module) {
assert(num == WebLimitations::MaxDataSegments - 1);
}
- std::vector<Memory::Segment> mergedSegments;
+ std::vector<std::unique_ptr<wasm::DataSegment>> mergedSegments;
mergedSegments.reserve(WebLimitations::MaxDataSegments);
// drop empty segments and pass through dynamic-offset segments
- for (auto& segment : memory.segments) {
- if (isEmpty(segment)) {
+ for (auto& segment : dataSegments) {
+ if (isEmpty(*segment)) {
continue;
}
- if (isConstantOffset(segment)) {
+ if (isConstantOffset(*segment)) {
continue;
}
- mergedSegments.push_back(segment);
+ mergedSegments.push_back(std::move(segment));
}
// from here on, we concern ourselves with non-empty constant-offset
// segments, the ones which we may need to merge
- auto isRelevant = [&](Memory::Segment& segment) {
+ auto isRelevant = [&](DataSegment& segment) {
return !isEmpty(segment) && isConstantOffset(segment);
};
- for (Index i = 0; i < memory.segments.size(); i++) {
- auto& segment = memory.segments[i];
- if (!isRelevant(segment)) {
+ for (Index i = 0; i < dataSegments.size(); i++) {
+ auto& segment = dataSegments[i];
+ if (!isRelevant(*segment)) {
continue;
}
if (mergedSegments.size() + 2 < WebLimitations::MaxDataSegments) {
- mergedSegments.push_back(segment);
+ mergedSegments.push_back(std::move(segment));
continue;
}
// we can emit only one more segment! merge everything into one
// start the combined segment at the bottom of them all
- auto start = segment.offset->cast<Const>()->value.getInteger();
- for (Index j = i + 1; j < memory.segments.size(); j++) {
- auto& segment = memory.segments[j];
- if (!isRelevant(segment)) {
+ auto start = segment->offset->cast<Const>()->value.getInteger();
+ for (Index j = i + 1; j < dataSegments.size(); j++) {
+ auto& segment = dataSegments[j];
+ if (!isRelevant(*segment)) {
continue;
}
- auto offset = segment.offset->cast<Const>()->value.getInteger();
+ auto offset = segment->offset->cast<Const>()->value.getInteger();
start = std::min(start, offset);
}
// create the segment and add in all the data
@@ -137,26 +135,27 @@ inline bool ensureLimitedSegments(Module& module) {
c->value = Literal(int32_t(start));
c->type = Type::i32;
- Memory::Segment combined(c);
- for (Index j = i; j < memory.segments.size(); j++) {
- auto& segment = memory.segments[j];
- if (!isRelevant(segment)) {
+ auto combined = Builder::makeDataSegment();
+ combined->offset = c;
+ for (Index j = i; j < dataSegments.size(); j++) {
+ auto& segment = dataSegments[j];
+ if (!isRelevant(*segment)) {
continue;
}
- auto offset = segment.offset->cast<Const>()->value.getInteger();
- auto needed = offset + segment.data.size() - start;
- if (combined.data.size() < needed) {
- combined.data.resize(needed);
+ auto offset = segment->offset->cast<Const>()->value.getInteger();
+ auto needed = offset + segment->data.size() - start;
+ if (combined->data.size() < needed) {
+ combined->data.resize(needed);
}
- std::copy(segment.data.begin(),
- segment.data.end(),
- combined.data.begin() + (offset - start));
+ std::copy(segment->data.begin(),
+ segment->data.end(),
+ combined->data.begin() + (offset - start));
}
- mergedSegments.push_back(combined);
+ mergedSegments.push_back(std::move(combined));
break;
}
- memory.segments.swap(mergedSegments);
+ dataSegments.swap(mergedSegments);
return true;
}
} // namespace wasm::MemoryUtils
diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h
index 5030bf84f..4f731748e 100644
--- a/src/ir/module-utils.h
+++ b/src/ir/module-utils.h
@@ -106,6 +106,20 @@ inline Table* copyTable(const Table* table, Module& out) {
return out.addTable(std::move(ret));
}
+inline DataSegment* copyDataSegment(const DataSegment* segment, Module& out) {
+ auto ret = Builder::makeDataSegment();
+ ret->name = segment->name;
+ ret->hasExplicitName = segment->hasExplicitName;
+ ret->isPassive = segment->isPassive;
+ if (!segment->isPassive) {
+ auto offset = ExpressionManipulator::copy(segment->offset, out);
+ ret->offset = offset;
+ }
+ ret->data = segment->data;
+
+ return out.addDataSegment(std::move(ret));
+}
+
inline void copyModule(const Module& in, Module& out) {
// we use names throughout, not raw pointers, so simple copying is fine
// for everything *but* expressions
@@ -127,11 +141,10 @@ inline void copyModule(const Module& in, Module& out) {
for (auto& curr : in.tables) {
copyTable(curr.get(), out);
}
-
- out.memory = in.memory;
- for (auto& segment : out.memory.segments) {
- segment.offset = ExpressionManipulator::copy(segment.offset, out);
+ for (auto& curr : in.dataSegments) {
+ copyDataSegment(curr.get(), out);
}
+ out.memory = in.memory;
out.start = in.start;
out.userSections = in.userSections;
out.debugInfoFileNames = in.debugInfoFileNames;
@@ -205,6 +218,15 @@ template<typename T> inline void iterDefinedMemories(Module& wasm, T visitor) {
}
}
+template<typename T>
+inline void iterActiveDataSegments(Module& wasm, T visitor) {
+ for (auto& segment : wasm.dataSegments) {
+ if (!segment->isPassive) {
+ visitor(segment.get());
+ }
+ }
+}
+
template<typename T> inline void iterImportedTables(Module& wasm, T visitor) {
for (auto& import : wasm.tables) {
if (import->imported()) {
diff --git a/src/ir/utils.h b/src/ir/utils.h
index 7abc87b5e..cad4a78aa 100644
--- a/src/ir/utils.h
+++ b/src/ir/utils.h
@@ -139,6 +139,7 @@ struct ReFinalize
void visitTable(Table* curr);
void visitElementSegment(ElementSegment* curr);
void visitMemory(Memory* curr);
+ void visitDataSegment(DataSegment* curr);
void visitTag(Tag* curr);
void visitModule(Module* curr);
@@ -163,6 +164,7 @@ struct ReFinalizeNode : public OverriddenVisitor<ReFinalizeNode> {
void visitTable(Table* curr) { WASM_UNREACHABLE("unimp"); }
void visitElementSegment(ElementSegment* curr) { WASM_UNREACHABLE("unimp"); }
void visitMemory(Memory* curr) { WASM_UNREACHABLE("unimp"); }
+ void visitDataSegment(DataSegment* curr) { WASM_UNREACHABLE("unimp"); }
void visitTag(Tag* curr) { WASM_UNREACHABLE("unimp"); }
void visitModule(Module* curr) { WASM_UNREACHABLE("unimp"); }