Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
[WebAssembly] Add support for --gc-sections
Browse files Browse the repository at this point in the history
In this initial version we only GC symbols with `hidden` visibility since
other symbols we export to the embedder.

We could potentially modify this the future and only use symbols
explicitly passed via `--export` as GC roots.

This version of the code only does GC of data and code. GC for the
types section is coming soon.

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

git-svn-id: https://llvm.org/svn/llvm-project/lld/trunk@323842 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
sbc100 committed Jan 31, 2018
1 parent 0e10ed2 commit c69119a
Show file tree
Hide file tree
Showing 17 changed files with 269 additions and 21 deletions.
2 changes: 1 addition & 1 deletion test/wasm/call-indirect.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; RUN: llc -filetype=obj %p/Inputs/call-indirect.ll -o %t2.o
; RUN: llc -filetype=obj %s -o %t.o
; RUN: lld -flavor wasm -o %t.wasm %t2.o %t.o
; RUN: lld -flavor wasm -no-gc-sections -o %t.wasm %t2.o %t.o
; RUN: obj2yaml %t.wasm | FileCheck %s

; bitcode generated from the following C code:
Expand Down
2 changes: 1 addition & 1 deletion test/wasm/comdats.ll
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/comdat1.ll -o %t1.o
; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/comdat2.ll -o %t2.o
; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o
; RUN: lld -flavor wasm -o %t.wasm %t.o %t1.o %t2.o
; RUN: lld -flavor wasm -no-gc-sections -o %t.wasm %t.o %t1.o %t2.o
; RUN: obj2yaml %t.wasm | FileCheck %s

target triple = "wasm32-unknown-unknown-wasm"
Expand Down
2 changes: 1 addition & 1 deletion test/wasm/data-layout.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ target triple = "wasm32-unknown-unknown-wasm"
@hello_str = external global i8*
@external_ref = global i8** @hello_str, align 8

; RUN: lld -flavor wasm --allow-undefined -o %t.wasm %t.o %t.hello.o
; RUN: lld -flavor wasm -no-gc-sections --allow-undefined -o %t.wasm %t.o %t.hello.o
; RUN: obj2yaml %t.wasm | FileCheck %s

; CHECK: - Type: GLOBAL
Expand Down
2 changes: 1 addition & 1 deletion test/wasm/entry.ll
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ entry:
; CHECK-CTOR-NEXT: Index: 0
; CHECK-CTOR-NEXT: - Name: __wasm_call_ctors
; CHECK-CTOR-NEXT: Kind: FUNCTION
; CHECK-CTOR-NEXT: Index: 1
; CHECK-CTOR-NEXT: Index: 0
79 changes: 79 additions & 0 deletions test/wasm/gc-sections.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
; RUN: llc -filetype=obj %s -o %t.o
; RUN: lld -flavor wasm -print-gc-sections -o %t1.wasm %t.o | FileCheck %s -check-prefix=PRINT-GC
; PRINT-GC: removing unused section 'unused_function' in file '{{.*}}'
; PRINT-GC-NOT: removing unused section 'used_function' in file '{{.*}}'
; PRINT-GC: removing unused section '.data.unused_data' in file '{{.*}}'
; PRINT-GC-NOT: removing unused section '.data.used_data' in file '{{.*}}'

target triple = "wasm32-unknown-unknown-wasm"

@unused_data = hidden global i32 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 i32 @used_function() {
%1 = load i32, i32* @used_data, align 4
ret i32 %1
}

define hidden void @_start() {
entry:
call i32 @used_function()
ret void
}

; RUN: obj2yaml %t1.wasm | FileCheck %s
; CHECK: - Type: DATA
; CHECK-NEXT: Segments:
; CHECK-NEXT: - SectionOffset: 7
; CHECK-NEXT: MemoryIndex: 0
; CHECK-NEXT: Offset:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 1024
; CHECK-NEXT: Content: '02000000'
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: linking
; CHECK-NEXT: DataSize: 4
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: name
; CHECK-NEXT: FunctionNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: used_function
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Name: _start
; CHECK-NEXT: - Index: 2
; CHECK-NEXT: Name: __wasm_call_ctors
; CHECK-NEXT: ...

; 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: DATA
; NO-GC-NEXT: Segments:
; NO-GC-NEXT: - SectionOffset: 7
; NO-GC-NEXT: MemoryIndex: 0
; NO-GC-NEXT: Offset:
; NO-GC-NEXT: Opcode: I32_CONST
; NO-GC-NEXT: Value: 1024
; NO-GC-NEXT: Content: '0100000002000000'
; NO-GC-NEXT: - Type: CUSTOM
; NO-GC-NEXT: Name: linking
; NO-GC-NEXT: DataSize: 8
; NO-GC-NEXT: - Type: CUSTOM
; NO-GC-NEXT: Name: name
; NO-GC-NEXT: FunctionNames:
; NO-GC-NEXT: - Index: 0
; NO-GC-NEXT: Name: unused_function
; NO-GC-NEXT: - Index: 1
; NO-GC-NEXT: Name: used_function
; NO-GC-NEXT: - Index: 2
; NO-GC-NEXT: Name: _start
; NO-GC-NEXT: - Index: 3
; NO-GC-NEXT: Name: __wasm_call_ctors
; NO-GC-NEXT: ...

; RUN: not lld -flavor wasm --gc-sections --relocatable -o %t1.no-gc.wasm %t.o 2>&1 | FileCheck %s -check-prefix=CHECK-ERROR
; CHECK-ERROR: lld: error: -r and --gc-sections may not be used together
8 changes: 5 additions & 3 deletions test/wasm/local-symbols.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ target triple = "wasm32-unknown-unknown-wasm"

define internal i32 @baz() local_unnamed_addr {
entry:
ret i32 2
%0 = load i32, i32* @bar, align 4
ret i32 %0
}

define i32 @_start() local_unnamed_addr {
entry:
call i32 @baz()
ret i32 1
}

Expand Down Expand Up @@ -70,10 +72,10 @@ entry:
; CHECK-NEXT: Functions:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 41020B
; CHECK-NEXT: Body: 4100280284888080000B
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 41010B
; CHECK-NEXT: Body: 1080808080001A41010B
; CHECK-NEXT: - Index: 2
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 0B
Expand Down
2 changes: 1 addition & 1 deletion test/wasm/weak-symbols.ll
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
; RUN: llc -filetype=obj %p/Inputs/weak-symbol1.ll -o %t1.o
; RUN: llc -filetype=obj %p/Inputs/weak-symbol2.ll -o %t2.o
; RUN: llc -filetype=obj %s -o %t.o
; RUN: lld -flavor wasm -o %t.wasm %t.o %t1.o %t2.o
; RUN: lld -flavor wasm -no-gc-sections -o %t.wasm %t.o %t1.o %t2.o
; RUN: obj2yaml %t.wasm | FileCheck %s

target triple = "wasm32-unknown-unknown-wasm"
Expand Down
1 change: 1 addition & 0 deletions wasm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ add_lld_library(lldWasm
Driver.cpp
InputChunks.cpp
InputFiles.cpp
MarkLive.cpp
OutputSections.cpp
SymbolTable.cpp
Symbols.cpp
Expand Down
2 changes: 2 additions & 0 deletions wasm/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ struct Configuration {
bool AllowUndefined;
bool CheckSignatures;
bool Demangle;
bool GcSections;
bool ImportMemory;
bool PrintGcSections;
bool Relocatable;
bool StripAll;
bool StripDebug;
Expand Down
24 changes: 19 additions & 5 deletions wasm/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
//===----------------------------------------------------------------------===//

#include "lld/Common/Driver.h"
#include "Config.h"
#include "InputChunks.h"
#include "MarkLive.h"
#include "SymbolTable.h"
#include "Writer.h"
#include "lld/Common/Args.h"
Expand All @@ -23,6 +24,8 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"

#define DEBUG_TYPE "lld"

using namespace llvm;
using namespace llvm::sys;
using namespace llvm::wasm;
Expand Down Expand Up @@ -253,6 +256,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
Config->ImportMemory = Args.hasArg(OPT_import_memory);
Config->OutputFile = Args.getLastArgValue(OPT_o);
Config->Relocatable = Args.hasArg(OPT_relocatable);
Config->GcSections =
Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !Config->Relocatable);
Config->PrintGcSections =
Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
Config->SearchPaths = args::getStrings(Args, OPT_L);
Config->StripAll = Args.hasArg(OPT_strip_all);
Config->StripDebug = Args.hasArg(OPT_strip_debug);
Expand All @@ -274,10 +281,14 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
if (!Args.hasArg(OPT_INPUT))
error("no input files");

if (Config->Relocatable && !Config->Entry.empty())
error("entry point specified for relocatable output file");
if (Config->Relocatable && Args.hasArg(OPT_undefined))
error("undefined symbols specified for relocatable output file");
if (Config->Relocatable) {
if (!Config->Entry.empty())
error("entry point specified for relocatable output file");
if (Config->GcSections)
error("-r and --gc-sections may not be used together");
if (Args.hasArg(OPT_undefined))
error("-r -and --undefined may not be used together");
}

Symbol *EntrySym = nullptr;
if (!Config->Relocatable) {
Expand Down Expand Up @@ -345,6 +356,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
if (errorCount())
return;

// Do size optimizations: garbage collection
markLive();

// Write the result to the file.
writeResult();
}
10 changes: 8 additions & 2 deletions wasm/InputChunks.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#ifndef LLD_WASM_INPUT_CHUNKS_H
#define LLD_WASM_INPUT_CHUNKS_H

#include "Config.h"
#include "InputFiles.h"
#include "WriterUtils.h"
#include "lld/Common/ErrorHandler.h"
Expand Down Expand Up @@ -58,17 +59,22 @@ class InputChunk {

bool Discarded = false;
std::vector<OutputRelocation> OutRelocations;
const 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) : File(F), SectionKind(K) {}
InputChunk(const ObjFile *F, Kind K)
: File(F), Live(!Config->GcSections), SectionKind(K) {}
virtual ~InputChunk() = default;
void calcRelocations();
virtual ArrayRef<uint8_t> data() const = 0;
virtual uint32_t getInputSectionOffset() const = 0;

std::vector<WasmRelocation> Relocations;
int32_t OutputOffset = 0;
const ObjFile *File;
Kind SectionKind;
};

Expand Down
8 changes: 4 additions & 4 deletions wasm/InputFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ void ObjFile::dumpInfo() const {
}

uint32_t ObjFile::relocateVirtualAddress(uint32_t GlobalIndex) const {
return GlobalSymbols[GlobalIndex]->getVirtualAddress();
return getGlobalSymbol(GlobalIndex)->getVirtualAddress();
}

uint32_t ObjFile::relocateFunctionIndex(uint32_t Original) const {
Symbol *Sym = FunctionSymbols[Original];
const Symbol *Sym = getFunctionSymbol(Original);
uint32_t Index = Sym->getOutputIndex();
DEBUG(dbgs() << "relocateFunctionIndex: " << toString(*Sym) << ": "
<< Original << " -> " << Index << "\n");
Expand All @@ -67,15 +67,15 @@ uint32_t ObjFile::relocateTypeIndex(uint32_t Original) const {
}

uint32_t ObjFile::relocateTableIndex(uint32_t Original) const {
Symbol *Sym = FunctionSymbols[Original];
const Symbol *Sym = getFunctionSymbol(Original);
uint32_t Index = Sym->hasTableIndex() ? Sym->getTableIndex() : 0;
DEBUG(dbgs() << "relocateTableIndex: " << toString(*Sym) << ": " << Original
<< " -> " << Index << "\n");
return Index;
}

uint32_t ObjFile::relocateGlobalIndex(uint32_t Original) const {
Symbol *Sym = GlobalSymbols[Original];
const Symbol *Sym = getGlobalSymbol(Original);
uint32_t Index = Sym->hasOutputIndex() ? Sym->getOutputIndex() : 0;
DEBUG(dbgs() << "relocateGlobalIndex: " << toString(*Sym) << ": " << Original
<< " -> " << Index << "\n");
Expand Down
2 changes: 2 additions & 0 deletions wasm/InputFiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ class ObjFile : public InputFile {
return FunctionSymbols[Index];
}

Symbol *getGlobalSymbol(uint32_t Index) const { return GlobalSymbols[Index]; }

private:
uint32_t relocateVirtualAddress(uint32_t Index) const;
uint32_t relocateTypeIndex(uint32_t Original) const;
Expand Down
Loading

0 comments on commit c69119a

Please sign in to comment.