mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-30 23:20:54 +00:00
LTOCodeGenerator: turns linkonce(_odr) into weak_(odr) when present "MustPreserve" set
Summary: If the linker requested to preserve a linkonce function, we should honor this even if we drop all uses. Reviewers: dexonsmith Subscribers: llvm-commits, joker.eph Differential Revision: http://reviews.llvm.org/D19527 From: Mehdi Amini <mehdi.amini@apple.com> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@267644 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7f794cf472
commit
e69ab0b5ff
@ -348,14 +348,58 @@ std::unique_ptr<TargetMachine> LTOCodeGenerator::createTargetMachine() {
|
||||
RelocModel, CodeModel::Default, CGOptLevel));
|
||||
}
|
||||
|
||||
// If a linkonce global is present in the MustPreserveSymbols, we need to make
|
||||
// sure we honor this. To force the compiler to not drop it, we turn its linkage
|
||||
// to the weak equivalent.
|
||||
static void
|
||||
preserveDiscardableGVs(Module &TheModule,
|
||||
function_ref<bool(const GlobalValue &)> mustPreserveGV) {
|
||||
auto mayPreserveGlobal = [&](GlobalValue &GV) {
|
||||
if (!GV.isDiscardableIfUnused() || GV.isDeclaration())
|
||||
return;
|
||||
if (!mustPreserveGV(GV))
|
||||
return;
|
||||
if (GV.hasAvailableExternallyLinkage() || GV.hasLocalLinkage())
|
||||
report_fatal_error("The linker asked LTO to preserve a symbol with an"
|
||||
"unexpected linkage");
|
||||
GV.setLinkage(GlobalValue::getWeakLinkage(GV.hasLinkOnceODRLinkage()));
|
||||
};
|
||||
|
||||
for (auto &GV : TheModule)
|
||||
mayPreserveGlobal(GV);
|
||||
for (auto &GV : TheModule.globals())
|
||||
mayPreserveGlobal(GV);
|
||||
for (auto &GV : TheModule.aliases())
|
||||
mayPreserveGlobal(GV);
|
||||
}
|
||||
|
||||
void LTOCodeGenerator::applyScopeRestrictions() {
|
||||
if (ScopeRestrictionsDone || !ShouldInternalize)
|
||||
if (ScopeRestrictionsDone)
|
||||
return;
|
||||
|
||||
// Declare a callback for the internalize pass that will ask for every
|
||||
// candidate GlobalValue if it can be internalized or not.
|
||||
SmallString<64> MangledName;
|
||||
auto mustPreserveGV = [&](const GlobalValue &GV) -> bool {
|
||||
// Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled
|
||||
// with the linker supplied name, which on Darwin includes a leading
|
||||
// underscore.
|
||||
MangledName.clear();
|
||||
MangledName.reserve(GV.getName().size() + 1);
|
||||
Mangler::getNameWithPrefix(MangledName, GV.getName(),
|
||||
MergedModule->getDataLayout());
|
||||
return MustPreserveSymbols.count(MangledName);
|
||||
};
|
||||
|
||||
// Preserve linkonce value on linker request
|
||||
preserveDiscardableGVs(*MergedModule, mustPreserveGV);
|
||||
|
||||
if (!ShouldInternalize)
|
||||
return;
|
||||
|
||||
if (ShouldRestoreGlobalsLinkage) {
|
||||
// Record the linkage type of non-local symbols so they can be restored
|
||||
// prior
|
||||
// to module splitting.
|
||||
// prior to module splitting.
|
||||
auto RecordLinkage = [&](const GlobalValue &GV) {
|
||||
if (!GV.hasAvailableExternallyLinkage() && !GV.hasLocalLinkage() &&
|
||||
GV.hasName())
|
||||
@ -373,22 +417,7 @@ void LTOCodeGenerator::applyScopeRestrictions() {
|
||||
// symbols referenced from asm
|
||||
UpdateCompilerUsed(*MergedModule, *TargetMach, AsmUndefinedRefs);
|
||||
|
||||
// Declare a callback for the internalize pass that will ask for every
|
||||
// candidate GlobalValue if it can be internalized or not.
|
||||
Mangler Mangler;
|
||||
SmallString<64> MangledName;
|
||||
auto MustPreserveGV = [&](const GlobalValue &GV) -> bool {
|
||||
// Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled
|
||||
// with the linker supplied name, which on Darwin includes a leading
|
||||
// underscore.
|
||||
MangledName.clear();
|
||||
MangledName.reserve(GV.getName().size() + 1);
|
||||
Mangler::getNameWithPrefix(MangledName, GV.getName(),
|
||||
MergedModule->getDataLayout());
|
||||
return MustPreserveSymbols.count(MangledName);
|
||||
};
|
||||
|
||||
internalizeModule(*MergedModule, MustPreserveGV);
|
||||
internalizeModule(*MergedModule, mustPreserveGV);
|
||||
|
||||
ScopeRestrictionsDone = true;
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
; RUN: llvm-as %s -o %t.o
|
||||
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -dylib -arch x86_64 -macosx_version_min 10.10.0 -lSystem -o %t.dylib %t.o -save-temps -undefined dynamic_lookup
|
||||
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -dylib -arch x86_64 -macosx_version_min 10.10.0 -lSystem -o %t.dylib %t.o -save-temps -undefined dynamic_lookup -exported_symbol _c -exported_symbol _b
|
||||
|
||||
; RUN: llvm-dis %t.dylib.lto.opt.bc -o - | FileCheck --check-prefix=IR %s
|
||||
; check that @a is still a linkonce_odr definition
|
||||
; IR: define linkonce_odr void @a()
|
||||
; check that @a is no longer a linkonce_odr definition
|
||||
; IR-NOT: define linkonce_odr void @a()
|
||||
; check that @b is turned into weak because it is exported
|
||||
; IR: define weak_odr void @b() #1 {
|
||||
|
||||
; RUN: llvm-nm %t.dylib | FileCheck --check-prefix=NM %s
|
||||
; check that the linker can hide @a but not @b
|
||||
|
Loading…
Reference in New Issue
Block a user