[lld] r374940 - [WebAssembly] Elide data segments for .bss sections

Thomas Lively via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 15 12:05:11 PDT 2019


Author: tlively
Date: Tue Oct 15 12:05:11 2019
New Revision: 374940

URL: http://llvm.org/viewvc/llvm-project?rev=374940&view=rev
Log:
[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

Added:
    lld/trunk/test/wasm/bss-only.ll
Modified:
    lld/trunk/test/wasm/Inputs/locals-duplicate1.ll
    lld/trunk/test/wasm/Inputs/locals-duplicate2.ll
    lld/trunk/test/wasm/custom-section-name.ll
    lld/trunk/test/wasm/data-layout.ll
    lld/trunk/test/wasm/data-segments.ll
    lld/trunk/test/wasm/locals-duplicate.test
    lld/trunk/wasm/OutputSections.cpp
    lld/trunk/wasm/OutputSections.h
    lld/trunk/wasm/OutputSegment.h
    lld/trunk/wasm/SyntheticSections.cpp
    lld/trunk/wasm/SyntheticSections.h
    lld/trunk/wasm/Writer.cpp

Modified: lld/trunk/test/wasm/Inputs/locals-duplicate1.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/Inputs/locals-duplicate1.ll?rev=374940&r1=374939&r2=374940&view=diff
==============================================================================
--- lld/trunk/test/wasm/Inputs/locals-duplicate1.ll (original)
+++ lld/trunk/test/wasm/Inputs/locals-duplicate1.ll Tue Oct 15 12:05:11 2019
@@ -1,11 +1,11 @@
 target triple = "wasm32-unknown-unknown"
 
 ; Will collide: local (internal linkage) with global (external) linkage
- at colliding_global1 = internal default global i32 0, align 4
+ at colliding_global1 = internal default global i32 1, align 4
 ; Will collide: global with local
- at colliding_global2 = default global i32 0, align 4
+ at colliding_global2 = default global i32 1, align 4
 ; Will collide: local with local
- at colliding_global3 = internal default global i32 0, align 4
+ at colliding_global3 = internal default global i32 1, align 4
 
 ; Will collide: local with global
 define internal i32 @colliding_func1() {

Modified: lld/trunk/test/wasm/Inputs/locals-duplicate2.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/Inputs/locals-duplicate2.ll?rev=374940&r1=374939&r2=374940&view=diff
==============================================================================
--- lld/trunk/test/wasm/Inputs/locals-duplicate2.ll (original)
+++ lld/trunk/test/wasm/Inputs/locals-duplicate2.ll Tue Oct 15 12:05:11 2019
@@ -1,11 +1,11 @@
 target triple = "wasm32-unknown-unknown"
 
 ; Will collide: local (internal linkage) with global (external) linkage
- at colliding_global1 = default global i32 0, align 4
+ at colliding_global1 = default global i32 1, align 4
 ; Will collide: global with local
- at colliding_global2 = internal default global i32 0, align 4
+ at colliding_global2 = internal default global i32 1, align 4
 ; Will collide: local with local
- at colliding_global3 = internal default global i32 0, align 4
+ at colliding_global3 = internal default global i32 1, align 4
 
 ; Will collide: local with global
 define i32 @colliding_func1() {

Added: lld/trunk/test/wasm/bss-only.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/bss-only.ll?rev=374940&view=auto
==============================================================================
--- lld/trunk/test/wasm/bss-only.ll (added)
+++ lld/trunk/test/wasm/bss-only.ll Tue Oct 15 12:05:11 2019
@@ -0,0 +1,14 @@
+; RUN: llc -filetype=obj %s -o %t.o
+; RUN: wasm-ld -no-gc-sections --no-entry %t.o -o %t.wasm
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+; Test that the data section is skipped entirely when there are only
+; bss segments
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+ at a = global [1000 x i8] zeroinitializer, align 1
+ at b = global i32 0
+
+; CHECK-NOT: - Type:            DATA

Modified: lld/trunk/test/wasm/custom-section-name.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/custom-section-name.ll?rev=374940&r1=374939&r2=374940&view=diff
==============================================================================
--- lld/trunk/test/wasm/custom-section-name.ll (original)
+++ lld/trunk/test/wasm/custom-section-name.ll Tue Oct 15 12:05:11 2019
@@ -1,6 +1,8 @@
 ; RUN: llc -filetype=obj %s -o %t.o
 ; RUN: wasm-ld -no-gc-sections --no-entry -o %t.wasm %t.o
-; RUN: obj2yaml %t.wasm | FileCheck %s
+; RUN: obj2yaml %t.wasm | FileCheck %s --check-prefixes=CHECK,NO-BSS
+; RUN: wasm-ld -no-gc-sections --no-entry --import-memory -o %t.bss.wasm %t.o
+; RUN: obj2yaml %t.bss.wasm | FileCheck %s --check-prefixes=CHECK,BSS
 ; RUN: wasm-ld -no-gc-sections --no-entry -o %t_reloc.o %t.o --relocatable
 ; RUN: obj2yaml %t_reloc.o | FileCheck -check-prefix RELOC %s
 
@@ -32,12 +34,13 @@ target triple = "wasm32-unknown-unknown"
 ; CHECK-NEXT:          Opcode:          I32_CONST
 ; CHECK-NEXT:          Value:           1032
 ; CHECK-NEXT:        Content:         '07000000'
-; CHECK-NEXT:      - SectionOffset:   37
-; CHECK-NEXT:        InitFlags:       0
-; CHECK-NEXT:        Offset:
-; CHECK-NEXT:          Opcode:          I32_CONST
-; CHECK-NEXT:          Value:           1036
-; CHECK-NEXT:        Content:         '00000000'
+; BSS-NEXT:        - SectionOffset:   37
+; BSS-NEXT:          InitFlags:       0
+; BSS-NEXT:          Offset:
+; BSS-NEXT:            Opcode:          I32_CONST
+; BSS-NEXT:            Value:           1036
+; BSS-NEXT:          Content:         '00000000'
+; NO-BSS-NOT:      - SectionOffset:
 
 ; RELOC-LABEL: SegmentInfo:
 ; RELOC-NEXT:    - Index:           0

Modified: lld/trunk/test/wasm/data-layout.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/data-layout.ll?rev=374940&r1=374939&r2=374940&view=diff
==============================================================================
--- lld/trunk/test/wasm/data-layout.ll (original)
+++ lld/trunk/test/wasm/data-layout.ll Tue Oct 15 12:05:11 2019
@@ -54,12 +54,6 @@ target triple = "wasm32-unknown-unknown"
 ; CHECK-NEXT:           Opcode:          I32_CONST
 ; CHECK-NEXT:           Value:           1040
 ; CHECK-NEXT:         Content:         '0100000000000000000000000000000003000000000000000004000034040000'
-; CHECK-NEXT:       - SectionOffset:   58
-; CHECK-NEXT:         InitFlags:       0
-; CHECK-NEXT:         Offset:
-; CHECK-NEXT:           Opcode:          I32_CONST
-; CHECK-NEXT:           Value:           1072
-; CHECK-NEXT:         Content:         '0000000000000000'
 ; CHECK-NEXT:    - Type:            CUSTOM
 
 

Modified: lld/trunk/test/wasm/data-segments.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/data-segments.ll?rev=374940&r1=374939&r2=374940&view=diff
==============================================================================
--- lld/trunk/test/wasm/data-segments.ll (original)
+++ lld/trunk/test/wasm/data-segments.ll Tue Oct 15 12:05:11 2019
@@ -44,13 +44,6 @@ target triple = "wasm32-unknown-unknown"
 ; ACTIVE-NEXT:          Opcode:          I32_CONST
 ; ACTIVE-NEXT:          Value:           1040
 ; ACTIVE-NEXT:        Content:         68656C6C6F00676F6F646279650000002A000000
-; ACTIVE-NEXT:      - SectionOffset:   53
-; ACTIVE-NEXT:        InitFlags:       0
-; ACTIVE-NEXT:        Offset:
-; ACTIVE-NEXT:          Opcode:          I32_CONST
-; ACTIVE-NEXT:          Value:           1060
-; ACTIVE-NEXT:        Content:         '0000000000
-; ACTIVE-SAME:                           0000000000'
 ; ACTIVE-NEXT:  - Type:            CUSTOM
 ; ACTIVE-NEXT:    Name:            name
 ; ACTIVE-NEXT:    FunctionNames:
@@ -78,10 +71,6 @@ target triple = "wasm32-unknown-unknown"
 ; PASSIVE-NEXT:      - SectionOffset:   18
 ; PASSIVE-NEXT:        InitFlags:       1
 ; PASSIVE-NEXT:        Content:         68656C6C6F00676F6F646279650000002A000000
-; PASSIVE-NEXT:      - SectionOffset:   41
-; PASSIVE-NEXT:        InitFlags:       1
-; PASSIVE-NEXT:        Content:         '0000000000
-; PASSIVE-SAME:                           0000000000'
 ; PASSIVE-NEXT:  - Type:            CUSTOM
 ; PASSIVE-NEXT:    Name:            name
 ; PASSIVE-NEXT:    FunctionNames:

Modified: lld/trunk/test/wasm/locals-duplicate.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/locals-duplicate.test?rev=374940&r1=374939&r2=374940&view=diff
==============================================================================
--- lld/trunk/test/wasm/locals-duplicate.test (original)
+++ lld/trunk/test/wasm/locals-duplicate.test Tue Oct 15 12:05:11 2019
@@ -167,7 +167,7 @@
 ; CHECK-NEXT:         Offset:
 ; CHECK-NEXT:           Opcode:          I32_CONST
 ; CHECK-NEXT:           Value:           1024
-; CHECK-NEXT:         Content:         '000000000000000000000000000000000000000000000000'
+; CHECK-NEXT:         Content:         '010000000100000001000000010000000100000001000000'
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            name
 ; CHECK-NEXT:     FunctionNames:
@@ -299,13 +299,13 @@
 ; RELOC-NEXT:         Locals:
 ; RELOC-NEXT:         Body:            4190808080000B
 ; RELOC-NEXT:       - Index:           6
-; RELOC-NEXT:         Locals:          
+; RELOC-NEXT:         Locals:
 ; RELOC-NEXT:         Body:            4181808080000B
 ; RELOC-NEXT:       - Index:           7
-; RELOC-NEXT:         Locals:          
+; RELOC-NEXT:         Locals:
 ; RELOC-NEXT:         Body:            4182808080000B
 ; RELOC-NEXT:       - Index:           8
-; RELOC-NEXT:         Locals:          
+; RELOC-NEXT:         Locals:
 ; RELOC-NEXT:         Body:            4183808080000B
 ; RELOC-NEXT:       - Index:           9
 ; RELOC-NEXT:         Locals:
@@ -326,13 +326,13 @@
 ; RELOC-NEXT:         Locals:
 ; RELOC-NEXT:         Body:            4194808080000B
 ; RELOC-NEXT:       - Index:           15
-; RELOC-NEXT:         Locals:          
+; RELOC-NEXT:         Locals:
 ; RELOC-NEXT:         Body:            4184808080000B
 ; RELOC-NEXT:       - Index:           16
-; RELOC-NEXT:         Locals:          
+; RELOC-NEXT:         Locals:
 ; RELOC-NEXT:         Body:            4185808080000B
 ; RELOC-NEXT:       - Index:           17
-; RELOC-NEXT:         Locals:          
+; RELOC-NEXT:         Locals:
 ; RELOC-NEXT:         Body:            4186808080000B
 ; RELOC-NEXT:   - Type:            DATA
 ; RELOC-NEXT:     Segments:
@@ -341,19 +341,19 @@
 ; RELOC-NEXT:         Offset:
 ; RELOC-NEXT:           Opcode:          I32_CONST
 ; RELOC-NEXT:           Value:           0
-; RELOC-NEXT:         Content:         '0000000000000000'
+; RELOC-NEXT:         Content:         '0100000001000000'
 ; RELOC-NEXT:       - SectionOffset:   19
 ; RELOC-NEXT:         InitFlags:       0
 ; RELOC-NEXT:         Offset:
 ; RELOC-NEXT:           Opcode:          I32_CONST
 ; RELOC-NEXT:           Value:           8
-; RELOC-NEXT:         Content:         '0000000000000000'
+; RELOC-NEXT:         Content:         '0100000001000000'
 ; RELOC-NEXT:       - SectionOffset:   32
 ; RELOC-NEXT:         InitFlags:       0
 ; RELOC-NEXT:         Offset:
 ; RELOC-NEXT:           Opcode:          I32_CONST
 ; RELOC-NEXT:           Value:           16
-; RELOC-NEXT:         Content:         '0000000000000000'
+; RELOC-NEXT:         Content:         '0100000001000000'
 ; RELOC-NEXT:   - Type:            CUSTOM
 ; RELOC-NEXT:     Name:            linking
 ; RELOC-NEXT:     Version:         2
@@ -489,15 +489,15 @@
 ; RELOC-NEXT:         Size:            4
 ; RELOC-NEXT:     SegmentInfo:
 ; RELOC-NEXT:       - Index:           0
-; RELOC-NEXT:         Name:            .bss.colliding_global1
+; RELOC-NEXT:         Name:            .data.colliding_global1
 ; RELOC-NEXT:         Alignment:       2
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:       - Index:           1
-; RELOC-NEXT:         Name:            .bss.colliding_global2
+; RELOC-NEXT:         Name:            .data.colliding_global2
 ; RELOC-NEXT:         Alignment:       2
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:       - Index:           2
-; RELOC-NEXT:         Name:            .bss.colliding_global3
+; RELOC-NEXT:         Name:            .data.colliding_global3
 ; RELOC-NEXT:         Alignment:       2
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:   - Type:            CUSTOM

Modified: lld/trunk/wasm/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/OutputSections.cpp?rev=374940&r1=374939&r2=374940&view=diff
==============================================================================
--- lld/trunk/wasm/OutputSections.cpp (original)
+++ lld/trunk/wasm/OutputSections.cpp Tue Oct 15 12:05:11 2019
@@ -128,8 +128,11 @@ void CodeSection::writeRelocations(raw_o
 
 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 @@ void DataSection::finalizeContents() {
          "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 @@ void DataSection::writeTo(uint8_t *buf)
   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 @@ void DataSection::writeRelocations(raw_o
       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);

Modified: lld/trunk/wasm/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/OutputSections.h?rev=374940&r1=374939&r2=374940&view=diff
==============================================================================
--- lld/trunk/wasm/OutputSections.h (original)
+++ lld/trunk/wasm/OutputSections.h Tue Oct 15 12:05:11 2019
@@ -82,7 +82,7 @@ public:
   void writeTo(uint8_t *buf) override;
   uint32_t getNumRelocations() const override;
   void writeRelocations(raw_ostream &os) const override;
-  bool isNeeded() const override { return segments.size() > 0; }
+  bool isNeeded() const override;
   void finalizeContents() override;
 
 protected:

Modified: lld/trunk/wasm/OutputSegment.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/OutputSegment.h?rev=374940&r1=374939&r2=374940&view=diff
==============================================================================
--- lld/trunk/wasm/OutputSegment.h (original)
+++ lld/trunk/wasm/OutputSegment.h Tue Oct 15 12:05:11 2019
@@ -32,6 +32,7 @@ public:
   }
 
   StringRef name;
+  bool isBss = false;
   uint32_t index = 0;
   uint32_t initFlags = 0;
   uint32_t sectionOffset = 0;

Modified: lld/trunk/wasm/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SyntheticSections.cpp?rev=374940&r1=374939&r2=374940&view=diff
==============================================================================
--- lld/trunk/wasm/SyntheticSections.cpp (original)
+++ lld/trunk/wasm/SyntheticSections.cpp Tue Oct 15 12:05:11 2019
@@ -365,6 +365,12 @@ void ElemSection::writeBody() {
   }
 }
 
+DataCountSection::DataCountSection(ArrayRef<OutputSegment *> segments)
+    : SyntheticSection(llvm::wasm::WASM_SEC_DATACOUNT),
+      numSegments(std::count_if(
+          segments.begin(), segments.end(),
+          [](OutputSegment *const segment) { return !segment->isBss; })) {}
+
 void DataCountSection::writeBody() {
   writeUleb128(bodyOutputStream, numSegments, "data count");
 }

Modified: lld/trunk/wasm/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SyntheticSections.h?rev=374940&r1=374939&r2=374940&view=diff
==============================================================================
--- lld/trunk/wasm/SyntheticSections.h (original)
+++ lld/trunk/wasm/SyntheticSections.h Tue Oct 15 12:05:11 2019
@@ -250,9 +250,7 @@ protected:
 
 class DataCountSection : public SyntheticSection {
 public:
-  DataCountSection(uint32_t numSegments)
-      : SyntheticSection(llvm::wasm::WASM_SEC_DATACOUNT),
-        numSegments(numSegments) {}
+  DataCountSection(ArrayRef<OutputSegment *> segments);
   bool isNeeded() const override;
   void writeBody() override;
 

Modified: lld/trunk/wasm/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Writer.cpp?rev=374940&r1=374939&r2=374940&view=diff
==============================================================================
--- lld/trunk/wasm/Writer.cpp (original)
+++ lld/trunk/wasm/Writer.cpp Tue Oct 15 12:05:11 2019
@@ -669,6 +669,13 @@ void Writer::createOutputSegments() {
         s = make<OutputSegment>(name);
         if (config->sharedMemory || name == ".tdata")
           s->initFlags = WASM_SEGMENT_IS_PASSIVE;
+        // Exported memories are guaranteed to be zero-initialized, so no need
+        // to emit data segments for bss sections.
+        // TODO: consider initializing bss sections with memory.fill
+        // instructions when memory is imported and bulk-memory is available.
+        if (!config->importMemory && !config->relocatable &&
+            name.startswith(".bss"))
+          s->isBss = true;
         segments.push_back(s);
       }
       s->addInputSegment(segment);
@@ -961,7 +968,7 @@ void Writer::createSyntheticSections() {
   out.exportSec = make<ExportSection>();
   out.startSec = make<StartSection>(segments.size());
   out.elemSec = make<ElemSection>();
-  out.dataCountSec = make<DataCountSection>(segments.size());
+  out.dataCountSec = make<DataCountSection>(segments);
   out.linkingSec = make<LinkingSection>(initFunctions, segments);
   out.nameSec = make<NameSection>();
   out.producersSec = make<ProducersSection>();




More information about the llvm-commits mailing list