diff options
Diffstat (limited to 'src/ir/memory-utils.h')
-rw-r--r-- | src/ir/memory-utils.h | 75 |
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 |