summaryrefslogtreecommitdiff
path: root/src/ir/memory-utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir/memory-utils.h')
-rw-r--r--src/ir/memory-utils.h75
1 files changed, 37 insertions, 38 deletions
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