diff --git a/lld/test/wasm/data-segments.ll b/lld/test/wasm/data-segments.ll --- a/lld/test/wasm/data-segments.ll +++ b/lld/test/wasm/data-segments.ll @@ -52,6 +52,8 @@ ; PASSIVE-LABEL: - Type: START ; PASSIVE-NEXT: StartFunction: 1 +; PASSIVE-LABEL: - Type: DATACOUNT +; PASSIVE-NEXT: Count: 2 ; PASSIVE-LABEL: - Type: CODE ; PASSIVE-NEXT: Functions: ; PASSIVE-NEXT: - Index: 0 @@ -59,7 +61,8 @@ ; PASSIVE-NEXT: Body: 0B ; PASSIVE-NEXT: - Index: 1 ; PASSIVE-NEXT: Locals: [] -; PASSIVE-NEXT: Body: 41B4D60041004101FE480200044041B4D6004101427FFE0102001A054180084100410DFC08000041900841004114FC08010041A40841004190CE00FC08020041B4D6004102FE17020041B4D600417FFE0002001A0BFC0900FC0901FC09020B +; PASSIVE-NEXT: Body: 41B4D60041004101FE480200044041B4D6004101427FFE0102001A054180084100410DFC08000041900841004114FC08010041B4D6004102FE17020041B4D600417FFE0002001A0BFC0900FC09010B + ; PASSIVE-NEXT: - Index: 2 ; PASSIVE-NEXT: Locals: [] ; PASSIVE-NEXT: Body: 0B diff --git a/lld/wasm/SyntheticSections.h b/lld/wasm/SyntheticSections.h --- a/lld/wasm/SyntheticSections.h +++ b/lld/wasm/SyntheticSections.h @@ -225,14 +225,14 @@ class StartSection : public SyntheticSection { public: - StartSection(uint32_t numSegments) - : SyntheticSection(llvm::wasm::WASM_SEC_START), numSegments(numSegments) { - } + StartSection(bool hasInitializedSegments) + : SyntheticSection(llvm::wasm::WASM_SEC_START), + hasInitializedSegments(hasInitializedSegments) {} bool isNeeded() const override; void writeBody() override; protected: - uint32_t numSegments; + bool hasInitializedSegments; }; class ElemSection : public SyntheticSection { diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp --- a/lld/wasm/SyntheticSections.cpp +++ b/lld/wasm/SyntheticSections.cpp @@ -326,7 +326,7 @@ } bool StartSection::isNeeded() const { - return !config->relocatable && numSegments && config->sharedMemory; + return !config->relocatable && hasInitializedSegments && config->sharedMemory; } void StartSection::writeBody() { diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -54,6 +54,9 @@ private: void openFile(); + bool needsPassiveInitialization(const OutputSegment *segment); + bool hasPassiveInitializedSegments(); + void createInitMemoryFunction(); void createApplyRelocationsFunction(); void createCallCtorsFunction(); @@ -729,6 +732,18 @@ cast(func->function)->setBody(body); } +bool Writer::needsPassiveInitialization(const OutputSegment *segment) { + return segment->initFlags & WASM_SEGMENT_IS_PASSIVE && + segment->name != ".tdata" && !segment->isBss; +} + +bool Writer::hasPassiveInitializedSegments() { + return std::find_if(segments.begin(), segments.end(), + [this](const OutputSegment *s) { + return this->needsPassiveInitialization(s); + }) != segments.end(); +} + void Writer::createInitMemoryFunction() { LLVM_DEBUG(dbgs() << "createInitMemoryFunction\n"); assert(WasmSym::initMemoryFlag); @@ -738,7 +753,7 @@ raw_string_ostream os(bodyContent); writeUleb128(os, 0, "num locals"); - if (segments.size()) { + if (hasPassiveInitializedSegments()) { // Initialize memory in a thread-safe manner. The thread that successfully // increments the flag from 0 to 1 is is responsible for performing the // memory initialization. Other threads go sleep on the flag until the @@ -804,7 +819,7 @@ // Did increment 0, so conditionally initialize passive data segments for (const OutputSegment *s : segments) { - if (s->initFlags & WASM_SEGMENT_IS_PASSIVE && s->name != ".tdata") { + if (needsPassiveInitialization(s)) { // destination address writeI32Const(os, s->startVA, "destination address"); // source segment offset @@ -838,7 +853,7 @@ // Unconditionally drop passive data segments for (const OutputSegment *s : segments) { - if (s->initFlags & WASM_SEGMENT_IS_PASSIVE && s->name != ".tdata") { + if (needsPassiveInitialization(s)) { // data.drop instruction writeU8(os, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix"); writeUleb128(os, WASM_OPCODE_DATA_DROP, "data.drop"); @@ -983,7 +998,7 @@ out.eventSec = make(); out.globalSec = make(); out.exportSec = make(); - out.startSec = make(segments.size()); + out.startSec = make(hasPassiveInitializedSegments()); out.elemSec = make(); out.dataCountSec = make(segments); out.linkingSec = make(initFunctions, segments);