[WebAssembly] Elide data segments for .bss sections
Summary:
WebAssembly memories are zero-initialized, so when module does not
import its memory initializing .bss sections is guaranteed to be a
no-op. To reduce binary size and initialization time, .bss sections
are simply not emitted into the final binary unless the memory is
imported.
Reviewers: sbc100
Subscribers: dschuff, jgravelle-google, aheejin, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D68965
llvm-svn: 374940
diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp
index 469a51a..0403f1d 100644
--- a/lld/wasm/OutputSections.cpp
+++ b/lld/wasm/OutputSections.cpp
@@ -128,8 +128,11 @@
void DataSection::finalizeContents() {
raw_string_ostream os(dataSectionHeader);
+ unsigned segmentCount =
+ std::count_if(segments.begin(), segments.end(),
+ [](OutputSegment *segment) { return !segment->isBss; });
- writeUleb128(os, segments.size(), "data segment count");
+ writeUleb128(os, segmentCount, "data segment count");
os.flush();
bodySize = dataSectionHeader.size();
@@ -137,6 +140,8 @@
"Currenly only a single data segment is supported in PIC mode");
for (OutputSegment *segment : segments) {
+ if (segment->isBss)
+ continue;
raw_string_ostream os(segment->header);
writeUleb128(os, segment->initFlags, "init flags");
if (segment->initFlags & WASM_SEGMENT_HAS_MEMINDEX)
@@ -181,6 +186,8 @@
memcpy(buf, dataSectionHeader.data(), dataSectionHeader.size());
for (const OutputSegment *segment : segments) {
+ if (segment->isBss)
+ continue;
// Write data segment header
uint8_t *segStart = buf + segment->sectionOffset;
memcpy(segStart, segment->header.data(), segment->header.size());
@@ -205,6 +212,13 @@
c->writeRelocations(os);
}
+bool DataSection::isNeeded() const {
+ for (const OutputSegment *seg : segments)
+ if (!seg->isBss)
+ return true;
+ return false;
+}
+
void CustomSection::finalizeContents() {
raw_string_ostream os(nameData);
encodeULEB128(name.size(), os);