diff options
author | Sam Clegg <sbc@chromium.org> | 2018-06-28 17:04:58 +0000 |
---|---|---|
committer | Sam Clegg <sbc@chromium.org> | 2018-06-28 17:04:58 +0000 |
commit | ce004bfe35c20d227865605427a11ff90ccb23b3 (patch) | |
tree | 3860ac0f4012651820b01211552863326a4e5968 /lld | |
parent | da5e7e11d1072ea13460f0b4ca77b7de35bf2bb8 (diff) | |
download | bcm5719-llvm-ce004bfe35c20d227865605427a11ff90ccb23b3.tar.gz bcm5719-llvm-ce004bfe35c20d227865605427a11ff90ccb23b3.zip |
[WebAssembly] Add support for bitcode archive members
This change effects the behavior of --export-all. Previously
--export-all would only effect symbols that survived GC. Now
--export-all will prevent any non-local symbols from being GCed.
Differential Revision: https://reviews.llvm.org/D48673
llvm-svn: 335878
Diffstat (limited to 'lld')
-rw-r--r-- | lld/test/wasm/export-all.ll | 17 | ||||
-rw-r--r-- | lld/test/wasm/lto/Inputs/archive.ll | 6 | ||||
-rw-r--r-- | lld/test/wasm/lto/archive.ll | 25 | ||||
-rw-r--r-- | lld/wasm/InputFiles.cpp | 10 | ||||
-rw-r--r-- | lld/wasm/LTO.cpp | 3 | ||||
-rw-r--r-- | lld/wasm/MarkLive.cpp | 4 | ||||
-rw-r--r-- | lld/wasm/Symbols.cpp | 10 | ||||
-rw-r--r-- | lld/wasm/Symbols.h | 1 | ||||
-rw-r--r-- | lld/wasm/Writer.cpp | 6 |
9 files changed, 65 insertions, 17 deletions
diff --git a/lld/test/wasm/export-all.ll b/lld/test/wasm/export-all.ll index 450c6e38e84..34797aac76f 100644 --- a/lld/test/wasm/export-all.ll +++ b/lld/test/wasm/export-all.ll @@ -7,12 +7,17 @@ ; RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=EXPORT ; RUN: wasm-ld --export-all --no-gc-sections -o %t.wasm %t.o -; RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=NOGC +; RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=EXPORT ; Verify the --export-all flag exports hidden symbols target triple = "wasm32-unknown-unknown" +define internal void @internal_func() local_unnamed_addr { +entry: + ret void +} + define hidden void @bar() local_unnamed_addr { entry: ret void @@ -26,6 +31,7 @@ entry: define hidden void @_start() local_unnamed_addr { entry: call void @foo() + call void @internal_func() ret void } @@ -33,13 +39,10 @@ entry: ; CHECK: - Name: _start ; CHECK-NOT: - Name: bar ; CHECK-NOT: - Name: foo +; CHECK-NOT: - Name: internal_func ; EXPORT: - Type: EXPORT ; EXPORT: - Name: _start -; EXPORT-NOT: - Name: bar +; EXPORT: - Name: bar ; EXPORT: - Name: foo - -; NOGC: - Type: EXPORT -; NOGC: - Name: _start -; NOGC: - Name: bar -; NOGC: - Name: foo +; EXPORT-NOT: - Name: internal_func diff --git a/lld/test/wasm/lto/Inputs/archive.ll b/lld/test/wasm/lto/Inputs/archive.ll new file mode 100644 index 00000000000..75984793246 --- /dev/null +++ b/lld/test/wasm/lto/Inputs/archive.ll @@ -0,0 +1,6 @@ +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +define void @f() { + ret void +} diff --git a/lld/test/wasm/lto/archive.ll b/lld/test/wasm/lto/archive.ll new file mode 100644 index 00000000000..89fa840cdec --- /dev/null +++ b/lld/test/wasm/lto/archive.ll @@ -0,0 +1,25 @@ +; RUN: llvm-as %S/Inputs/archive.ll -o %t1.o +; RUN: rm -f %t.a +; RUN: llvm-ar rcs %t.a %t1.o +; RUN: llvm-as %s -o %t2.o +; RUN: wasm-ld %t2.o %t.a -o %t3 +; RUN: obj2yaml %t3 | FileCheck %s + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +define void @_start() { + call void @f() + ret void +} + +declare void @f() + +; CHECK: Name: name +; CHECK-NEXT: FunctionNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __wasm_call_ctors +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Name: _start +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Name: f diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp index ee9e99bd775..55392ccd34f 100644 --- a/lld/wasm/InputFiles.cpp +++ b/lld/wasm/InputFiles.cpp @@ -360,12 +360,18 @@ void ArchiveFile::addMember(const Archive::Symbol *Sym) { "could not get the buffer for the member defining symbol " + Sym->getName()); - if (identify_magic(MB.getBuffer()) != file_magic::wasm_object) { + InputFile *Obj; + + file_magic Magic = identify_magic(MB.getBuffer()); + if (Magic == file_magic::wasm_object) { + Obj = make<ObjFile>(MB); + } else if (Magic == file_magic::bitcode) { + Obj = make<BitcodeFile>(MB); + } else { error("unknown file type: " + MB.getBufferIdentifier()); return; } - InputFile *Obj = make<ObjFile>(MB); Obj->ParentName = ParentName; Symtab->addFile(Obj); } diff --git a/lld/wasm/LTO.cpp b/lld/wasm/LTO.cpp index 58f32aaf244..dd66c67e39f 100644 --- a/lld/wasm/LTO.cpp +++ b/lld/wasm/LTO.cpp @@ -95,7 +95,8 @@ void BitcodeCompiler::add(BitcodeFile &F) { // Once IRObjectFile is fixed to report only one symbol this hack can // be removed. R.Prevailing = !ObjSym.isUndefined() && Sym->getFile() == &F; - R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj; + R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj || + (R.Prevailing && Sym->isExported()); if (R.Prevailing) undefine(Sym); } diff --git a/lld/wasm/MarkLive.cpp b/lld/wasm/MarkLive.cpp index 018b3255b55..dfaa712c329 100644 --- a/lld/wasm/MarkLive.cpp +++ b/lld/wasm/MarkLive.cpp @@ -54,9 +54,9 @@ void lld::wasm::markLive() { Enqueue(Symtab->find(Config->Entry)); Enqueue(WasmSym::CallCtors); - // We export all defined, non-hidden symbols so they are all gc roots too + // We need to preserve any exported symbol for (Symbol *Sym : Symtab->getSymbols()) - if (Sym->isDefined() && !Sym->isHidden()) + if (Sym->isExported()) Enqueue(Sym); // The ctor functions are all used in the synthetic __wasm_call_ctors diff --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp index 6b43eb36341..ef135b35b1a 100644 --- a/lld/wasm/Symbols.cpp +++ b/lld/wasm/Symbols.cpp @@ -98,6 +98,16 @@ void Symbol::setHidden(bool IsHidden) { Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT; } +bool Symbol::isExported() const { + if (!isDefined() || isLocal()) + return false; + + if (Config->ExportAll) + return true; + + return !isHidden(); +} + uint32_t FunctionSymbol::getFunctionIndex() const { if (auto *F = dyn_cast<DefinedFunction>(this)) return F->Function->getFunctionIndex(); diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h index a4d6e0bbf0f..794a65df673 100644 --- a/lld/wasm/Symbols.h +++ b/lld/wasm/Symbols.h @@ -90,6 +90,7 @@ public: void setOutputSymbolIndex(uint32_t Index); WasmSymbolType getWasmType() const; + bool isExported() const; // True if this symbol was referenced by a regular (non-bitcode) object. unsigned IsUsedInRegularObj : 1; diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp index 41562e3c532..37ad32452a9 100644 --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -740,11 +740,7 @@ void Writer::calculateExports() { unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size(); for (Symbol *Sym : Symtab->getSymbols()) { - if (!Sym->isDefined()) - continue; - if (Sym->isHidden() && !Config->ExportAll) - continue; - if (Sym->isLocal()) + if (!Sym->isExported()) continue; if (!Sym->isLive()) continue; |