[lld] r323931 - [WebAssembly] Write minimal types section

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 31 15:48:14 PST 2018


Author: sbc
Date: Wed Jan 31 15:48:14 2018
New Revision: 323931

URL: http://llvm.org/viewvc/llvm-project?rev=323931&view=rev
Log:
[WebAssembly] Write minimal types section

Don't include type signatures that are not referenced by
some relocation.

We don't include this in the -gc-sections settings since
we are always building the type section from scratch,
just like we do the table elements.

In the future we might want to unify the relocation
processing which is currently done once for gc-sections
and then again for building the sympathetic type and
table sections.

Differential Revision: https://reviews.llvm.org/D42747

Modified:
    lld/trunk/test/wasm/call-indirect.ll
    lld/trunk/test/wasm/gc-sections.ll
    lld/trunk/test/wasm/relocatable.ll
    lld/trunk/wasm/InputChunks.h
    lld/trunk/wasm/InputFiles.cpp
    lld/trunk/wasm/InputFiles.h
    lld/trunk/wasm/Writer.cpp

Modified: lld/trunk/test/wasm/call-indirect.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/call-indirect.ll?rev=323931&r1=323930&r2=323931&view=diff
==============================================================================
--- lld/trunk/test/wasm/call-indirect.ll (original)
+++ lld/trunk/test/wasm/call-indirect.ll Wed Jan 31 15:48:14 2018
@@ -43,21 +43,21 @@ define void @call_ptr(i64 (i64)* %arg) {
 ; CHECK-NEXT:         ReturnType:      I64
 ; CHECK-NEXT:         ParamTypes:
 ; CHECK-NEXT:       - Index:           1
-; CHECK-NEXT:         ReturnType:      NORESULT
+; CHECK-NEXT:         ReturnType:      I32
 ; CHECK-NEXT:         ParamTypes:
 ; CHECK-NEXT:       - Index:           2
-; CHECK-NEXT:         ReturnType:      I32
+; CHECK-NEXT:         ReturnType:      I64
 ; CHECK-NEXT:         ParamTypes:
+; CHECK-NEXT:           - I64
 ; CHECK-NEXT:       - Index:           3
 ; CHECK-NEXT:         ReturnType:      NORESULT
 ; CHECK-NEXT:         ParamTypes:
-; CHECK-NEXT:           - I32
 ; CHECK-NEXT:       - Index:           4
-; CHECK-NEXT:         ReturnType:      I64
+; CHECK-NEXT:         ReturnType:      NORESULT
 ; CHECK-NEXT:         ParamTypes:
-; CHECK-NEXT:           - I64
+; CHECK-NEXT:           - I32
 ; CHECK-NEXT:   - Type:            FUNCTION
-; CHECK-NEXT:     FunctionTypes:   [ 0, 1, 2, 2, 3, 1 ]
+; CHECK-NEXT:     FunctionTypes:   [ 0, 3, 1, 1, 4, 3 ]
 ; CHECK-NEXT:   - Type:            TABLE
 ; CHECK-NEXT:     Tables:
 ; CHECK-NEXT:       - ElemType:        ANYFUNC
@@ -120,16 +120,16 @@ define void @call_ptr(i64 (i64)* %arg) {
 ; CHECK-NEXT:         Locals:
 ; CHECK-NEXT:            - Type:            I32
 ; CHECK-NEXT:              Count:           1
-; CHECK-NEXT:          Body:            4100280284888080002100410028028088808000118080808000001A2000118280808000001A0B
+; CHECK-NEXT:          Body:            4100280284888080002100410028028088808000118080808000001A2000118180808000001A0B
 ; CHECK-NEXT:       - Index:           2
 ; CHECK-NEXT:         Locals:
 ; CHECK-NEXT:         Body:            41020B
 ; CHECK-NEXT:       - Index:           3
 ; CHECK-NEXT:         Locals:
-; CHECK-NEXT:         Body:            410028028888808000118280808000001A41000B
+; CHECK-NEXT:         Body:            410028028888808000118180808000001A41000B
 ; CHECK-NEXT:       - Index:           4
 ; CHECK-NEXT:         Locals:
-; CHECK-NEXT:         Body:            42012000118480808000001A0B
+; CHECK-NEXT:         Body:            42012000118280808000001A0B
 ; CHECK-NEXT:       - Index:           5
 ; CHECK-NEXT:         Locals:
 ; CHECK-NEXT:         Body:            0B

Modified: lld/trunk/test/wasm/gc-sections.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/gc-sections.ll?rev=323931&r1=323930&r2=323931&view=diff
==============================================================================
--- lld/trunk/test/wasm/gc-sections.ll (original)
+++ lld/trunk/test/wasm/gc-sections.ll Wed Jan 31 15:48:14 2018
@@ -7,12 +7,12 @@
 
 target triple = "wasm32-unknown-unknown-wasm"
 
- at unused_data = hidden global i32 1, align 4
+ at unused_data = hidden global i64 1, align 4
 @used_data = hidden global i32 2, align 4
 
-define hidden i32 @unused_function() {
-  %1 = load i32, i32* @unused_data, align 4
-  ret i32 %1
+define hidden i64 @unused_function() {
+  %1 = load i64, i64* @unused_data, align 4
+  ret i64 %1
 }
 
 define hidden i32 @used_function() {
@@ -27,6 +27,17 @@ entry:
 }
 
 ; RUN: obj2yaml %t1.wasm | FileCheck %s
+
+; CHECK:        - Type:            TYPE
+; CHECK-NEXT:     Signatures:      
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         ReturnType:      I32
+; CHECK-NEXT:         ParamTypes:      
+; CHECK-NEXT:       - Index:           1
+; CHECK-NEXT:         ReturnType:      NORESULT
+; CHECK-NEXT:         ParamTypes:      
+; CHECK-NEXT:   - Type:            FUNCTION
+
 ; CHECK:        - Type:            DATA
 ; CHECK-NEXT:     Segments:        
 ; CHECK-NEXT:       - SectionOffset:   7
@@ -51,6 +62,20 @@ entry:
 
 ; RUN: lld -flavor wasm -print-gc-sections --no-gc-sections -o %t1.no-gc.wasm %t.o
 ; RUN: obj2yaml %t1.no-gc.wasm | FileCheck %s -check-prefix=NO-GC
+
+; NO-GC:        - Type:            TYPE
+; NO-GC-NEXT:     Signatures:      
+; NO-GC-NEXT:       - Index:           0
+; NO-GC-NEXT:         ReturnType:      I64
+; NO-GC-NEXT:         ParamTypes:      
+; NO-GC-NEXT:       - Index:           1
+; NO-GC-NEXT:         ReturnType:      I32
+; NO-GC-NEXT:         ParamTypes:      
+; NO-GC-NEXT:       - Index:           2
+; NO-GC-NEXT:         ReturnType:      NORESULT
+; NO-GC-NEXT:         ParamTypes:      
+; NO-GC-NEXT:   - Type:            FUNCTION
+
 ; NO-GC:        - Type:            DATA
 ; NO-GC-NEXT:     Segments:        
 ; NO-GC-NEXT:       - SectionOffset:   7
@@ -58,10 +83,10 @@ entry:
 ; NO-GC-NEXT:         Offset:          
 ; NO-GC-NEXT:           Opcode:          I32_CONST
 ; NO-GC-NEXT:           Value:           1024
-; NO-GC-NEXT:         Content:         '0100000002000000'
+; NO-GC-NEXT:         Content:         '010000000000000002000000'
 ; NO-GC-NEXT:   - Type:            CUSTOM
 ; NO-GC-NEXT:     Name:            linking
-; NO-GC-NEXT:     DataSize:        8
+; NO-GC-NEXT:     DataSize:        12
 ; NO-GC-NEXT:   - Type:            CUSTOM
 ; NO-GC-NEXT:     Name:            name
 ; NO-GC-NEXT:     FunctionNames:   

Modified: lld/trunk/test/wasm/relocatable.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/relocatable.ll?rev=323931&r1=323930&r2=323931&view=diff
==============================================================================
--- lld/trunk/test/wasm/relocatable.ll (original)
+++ lld/trunk/test/wasm/relocatable.ll Wed Jan 31 15:48:14 2018
@@ -38,34 +38,34 @@ entry:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         ReturnType:      NORESULT
 ; CHECK-NEXT:         ParamTypes:
+; CHECK-NEXT:           - I32
 ; CHECK-NEXT:       - Index:           1
-; CHECK-NEXT:         ReturnType:      NORESULT
+; CHECK-NEXT:         ReturnType:      I32
 ; CHECK-NEXT:         ParamTypes:
-; CHECK-NEXT:           - I32
 ; CHECK-NEXT:       - Index:           2
-; CHECK-NEXT:         ReturnType:      I32
+; CHECK-NEXT:         ReturnType:      NORESULT
 ; CHECK-NEXT:         ParamTypes:
 ; CHECK-NEXT:   - Type:            IMPORT
 ; CHECK-NEXT:     Imports:
 ; CHECK-NEXT:       - Module:          env
 ; CHECK-NEXT:         Field:           puts
 ; CHECK-NEXT:         Kind:            FUNCTION
-; CHECK-NEXT:         SigIndex:        1
+; CHECK-NEXT:         SigIndex:        0
 ; CHECK-NEXT:       - Module:          env
 ; CHECK-NEXT:         Field:           foo_import
 ; CHECK-NEXT:         Kind:            FUNCTION
-; CHECK-NEXT:         SigIndex:        2
+; CHECK-NEXT:         SigIndex:        1
 ; CHECK-NEXT:       - Module:          env
 ; CHECK-NEXT:         Field:           bar_import
 ; CHECK-NEXT:         Kind:            FUNCTION
-; CHECK-NEXT:         SigIndex:        2
+; CHECK-NEXT:         SigIndex:        1
 ; CHECK-NEXT:       - Module:          env
 ; CHECK-NEXT:         Field:           data_import
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         GlobalType:      I32
 ; CHECK-NEXT:         GlobalMutable:   false
 ; CHECK-NEXT:   - Type:            FUNCTION
-; CHECK-NEXT:     FunctionTypes:   [ 0, 2, 2 ]
+; CHECK-NEXT:     FunctionTypes:   [ 2, 1, 1 ]
 ; CHECK-NEXT:   - Type:            TABLE
 ; CHECK-NEXT:     Tables:
 ; CHECK-NEXT:       - ElemType:        ANYFUNC

Modified: lld/trunk/wasm/InputChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputChunks.h?rev=323931&r1=323930&r2=323931&view=diff
==============================================================================
--- lld/trunk/wasm/InputChunks.h (original)
+++ lld/trunk/wasm/InputChunks.h Wed Jan 31 15:48:14 2018
@@ -59,14 +59,14 @@ public:
 
   bool Discarded = false;
   std::vector<OutputRelocation> OutRelocations;
-  const ObjFile *File;
+  ObjFile *File;
 
   // The garbage collector sets sections' Live bits.
   // If GC is disabled, all sections are considered live by default.
   unsigned Live : 1;
 
 protected:
-  InputChunk(const ObjFile *F, Kind K)
+  InputChunk(ObjFile *F, Kind K)
       : File(F), Live(!Config->GcSections), SectionKind(K) {}
   virtual ~InputChunk() = default;
   void calcRelocations();
@@ -88,7 +88,7 @@ protected:
 // each global variable.
 class InputSegment : public InputChunk {
 public:
-  InputSegment(const WasmSegment &Seg, const ObjFile *F)
+  InputSegment(const WasmSegment &Seg, ObjFile *F)
       : InputChunk(F, InputChunk::DataSegment), Segment(Seg) {}
 
   static bool classof(const InputChunk *C) { return C->kind() == DataSegment; }
@@ -127,7 +127,7 @@ protected:
 class InputFunction : public InputChunk {
 public:
   InputFunction(const WasmSignature &S, const WasmFunction *Func,
-                const ObjFile *F)
+                ObjFile *F)
       : InputChunk(F, InputChunk::Function), Signature(S), Function(Func) {}
 
   static bool classof(const InputChunk *C) {

Modified: lld/trunk/wasm/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.cpp?rev=323931&r1=323930&r2=323931&view=diff
==============================================================================
--- lld/trunk/wasm/InputFiles.cpp (original)
+++ lld/trunk/wasm/InputFiles.cpp Wed Jan 31 15:48:14 2018
@@ -63,6 +63,7 @@ uint32_t ObjFile::relocateFunctionIndex(
 }
 
 uint32_t ObjFile::relocateTypeIndex(uint32_t Original) const {
+  assert(TypeIsUsed[Original]);
   return TypeMap[Original];
 }
 
@@ -149,6 +150,9 @@ void ObjFile::parse() {
       DataSection = &Section;
   }
 
+  TypeMap.resize(getWasmObj()->types().size());
+  TypeIsUsed.resize(getWasmObj()->types().size(), false);
+
   initializeSymbols();
 }
 

Modified: lld/trunk/wasm/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.h?rev=323931&r1=323930&r2=323931&view=diff
==============================================================================
--- lld/trunk/wasm/InputFiles.h (original)
+++ lld/trunk/wasm/InputFiles.h Wed Jan 31 15:48:14 2018
@@ -101,6 +101,7 @@ public:
   const WasmSection *DataSection = nullptr;
 
   std::vector<uint32_t> TypeMap;
+  std::vector<bool> TypeIsUsed;
   std::vector<InputSegment *> Segments;
   std::vector<InputFunction *> Functions;
 

Modified: lld/trunk/wasm/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Writer.cpp?rev=323931&r1=323930&r2=323931&view=diff
==============================================================================
--- lld/trunk/wasm/Writer.cpp (original)
+++ lld/trunk/wasm/Writer.cpp Wed Jan 31 15:48:14 2018
@@ -689,15 +689,23 @@ uint32_t Writer::registerType(const Wasm
 }
 
 void Writer::calculateTypes() {
+  // The output type section is the union of the following sets:
+  // 1. Any signature used in the TYPE relocation
+  // 2. The signatures of all imported functions
+  // 3. The signatures of all defined functions
+
   for (ObjFile *File : Symtab->ObjectFiles) {
-    File->TypeMap.reserve(File->getWasmObj()->types().size());
-    for (const WasmSignature &Sig : File->getWasmObj()->types())
-      File->TypeMap.push_back(registerType(Sig));
+    ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
+    for (uint32_t I = 0; I < Types.size(); I++)
+      if (File->TypeIsUsed[I])
+        File->TypeMap[I] = registerType(Types[I]);
   }
 
-  for (Symbol *Sym : Symtab->getSymbols())
-    if (Sym->isFunction())
-      registerType(Sym->getFunctionType());
+  for (const Symbol *Sym : ImportedFunctions)
+    registerType(Sym->getFunctionType());
+
+  for (const InputFunction *F : DefinedFunctions)
+    registerType(F->Signature);
 }
 
 void Writer::assignIndexes() {
@@ -746,25 +754,30 @@ void Writer::assignIndexes() {
   }
 
   for (ObjFile *File : Symtab->ObjectFiles) {
-    DEBUG(dbgs() << "Table Indexes: " << File->getName() << "\n");
-    auto HandleTableRelocs = [&](InputChunk *Chunk) {
+    DEBUG(dbgs() << "Handle relocs: " << File->getName() << "\n");
+    auto HandleRelocs = [&](InputChunk *Chunk) {
       if (Chunk->Discarded)
         return;
+      ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
       for (const WasmRelocation& Reloc : Chunk->getRelocations()) {
-        if (Reloc.Type != R_WEBASSEMBLY_TABLE_INDEX_I32 &&
-            Reloc.Type != R_WEBASSEMBLY_TABLE_INDEX_SLEB)
-          continue;
-        Symbol *Sym = File->getFunctionSymbol(Reloc.Index);
-        if (Sym->hasTableIndex() || !Sym->hasOutputIndex())
-          continue;
-        Sym->setTableIndex(TableIndex++);
-        IndirectFunctions.emplace_back(Sym);
+        if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32 ||
+            Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB) {
+          Symbol *Sym = File->getFunctionSymbol(Reloc.Index);
+          if (Sym->hasTableIndex() || !Sym->hasOutputIndex())
+            continue;
+          Sym->setTableIndex(TableIndex++);
+          IndirectFunctions.emplace_back(Sym);
+        } else if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) {
+          Chunk->File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]);
+          Chunk->File->TypeIsUsed[Reloc.Index] = true;
+        }
       }
     };
+
     for (InputFunction* Function : File->Functions)
-      HandleTableRelocs(Function);
+      HandleRelocs(Function);
     for (InputSegment* Segment : File->Segments)
-      HandleTableRelocs(Segment);
+      HandleRelocs(Segment);
   }
 }
 
@@ -858,8 +871,6 @@ void Writer::calculateInitFunctions() {
 }
 
 void Writer::run() {
-  log("-- calculateTypes");
-  calculateTypes();
   log("-- calculateImports");
   calculateImports();
   log("-- assignIndexes");
@@ -870,6 +881,8 @@ void Writer::run() {
   calculateInitFunctions();
   if (!Config->Relocatable)
     createCtorFunction();
+  log("-- calculateTypes");
+  calculateTypes();
 
   if (errorHandler().Verbose) {
     log("Defined Functions: " + Twine(DefinedFunctions.size()));




More information about the llvm-commits mailing list