forked from OSchip/llvm-project
[lld-macho] Unset ExportDynamic where possible for LTO
By unsetting this property, we are now able to internalize more symbols during LTO. I compared the output of `-save-temps` for both LLD and ld64, and we now match ld64's behavior as far as `lto-internalize.ll` is concerned. (Thanks @smeenai for working on an initial version of this diff!) Fixes https://github.com/llvm/llvm-project/issues/50574. Reviewed By: #lld-macho, thakis Differential Revision: https://reviews.llvm.org/D119372
This commit is contained in:
parent
af45d0fd94
commit
103e1d934a
|
@ -505,14 +505,6 @@ static void initLLVM() {
|
|||
}
|
||||
|
||||
static void compileBitcodeFiles() {
|
||||
// FIXME: Remove this once LTO.cpp honors config->exportDynamic.
|
||||
if (config->exportDynamic)
|
||||
for (InputFile *file : inputFiles)
|
||||
if (isa<BitcodeFile>(file)) {
|
||||
warn("the effect of -export_dynamic on LTO is not yet implemented");
|
||||
break;
|
||||
}
|
||||
|
||||
TimeTraceScope timeScope("LTO");
|
||||
auto *lto = make<BitcodeCompiler>();
|
||||
for (InputFile *file : inputFiles)
|
||||
|
|
|
@ -64,6 +64,8 @@ void BitcodeCompiler::add(BitcodeFile &f) {
|
|||
resols.reserve(objSyms.size());
|
||||
|
||||
// Provide a resolution to the LTO API for each symbol.
|
||||
bool exportDynamic =
|
||||
config->outputType != MH_EXECUTE || config->exportDynamic;
|
||||
auto symIt = f.symbols.begin();
|
||||
for (const lto::InputFile::Symbol &objSym : objSyms) {
|
||||
resols.emplace_back();
|
||||
|
@ -77,12 +79,14 @@ void BitcodeCompiler::add(BitcodeFile &f) {
|
|||
// be removed.
|
||||
r.Prevailing = !objSym.isUndefined() && sym->getFile() == &f;
|
||||
|
||||
// FIXME: What about other output types? And we can probably be less
|
||||
// restrictive with -flat_namespace, but it's an infrequent use case.
|
||||
// FIXME: Honor config->exportDynamic.
|
||||
r.VisibleToRegularObj = config->outputType != MH_EXECUTE ||
|
||||
config->namespaceKind == NamespaceKind::flat ||
|
||||
sym->isUsedInRegularObj;
|
||||
if (const auto *defined = dyn_cast<Defined>(sym))
|
||||
r.ExportDynamic =
|
||||
defined->isExternal() && !defined->privateExtern && exportDynamic;
|
||||
else if (const auto *common = dyn_cast<CommonSymbol>(sym))
|
||||
r.ExportDynamic = !common->privateExtern && exportDynamic;
|
||||
|
||||
r.VisibleToRegularObj =
|
||||
sym->isUsedInRegularObj || (r.Prevailing && r.ExportDynamic);
|
||||
|
||||
// Un-define the symbol so that we don't get duplicate symbol errors when we
|
||||
// load the ObjFile emitted by LTO compilation.
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
; RUN: llvm-dis < %t/test.0.2.internalize.bc | FileCheck %s
|
||||
; RUN: llvm-objdump --macho --syms %t/test | FileCheck %s --check-prefix=SYMTAB
|
||||
|
||||
; CHECK: @comm = internal global
|
||||
; CHECK: @comm_hide = internal global
|
||||
|
||||
;; Check that main is not internalized. This covers the case of bitcode symbols
|
||||
;; referenced by undefined symbols that don't belong to any InputFile.
|
||||
; CHECK: define void @main()
|
||||
|
@ -28,18 +31,48 @@
|
|||
;; internalized.
|
||||
; CHECK: define internal void @baz()
|
||||
|
||||
; Check foo and bar are not emitted to the .symtab
|
||||
;; Check that all internalized symbols are not emitted to the symtab
|
||||
; SYMTAB-LABEL: SYMBOL TABLE:
|
||||
; SYMTAB-NEXT: g F __TEXT,__text _main
|
||||
; SYMTAB-NEXT: g F __TEXT,__text _used_in_regular_obj
|
||||
; SYMTAB-NEXT: g F __TEXT,__text __mh_execute_header
|
||||
; SYMTAB-NEXT: *UND* dyld_stub_binder
|
||||
; SYMTAB-DAG: g F __TEXT,__text _main
|
||||
; SYMTAB-DAG: g F __TEXT,__text _used_in_regular_obj
|
||||
; SYMTAB-DAG: g F __TEXT,__text __mh_execute_header
|
||||
; SYMTAB-DAG: *UND* dyld_stub_binder
|
||||
; SYMTAB-EMPTY:
|
||||
|
||||
; RUN: %lld -lSystem -dylib %t/test.o %t/baz.o %t/regular.o -o %t/test.dylib -save-temps
|
||||
; RUN: llvm-dis < %t/test.dylib.0.2.internalize.bc | FileCheck %s --check-prefix=DYN
|
||||
; RUN: llvm-nm -m %t/test.dylib | FileCheck %s --check-prefix=DYN-SYMS \
|
||||
; RUN: --implicit-check-not _foo
|
||||
|
||||
; RUN: %lld -lSystem -export_dynamic %t/test.o %t/baz.o %t/regular.o -o %t/test.extdyn -save-temps
|
||||
; RUN: llvm-dis < %t/test.extdyn.0.2.internalize.bc
|
||||
; RUN: llvm-nm -m %t/test.extdyn | FileCheck %s --check-prefix=DYN-SYMS \
|
||||
; RUN: --implicit-check-not _foo
|
||||
|
||||
;; Note that only foo() gets internalized here; everything else that isn't
|
||||
;; hidden must be exported.
|
||||
; DYN: @comm = common global
|
||||
; DYN: @comm_hide = internal global
|
||||
; DYN: define void @main()
|
||||
; DYN: define void @bar()
|
||||
; DYN: define internal void @foo()
|
||||
; DYN: define void @used_in_regular_obj()
|
||||
; DYN: define void @baz()
|
||||
|
||||
; DYN-SYMS-DAG: (__TEXT,__text) external _bar
|
||||
; DYN-SYMS-DAG: (__TEXT,__text) external _baz
|
||||
; DYN-SYMS-DAG: (__DATA,__common) external _comm
|
||||
; DYN-SYMS-DAG: (__TEXT,__text) external _main
|
||||
; DYN-SYMS-DAG: (__TEXT,__text) external _used_in_regular_obj
|
||||
|
||||
;--- test.s
|
||||
target triple = "x86_64-apple-macosx10.15.0"
|
||||
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
;; Common symbols are always external.
|
||||
@comm = common global i8 0, align 1
|
||||
@comm_hide = common hidden global i8 0, align 1
|
||||
|
||||
declare void @baz()
|
||||
|
||||
define void @main() {
|
||||
|
|
Loading…
Reference in New Issue